前记
- 事务隔离性由锁实现;
- 原子性、一致性、持久性由数据库redo log和undo log完成。redo log重做日志,保证事务原子性和持久性,undo log保证事务一致性;
- redo和undo都可视为一种恢复操作,redo恢复提交事务修改的页操作,undo回滚行记录到某个特定版本;
- redo是物理日志,记录的是页的物理操作,undo是逻辑日志,根据每行记录进行记录;
- redo log基本是顺序写,数据库运行时不需要对redo log file进行读取操作,undo log需要随机读写;
- InnoDB存储引擎启动时,不管上次数据库是否正常关闭,都会尝试进行恢复操作。redo log记录的是物理日志,恢复速度比逻辑日志快;
redo
- 实现事务的持久性。由两部分组成,内存中重做日志缓存redo log buffer,易失;重做日志文件redo log file,持久的;
- 通过Force Log at Commit机制实现事务的持久性,即事务提交commit时,需将该事务所有日志写入到redo log file进行持久化,待事务commit操作完成才算完成;
- 每次将redo log buffer写入redo log file,InnoDB调用一次fsync操作;
- innodb_flush_log_at_trx_commit参数控制redo log刷新到磁盘的策略;
1:事务提交时必须调用一次fsync;
0:事务提交时不进行写入redo log操作,该操作仅在master thread中完成,master thread中每1秒进行一次redo log file的fsync操作;
2:事务提交时将redo log写入redo log file,但仅写入文件系统的缓存中,不进行fsync;redo log vs binlog
- redo log是在InnoDB层,binlog是MySQL数据库上层产生;
- binlog是逻辑日志,记录的是对于的SQL语句;redo log是物理日志,记录的是对每个页的修改;
- binlog在事务commit完成后进行一次写入;redo log在事务中不断的被写入,不是随事务提交顺序写入的;
log block
- Innodb中,redo log以512字节存储的,即redo log buffer、redo log file都是以block方式保存,称为redo log block,大小为512字节;
- redo log block=log block header(12字节) + log body(492字节) + log tailer(8字节);
- redo log格式
- InnoDB引擎的存储管理基于页,所以redo log格式也是基于页;
- 格式=redo_log_type + space + page_no + redo log body;
redo_log_type:redo log的类型;
space:表空间的ID;
page_no:页的偏移量;LSN
Log Sequence Number 日志序列号。InnoDB存储引擎中,LSN占用8字节,单调递增;
LSN含义:
重做日志的总量;
checkpoint的位置;
页的版本;undo
- redo log记录事务的行为,可对页进行“重做”操作。回滚操作使用undo。
- undo存放在数据库内部一个特殊段里,称为undo segment,位于共享表空间内;
- undo 是逻辑日志,讲数据库逻辑的恢复到原来的样子;
- InnoDB回滚操作:
insert ===> delete
delete ===> insert
update ===> update
- undo另一个作用是MVCC,用户读取一行记录时,该记录已经被其他事务占用,当前事务通过undo读取之前的行版本信息;
- undo log会产生redo log,undo log也需持久化保护;
undo log格式
InnoDB存储引擎中,undo log分为:
insert undo log:insert操作产生,该undo log在事务commit后直接删除,不需进行purge操作;
update undo log:delete和update操作产生,该undo log可能需要提供MVCC机制,事务commit后不能进行删除,放入undo log链表中,等待purge线程最后删除。