InnoDB 事务的实现
Table of Contents

事务的实现

事务的隔离性由锁来实现,原子性,一致性,持久性通过数据库的 redo log 和 undo log 来完成。

redo log

redo log 跟 binlog的区别

首先,二进制日志会记录所有与MySQL数据库有关的日志记录,包括InnoDB、MyISAM、Heap等其他存储引擎的日志。而InnoDB存储引擎的重做日志只记录有关该存储引擎本身的事务日志。

其次,记录的内容不同,无论用户将二进制日志文件记录的格式设为STATEMENT还是ROW,又或者是MIXED,其记录的都是关于一个事务的具体操作内容,即该日志是逻辑日志。而InnoDB存储引擎的重做日志文件记录的是关于每个页(Page)的更改的物理情况。

此外,写入的时间也不同,二进制日志文件仅在事务提交前进行提交,即只写磁盘一次,不论这时该事务多大。而在事务进行的过程中,却不断有重做日志条目(redoentry)被写入到重做日志文件中。

重做日志缓存

重做日志并不是直接写入到磁盘中的,而是先写入一个重做日志缓存中,然后按照一定条件顺序地写入日志文件:

参数innodb_flush_log_at_trx_commit的有效值有0、1、2。

因此为了保证事务的ACID中的持久性,必须将innodb_flush_log_at_trx_commit设置为1,也就是每当有事务提交时,就必须确保事务都已经写入重做日志文件。那么当数据库因为意外发生宕机时,可以通过重做日志文件恢复,并保证可以恢复已经提交的事务。而将重做日志文件设置为0或2,都有可能发生恢复时部分事务的丢失。不同之处在于,设置为2时,当MySQL数据库发生宕机而操作系统及服务器并没有发生宕机时,由于此时未写入磁盘的事务日志保存在文件系统缓存中,当恢复时同样能保证数据不丢失。

undo log

undo 存放在数据库内部的一个特殊段(undo segment)中,在共享表空间中。

undo log 是逻辑日志,通过取消逻辑修改来回滚事务,例如对于一个INSERT,回滚过程是通过DELETE操作来删除增加的记录。同时undo log 会产生redo log。