本文已参与「新人创作礼」活动,一起开启掘金创作之路。
redo log
- redo log 是InnoDB独有的,属于物理日志,记录的是“在某个数据页上做了什么修改”,当系统比较空闲的时候,再将操作记录一起更新到磁盘里面
- 也就是说在刷新到IO这个操作,时通过写入到Redo Log缓冲区中,再由缓冲区刷新到磁盘,如果此时发生宕机,redo log依旧记录着这个行为,这个方式也称为crash-safe
- 事务的“持久性”就是redo log实现的
- 从逻辑结构上看,redo log 是一个循环数组,有两个指针,一个指针指着当前要擦除的位置(checkpoint),另一个指针指着当前记录的位置(write pos)。
undo log
- undo log(回滚日志)用于记录数据被修改之前的信息,作用包含两个:提供回滚和MVCC(多版本并发控制)
- undo log是逻辑日志,原子性底层就是通过undo log实现的。undo log主要记录了数据的逻辑变化,比如一条INSERT语句,对应一条DELETE的undo log,对于每个UPDATE语句,对应一条相反的UPDATE的undo log,这样在发生错误时,就能回滚到事务之前的数据状态。
- 事务的“原子性”就是undo log实现的
MVCC
- 多版本并发控制,指维护一个数据的多个版本,使得读写操作不会冲突,MVCC的具体实现需要依赖数据库中记录的三个隐藏字段、undo log、readView
- 事务的“一致性”就是MVCC+readView实现的
版本链:链表的头部是最新的记录,链表尾部是最早的旧记录
Read View
binlog
- binlog用于记录数据库执行的写入性操作(不包括查询,查询是由单独的查询日志来实现的),
- binlog以二进制的形式保存在磁盘中。binlog是mysql的逻辑日志,并且由Server层进行记录,使用任何存储引擎的mysql数据库都会记录binlog日志。
- 在实际应用中,binlog的主要使用场景有两个,分别是主从复制和数据恢复。
慢查询日志
慢查询日志记录了所有执行时间超过参数long_query_time(默认10s)
事务提交流程
我们再来看看一条更新语句的执行周期
- 两阶段提交将 redo log 的写入拆成了两个步骤: prepare 和 commit
为什么需要两阶段提交?如果不用会有什么后果?
两阶段提交的目的是让这两个状态保持逻辑上的一致
如果不使用“两阶段提交”,那么数据库的状态就有可能和用它的日志恢复出来的库的状态不一致。