Mysql——三大日志
Redo log 重做日志
作用:redo log为innodb独有,用于崩溃恢复,保证数据的持久性和完整性。
刷盘时机
- 根据innodb_flush_log_at_trx_commit:
- 0:每次事务提交不进行刷盘
- 1:每次事务提交都进行刷盘
- 2:每次事务提交,将log buffer中的redo log写入page cache
- 当log buffer中缓存的redo log占其容量约一半时,进行刷盘
- 当事务日志缓冲区(transaction log buffer)满时,触发刷盘
- innodb定期执行检查点操作,将内存中脏数据刷新到磁盘,并将对应redo log一并刷新
- innodb有一个后台线程,周期性地(1秒)将脏页与相关redo log刷新到磁盘
- mysql服务器关闭时,会刷新

存储形式
redo log以日志文件组的形式存储在磁盘上,每个日志文件组包含多个日志文件,每个文件大小一样。
采用环形数组形式,从头循环写。

- write pos:当前记录的位置,一边写一边后移
- checkpoint:当前要擦出的位置,一边擦一边后移
每次刷盘 redo log 记录到日志文件组中,write pos位置就会后移更新。
每次 MySQL 加载日志文件组恢复数据时,会清空加载过的 redo log 记录,并把 checkpoint后移更新。
如果 write pos追上 checkpoint,表示日志文件组满了,这时候不能再写入新的 redo log 记录,MySQL 得停下来,清空一些记录,把 checkpoint推进一下。
Binlog
作用:
- 主从同步和数据备份
- 数据恢复,可以通过binlog恢复到任意时间点的数据
- 审计与数据分析
记录格式
- statement:记录sql语句原文,对于now()、random()等无法保持一致。
- row:记录sql语句和操作的具体数据,row格式的记录需要通过mysqlbinlog工具进行解析。row可以保持一致性,但占据空间,影响性能。
- mixed:先判断sql语句是否会引起数据不一致,决定用row还是statement。


写入机制
事务执行过程中,binlog写入binlog cache,每个线程都有单独的binlog cache,以保证一个事物的binlog不会被拆开。
当事务提交时,再写入pagecache(write),以及之后刷盘(fsync)。
根据sync_binlog参数:
- 0:每次提交事务只write,由系统决定何时执行fsync
- 1:每次提交事务都会fsync
- N:积累N个事务后再一并fsync
两阶段提交

事务执行期间,更新数据先是写入redo log的prepare阶段;提交事务后,写入binlog,再将redo log的prepare阶段改为commit阶段。
- 当写入binlog时发生异常,恢复时由于发现redo log还在prepare阶段且没有对于binlog,因此回滚事务即可。
- 当设置commit时发生异常,由于能找到binlog,直接提交事务即可。
Undo log
作用:
- 事务回滚,保证原子性
- 在MVCC中提供数据的历史版本
undo log属于逻辑日志,对于每一条sql语句,记录其相反的操作。