1、undo log
- undo log日志是一种用于撤销回退的逻辑日志,在事务未提交前会记录相反的操作到undo log,当事务回滚,使用undo log 进行回滚,保证了事务的原子性。
- MVCC通过 undo log+ReadView实现,undo log为每条记录保存多份历史数据,Mysql根据ReadView里的信息顺着undo log记录的版本链找到相关记录。
2、Buffer Pool
Buffer Pool是Innodb引擎将磁盘的数据页缓存到内存中的一片区域
- 当读取数据时,如果数据在Buffer Pool中,直接读取,否则去磁盘读,然后缓存到Buffer Pool中
- 当修改数据时,会直接修改在Buffer Pool中的数据,并将数据所在页设置为脏页,后台由另一个线程将脏页写入磁盘。
- Buffer Pool中除了缓存数据页,还缓存了undo页,undo log日志首先写入undo页,undo页和数据页一样由redo log来记录,然后通过redo log落盘
3、WAL
- 全称write-ahead-loggin,指的是MySQL的写不是先写磁盘,而是先写日志,后续在合适时间再写磁盘,buffer pool和redo log的设计就是WAL技术
4、redo log
- 由于buffer pool是存储在内存,所以会有丢失风险,因此需要对在buffer pool中修改的数据记录到redo log中,事务提交后,redo log日志落盘,保证了事务的持久性
- redo log是物理日志,记录了对某个数据页做了什么修改,比如对A表的B数据页C偏移量的地方做了D更新。
- 同样redo log也有自己的缓存区,即redo log buffer,写日志前先写buffer,后续在以下情况下落盘:
1、MySQL正常关闭
2、redo log buffer写入量大于其空间一半
3、后台线程每隔一秒落盘
4、事务提交时由innodb_flush_log_at_trx_commit参数控制:0时不落盘,1时落盘,2时写到操作系统文件缓存,后续由操作系统落盘。因此性能比较为0>2>1;安全性比较为1>2>0; - redo log文件是由两个文件组成,第一个文件写满了写第二个,第二个写满了写第一个,因此是一个循环写的过程,两个文件都满了,MySQL被阻塞,将buffer pool脏页落盘,然后清除redo log文件中落盘数据。
5、总结
- undo log用做事务回滚,记录了事务更新前的数据,保证事务的原子性,同时也用于实现MVCC
- redo log用做重做数据,记录了事务更新后的数据,保证事务的持久性。通过自己的redo log buffer来缓存日志并按一定规则进行落盘操作。redo log写入文件是一个循环写的过程。
- Buffer Pool用做缓存数据页,如果涉及数据更新,则直接对缓存数据数据页做更新,更新后的数据页称为脏页,脏页由后台线程落盘
6、问题
- 如果在事务执行过程中(未提交)宕机,MySQL如何处理?
答:如果在事务执行过程中宕机,由于事务没有提交,buffer pool里的数据也未落盘,因此执行过程中的修改其实无效,MySQL无需处理 - 如果在事务提交后宕机,MySQL如何处理?
答:事务提交时,Innodb 会将记录写到redo log buffer中。事务提交后,会根据innodb_flush_log_at_trx_commit参数决定是否落盘,即0:不落盘,1:落盘,2:写入文件缓存,由操作系统落盘。如果设置为0,则会发生数据丢失;如果设置为1,在落盘过程中宕机也会发生丢失;如果设置为2,机器宕机会丢失,MySQL挂了不会丢失。