redo log
redo log是物理日志,记录的是“在某个数据页上做了什么修改”,它是循环写的,文件大小固定,是InnoDB引擎特有的。
bin log
bin log是逻辑日志,记录的是逻辑SQL语句。
格式
bin log有两种格式,分别是STATEMENT和ROW。
- STATEMENT:日志记录的是逻辑SQL语句
- ROW:日志记录的是表的行更改情况
redo log 和bin log的配置使用实现了crash-safe
crash-safe:即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为 crash-safe。这里提交的概念是指,日志能够成功写入redo log,否则告之客户端提交失败
流程
假设数据库执行语句
update t set n = n+1 where id =1
- 数据库执行器从内存中查找表n id为1的值,如果能找到,直接返回该值n,否则,要从磁盘中查询、读取该值;
- 执行器拿到引擎层给的数据,对将n设置为n+1,再调用引擎层写入新数据;
- 引擎层拿到这一行数据,先将该数据写入redo log,并将状态设定为prepared,且告知执行器执行完成了,事务随时可以提交;
- 执行器生成这个操作的 bin log,并将bin log写入磁盘;
- 执行器调用引擎层事务提交的接口,将刚刚写入的redo log的状态设定为commited,更新完成。
crash 分析
- 如果数据在上述流程第3步之后crash,通过redo log恢复时检测到事务尚未提交,事务本身会回滚,两阶段数据一致;
- 如果数据在上述流程第4步之后crash,恢复时检测到bin log中存在该操作,且redo log处于prepared状态,重启时会自动commit。
其他流程
- 先写redo log,再写bin log,如果写完redo log发生crash,这样重启恢复的时候,redo log已经commit。造成bin log和 redo log不一致。如果主从复制使用该bin log,就会发生主机和从机数据不一致的情况;
- 先写bin log,再写redo log,如果写完bin log发生crash,自动重启后,由于没有通过commit来提交,事务会发生回滚。而bin log是存在该记录的,如果主从复制使用该bin log,就会发生主机和从机数据不一致的情况;