一、前置问题
- binlog, redolog区别
二、InnoDB实现原子级的持久性
1. 直接把buffer中的修改页写到磁盘的挑战
1)写磁盘操作的非原子性
事务提交后,直接把buffer中的修改页写入磁盘,如果此过程中数据库宕机,则可能导致事务写入不完整,且重启后无法恢复;
2)随机写盘的IO效率和响应时间
由于数据库数据按B+数的结构存储,其数据必然是不连续的;持久化操作必然是非顺序写,IO的操作必然导致客户端响应时间变大;
2. Innodb的解决方案——redo log
redo log是Innodb存储引擎引入的,用来解决事务级别的持久化和原子性;redo log的使用是建立在页完整的基础上的,所以需要依赖另一个技术double write
来避免partial page write
。
1)redo log存储了本次的事务的操作,其最后的行end trx_num
来标识事务是否已完成;通过该行来原子性标识是否事务是否完成;
2)redo log顺序写的特性保证其IO效率高,响应快;
通过同步写redo log,异步刷新修改页到磁盘实现高响应;如果写磁盘发生宕机则通过重放redo log实现crash recovery,实现数据不丢失;
三、bin log
bin log是mysql server层的日志,主要用来实现主从同步;
四、redo log的二段式提交
innoDB为了使redo log和bin log保持同步,即保证主库和从库的同步,在收到事务的commit操作后,采用二段式提交实现;
1)第一步:pepare redo log,第一次提交
start tx_num;
write operate_1;
write operate_n;
pepare tx_num;
2)第二步:write bin log
write binlog;
3)第三步:end tx_num,第二次提交
end tx_num;
此时,有三种场景:
1)第一步失败(redo log中无prepare tx_num
行)- mysql认为事务提交失败,忽略事务;
2)第二步失败(redo log中存在prepare tx_num
行)- mysql通过redo log恢复bin log,继续执行第三步,事务提交成功;
3)第三步失败(redo log中存在prepare tx_num
行)- 重启后继续执行第三步,事务提交成功;
网友评论