InnoDB更新事务流程
涉及内容
- 一次InnoDB的事务更新操作涉及Buffer Pool,BinLog,RedoLog,UndoLog和物理磁盘。
Buffer Pool:
- Buffer Pool是InnoDB引入的中间层:内存上的一块连续空间,用来缓存数据页,每个数据页的大小为16KB。它的存在是为了提高SQL的读写性能,避免每次查询和修改都直接与磁盘进行交互。于是,每次读取数据的时候,InnoDB会先检查Buffer Pool中是否存在该数据,存在则直接从内存中取,若不存在,再去磁盘中获取,获取后将该数据所在的页复制一份存入Buffer Pool。这样做,避免了频繁的磁盘读取,从而可以提高查询性能。
BinLog:
- BinLog是MySQL用来记录所有DDL和DML语句的二进制文件,用于数据库的数据备份,数据复制等操作。为了支持高并发,数据库有时会进行读写分离,主库的数据通过BinLog日志来同步复制给从库。
RedoLog:
- RedoLog是MySQL用于实现数据持久化和崩溃恢复的一种机制,在事务执行过程中,MySQL会将事务做的改动记录到RedoLog中。当系统发生崩溃或数据异常时,RedoLog可以进行数据库重启后的恢复工作,保证了数据库事务的持久性。
UndoLog:文章来源:https://www.toymoban.com/news/detail-787648.html
- UndoLog用于事务的回滚操作,当一个事务执行过程中,MySQL会将修改前的数据记录到UndoLog中,如果事务发生了异常需要回滚,则从UndoLog中找到对应的记录执行,以撤销事务的操作,确保事务的原子性和一致性。此外,UndoLog还支持MVCC(多版本并发控制)机制,用于在并发事务执行时,提供一定的隔离性。
完整的更新流程步骤
- 在Buffer Pool中读取数据,若该数据不在Buffer Pool中,则从磁盘读取该数据所在的数据页放入Buffer Pool中。
- 记录UndoLog,在数据修改前,InnoDB会在UndoLog中记录修改前的数据。UndoLog最开始写在内存中,由后台线程定时刷入磁盘。
- 在Buffer Pool中执行Update语句,更新数据。然后将更新后的数据页状态设置为脏页(dirty page),表示该页已修改但未刷入磁盘。
- 记录RedoLog,InnoLog将修改操作写入RedoLog buffer pool中,此时为二阶段提交的prepare阶段。
- 记录BinLog,在提交过程中,InnoDB会将事务提交信息记录到BinLog中。BinLog中记录的信息包括:事务开始时间,数据库名,表名,事务ID,SQL语句等。后续通过Binlog进行主从复制。将BinLog写入磁盘中,完成后将RedoLog也写入磁盘。此为二阶段提交的commit阶段。
- 写入磁盘,在提交过程后,InnoDB会将Buffer Pool里的脏页写入磁盘,以保证数据库的持久性。这个写入过程是后台线程异步执行的,具有延迟性。
注意:在BinLog和RedoLog写入的时候,是分了两个阶段,以二阶段提交的方式来保证一致性。文章来源地址https://www.toymoban.com/news/detail-787648.html
二阶段提交
二阶段提交的步骤
- prepare阶段
- 这个阶段SQL成功执行并生成RedoLog,并处于准备阶段。
- commit阶段
- BinLog持久化:通过write()方法将BinLog写入文件缓冲区,再通过fsync()将文件缓存区中的BinLog写入磁盘。
- RedoLog写入磁盘。
为什么需要二阶段提交
- 采用二阶段可以保证BinLog日志和RedoLog日志的一致性。如果二者的一致性不能保证,那么主从库的数据就会出现不一致。
- 如果RedoLog写入成功,而BinLog还未写入成功,此时主库崩了,那么重启后,主库可以通过RedoLog恢复数据,但是BinLog日志的数据没写成功,那么主从同步后,从库便缺少了相关的数据。
- 如果BinLog写入成功,而RedoLog还未写入成功,此时主库崩了,那么重启后,主库可以无法RedoLog恢复丢失的数据,仍是事务执行前的状态,但是BinLog日志的数据已经写成功,那么主从同步后,从库会得到事务执行后的数据。
二阶段提交如何保证一致性
- 若在prepare阶段数据库崩溃了,此时RedoLog已经写完,状态在prepare阶段,而BinLog没有成功写入,那么重启后根据RedoLog记录的事务id将对应事务进行回滚。
- 若RedoLog在prepare阶段,而BinLog已经写入成功的时候数据库崩溃了,则重启后,若事务id对应的BinLog已经写入磁盘了,则即使RedoLog还没有commit,MySQL也要提交该事务。
- 通过二阶段提交,保证了RedoLog和BinLog的一致性。
到了这里,关于MySQL--InnoDB的一次更新事务实现流程与二阶段提交的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!