我们都知道,事务拥有四个特性,就是我们常说的 ACID
- 原子性
- 一致性
- 隔离性
- 持久性
事务的原子性,隔离性由锁来实现,这个我们后面再说。
而事务的持久性依靠redo log来实现,主要用来重放操作的能力。
事务的一致性通过undo log来实现,主要用来回滚操作。
innodb会在事务提交的时候先将该事务的日志写入到磁盘上的redo log file 和 undo log file,同时还会在server层写入binlog中(这个和使用的引擎不相关,不是innodb也会写入)。
redo log
redo log 纷纷一两部分,一部分是放在内容中的 redo log buffer,该部分日志在系统崩溃时将会丢失。另一部分是存储在硬盘的redo log file。
redo log 会先写入用户态的log buffer中,如果想要落盘,还需要经过调用内核态os buffer,然后才能写入到磁盘中。可以通过fsync() 操作立即执行写入动作。
innodb支持用户自定义在commit时,如果和log buffer中的日志刷入到log file中。通过控制变量 innodb_flush_log_at_trx_commit的值来决定:
0 : 事务提交时不会将log buffer中的日志写入到 os buffer, 而是每秒写入到os buffer,并调用fsync 写入到log file中,也就是说,使用这种方式会每秒写一次磁盘,但是当系统崩溃的时候,最多会丢失1秒钟的数据(不要小看这个数据量,在全速写入时,可能是10万级别的数据)。
1:innodb的默认设置,每次事务提交都会写入到os buffer,并且调用fsync写入到磁盘。相比0来说,性能会有所下降,但是数据是安全的。
2:每次提交都仅写如到 os buffer中,然后每秒调用fsync,刷入到磁盘中。

undo log
Undo + Redo事务的简化过程
假设有A、B两个数据,值分别为1,2,开始一个事务,事务的操作内容为:把1修改为3,2修改为4,那么实际的记录如下(简化):
A.事务开始.
B.记录A=1到undo log.
C.修改A=3.
D.记录A=3到redo log.
E.记录B=2到undo log.
F.修改B=4.
G.记录B=4到redo log.
H.将redo log写入磁盘。
I.事务提交
