内容
- 事务
- innodb_flush_log_at_trx_commit
事务其实就是并发控制的基本单位;相信我们都知道,事务是一个序列操作,其中的操作要么都执行,要么都不执行,它是一个不可分割的工作单位;数据库事务的 ACID 四大特性是事务的基础,了解了 ACID 是如何实现的,我们也就清楚了事务的实现,接下来将依次介绍数据库是如何实现这四个特性的。
- 原子性(Atomicity):事务是一个原子操作单元,其对数据的修改,要么全部都执行,要么全都不执行
- 一致性(Consistent):在事务开始和完成时,数据都必须保存一致状态。这意味着所有相关的数据规则都必须应用于事务的修改,以保持数据的完整性;事务结束时,所有的内部数据结构(如B树索引或双向链表)也都必须正确的。
- 隔离性(lsolation):数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立”环境执行。这意味着事务处理过程中的中间状态对外部是不可见,反之亦然。
- 持久性(Durable):事务完成后,它对于数据的修改是永久性的,即使出现系统故障也能够保持
1.事务的特性理解
-- 查看事务日志 : show engine innodb status\G; -- 查看日志文件设置状态 show variables like ‘innodb_%‘;
事务日志文件
innodb_log_files_in_group:DB中设置几组事务日志,默认是2; innodb_log_group_home_dir:事务日志存放目录,不设置,ib_logfile0...存在在数据文件目录下
Innodb存储引擎可将所有数据存放于ibdata*的共享表空间,也可将每张表存放于独立的.ibd文件的独立表空间
注意:在MySQL中对于数据来说, 最为重要的是日志文件
redo log => ib_logfile0
undo log => ibdata
1.2原子性
通俗的解释就是;一条绳子上的蚂蚱 专业点:事务就是一系列的操作,要么全部都执行,要都不执行
1.2.1回滚日志
想要保证事务的原子性,就需要在异常发生时,对已经执行的操作进行回滚,而在 MySQL 中,恢复机制是通过回滚日志(undo log)实现的,所有事务进行的修改都会先记录到这个回滚日志中,然后在对数据库中的对应行进行写入。
注意:系统发生崩溃、数据库进程直接被杀死后,当用户再次启动数据库进程时,还能够立刻通过查询回滚日志将之前未完成的事务进行回滚,这也就需要回滚日志必须先于数据持久化到磁盘上,是我们需要先写日志后写数据库的主要原因。
在日志文件中:在事务中使用的每一条 INSERT 都对应了一条 DELETE,每一条 UPDATE 也都对应一条相反的 UPDATE 语句。
1.3持久化
事务被提交,数据一定会被写入到数据库中并持久存储起来,通常来说当事务已经被提交之后,就无法再次回滚了
1.3.1重做日志
与原子性一样,事务的持久性也是通过日志来实现的,MySQL 使用重做日志(redo log)实现事务的持久性,重做日志由两部分组成,一是内存中的重做日志缓冲区,因为重做日志缓冲区在内存中,所以它是易失的,另一个就是在磁盘上的重做日志文件,它是持久的。
在事务写入过程
当我们在一个事务中尝试对数据进行写时,它会先将数据从磁盘读入内存,并更新内存中缓存的数据,然后生成一条重做日志并写入重做日志缓存,当事务真正提交时,MySQL 会将重做日志缓存中的内容刷新到重做日志文件,再将内存中的数据更新到磁盘上,图中的第 4、5 步就是在事务提交时执行的。
1.4回滚日志和重做日志
到现在为止我们了解了 MySQL 中的两种日志,回滚日志(undo log)和重做日志(redo log);在数据库系统中,事务的原子性和持久性是由事务日志(transaction log)保证的,在实现时也就是上面提到的两种日志,前者用于对事务的影响进行撤销,后者在错误处理时对已经提交的事务进行重做,它们能保证两点:
- 发生错误或者需要回滚的事务能够成功回滚(原子性);
- 在事务提交后,数据没来得及写会磁盘就宕机时,在下次重新启动后能够成功恢复数据(持久性);
在数据库中,这两种日志经常都是一起工作的,我们可以将它们整体看做一条事务日志,其中包含了事务的 ID、修改的行元素以及修改前后的值。
1.5事务日志流程
MySQL的checkpoint https://www.cnblogs.com/lintong/p/4381578.html
checkpoint,即检查点。在undolog中写入检查点,表示在checkpoint前的事务都已经完成commit或者rollback了,也就是检查点前面的事务已经不存在数据一致性的问题了(此处暂时不会深入解释)
Innodb的事务日志是指Redo log,简称Log,保存在日志文件ib_logfile里面(去mysql数据目录下看下)。Innodb还有另外一个日志Undo log,但Undo log是存放在共享表空间里面的(ibdata*文件,存储的是check point日志序列号)。
Innodb的一条事务日志共经历4个阶段:
- 创建阶段:事务创建一条日志;
- 日志刷盘:日志写入到磁盘上的日志文件; (ib_logfile里面)
- 数据刷盘:日志对应的脏页数据写入到磁盘上的数据文件;
- 写CKP:日志被当作Checkpoint写入日志文件;(ib_data里面)
2.innodb_flush_log_at_trx_commit参数解析
-- 查看日志文件设置状态 show variables like ‘innodb_%‘; -- 更改 set @@global.innodb_flush_log_at_trx_commit = 0; -- 0,1,2 show variables like ‘innodb_flush_log_at_trx_commit‘;
2.1概述
2.2性能对比方式
设置innodb_flush_log_at_trx_commit 不同的值,然后对比 所用的时间
2.3数据问题对比
因为在实际过程中很难去模拟实际的断点故障的情况,但是你可以尝试通过终止MySQL服务来测试;数据的插入速度是很快的(大量数据除外),为了方便测试这里可以对于数据插入之后睡眠一下,然后再去终止MySQL服务;就可以模拟情况;过程需要自己返回测试