尼恩说在前面
谈谈:mysql 中 redo log 、undo log、 binlog 分别实现了事务ACID的那些特性? 谈谈:如何解决 bin log 与 redo log 的一致性问题? 谈谈:一条 SQL 更新语句是如何执行的? 谈谈:redo log / bin log 两阶段提交原理 .......
最新《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》的PDF,请关注本公众号【技术自由圈】获取,回复:领电子书
本文目录
- 尼恩说在前面
- 1. 基础知识:MySQL架构&SQL语句执行流程
- 1.1 服务层(Server Layer) 主要负责以下功能:
- 1.2 Server 服务层(Service Layer)三个核心组件
-1. 解析器(Parser)
-2. 优化器(Optimizer)
-3. 执行器(Executor)
-三个核心组件之间的交互流程
- 1.3 SQL语句的执行过程
- sql查询语句的执行流程
- Mysql数据更新语句的流程:
- 1.4 以下面以一条简单的 SQL 语句为例,介绍sql更新流程
- 2. undolog 原子性 + 隔离性
- 什么是undolog?
- 什么是事务回滚?
- 什么是MVCC和事务的隔离性?
- 基础知识-- Buffer Pool
- 3. redo log – 持久性
- 什么是 redo log ?
- redo log buffer的进行刷盘
- 不同刷盘策略的流程演示
-innodb_flush_log_at_trx_commit=1 流程图
-innodb_flush_log_at_trx_commit=2 流程图
-innodb_flush_log_at_trx_commit=0 流程图
- 如何选择 redo log 参数刷盘?
- redolog日志文件的写入机制:循环写入
- 通过redo log实现crash-safe 能力
- 4. bin log – 一致性
- 什么是binlog ?
- bin log的二进制日志格式
- binlog 刷盘时机
- bin log 与 两阶段提交
- binlog的日志结构
- binlog日志文件结构
- 中继日志 relay-log与主从复制一致性
- mysql主从复制流程
- 中继日志 relay-log 的文件结构
- 中继日志 relay-log 的回放流程
- Binlog 与两大数据一致性
-1 崩溃一致性(Crash Consistency)
-2 中继日志与主从复制的一致性
- 崩溃恢复时的判断规则
- commit阶段写入 binlog 之前发生了崩溃,事务回滚
- commit阶段写入 binlog 之后发生了崩溃,事务恢复
- undo log、redo log、binlog的定义和对比
- 尼恩架构团队的塔尖 sql 面试题
- 说在最后:有问题找老架构取经
1. 基础知识:MySQL架构&SQL语句执行流程
第1层:连接层
第2层:server 服务层:
第3层:存储引擎层:
第4层:文件系统层:
1.1 服务层(Server Layer) 主要负责以下功能:
语法解析:将客户端发送的 SQL 查询转化为可理解的内部结构,检查 SQL 语句是否符合 MySQL 语法规则。 查询重写:服务层会将一些查询优化为等效的、执行效率更高的形式,比如将子查询改写为 JOIN,或简化复杂的表达式。 查询优化:MySQL 服务层有一个查询优化器,会基于数据统计信息,选择最优的执行计划。包括表的连接顺序、索引的选择等。其优化方式包括基于成本的优化器(CBO)。
1.2 Server 服务层(Service Layer)三个核心组件
解析器(Parser) 优化器(Optimizer) 执行器(Executor)
1. 解析器(Parser)
SQL 词法分析:解析器首先对 SQL 语句进行词法分析,将 SQL 语句分割成多个“单词”或“标记”,如表名、列名、关键字等。 语法分析:接着,解析器会根据 SQL 语法规则生成对应的解析树(Parse Tree),用来描述 SQL 语句的逻辑结构。这个过程检查 SQL 语句的语法是否正确。 语义分析:确认 SQL 语句中涉及的数据库对象是否存在(比如表名、字段名是否有效),并且检查权限。
2. 优化器(Optimizer)
逻辑优化:优化器会对 SQL 语句进行逻辑优化,比如 SQL 语句重写、消除冗余操作、合并重复条件、重新排列 WHERE 子句中的条件等。 物理优化:在物理优化阶段,优化器会选择最优的访问路径和执行顺序。例如,它会决定使用哪种索引(如果有多个索引可选),是否做全表扫描,如何连接多张表(选择嵌套循环、哈希连接或排序合并连接等)。 成本估算:优化器会基于数据库的统计信息(例如表的大小、索引的选择性等)来估算不同执行计划的成本,选择代价最低的执行方案。
3. 执行器(Executor)
权限检查:在执行之前,执行器会首先检查用户是否有权限执行相应的操作。如果没有权限,则返回错误信息。 执行执行计划:执行器根据生成的执行计划,依次调用存储引擎的接口来执行具体的操作。例如,如果是查询操作,执行器会调用存储引擎来读取相应的数据;如果是插入操作,执行器则会调用存储引擎来插入数据。 结果返回:执行器根据查询的结果,将数据以合适的格式返回给客户端。如果涉及多个步骤(如 JOIN 操作),执行器会协调各个步骤的执行,并组合最终的结果集。
三个核心组件之间的交互流程
解析器:SQL 语句转换为解析树。 优化器:生成最优的执行计划。 执行器:根据计划调用存储引擎执行操作并返回结果。
1.3 SQL语句的执行过程
1.3.1 sql查询(select)语句的执行流程
1.3.2 Mysql数据更新(update)语句的流程:
update table set name=“塔尖技术社区 技术自由圈” where id = 1000;
的流程如下:执行器负责具体执行,会调用存储引擎的接口,通过主键索引树搜索获取 id = 1 这一行记录:
如果 id=1000 这一行所在的数据页本来就在 buffer pool 中,就直接返回给执行器更新; 如果记录不在 buffer pool,将数据页从磁盘读入到 buffer pool,返回记录给执行器。
如果一样的话就不进行后续更新流程; 如果不一样的话就把更新前的记录和更新后的记录都当作参数传给 InnoDB 层,让 InnoDB 真正的执行更新记录的操作;
老架构师尼恩提示:Undo Log 的第一个目标就是为了保证事务的 原子性(Atomicity)。事务的原子性意味着事务中的所有操作要么全部成功,要么全部回滚到事务开始之前的状态,不会出现部分执行的情况。如果事务在执行过程中发生错误,或者用户明确发起了回滚操作( ROLLBACK
),数据库会通过读取 Undo Log 中记录的旧值,恢复被修改的数据到事务开始前的状态。这种恢复操作确保了事务的原子性,即便事务中途失败,数据库也能够恢复到一致的状态。当然,Undo Log 还用于实现 MVCC(Multi-Version Concurrency Control)。当不同事务同时读取数据时,Undo Log 提供了“旧版本”的数据视图,使得即使某个事务在修改数据,其他事务仍然能够读取到事务开始时的数据版本。这不仅提升了并发性能,也间接支持了原子性和隔离性的实现。所以,Undo Log 实现了对 事务的 原子性、隔离性的支持。 尼恩提示:模式的时候,一般人都知道 undo log 实现了事务的原子性, 如果把undo log的 隔离性说出来,一定会惊讶到 面试官的。
先记录 redo log ,再更新数据, InnoDB 层开始更新数据记录之前,根据 WAL 思想,先记录修改数据页面的 redo log ,然后再真正的修改数据页面。 修改数据页面的过程是修改 Buffer Pool 中数据所在的页,然后将其页设置为脏页,而不是之间写磁盘。 为了减少磁盘I/O,不会立即将脏页写入磁盘,后续由后台线程选择一个合适的时机将脏页写入到磁盘。 至此,一条记录更新完了。 老架构师尼恩提示:Redo Log 是实现事务 持久性(Durability) 的关键机制之一。事务的持久性意味着一旦事务提交成功,即使数据库系统发生崩溃,系统也能够在重启后保证数据不会丢失。Redo Log 通过记录事务的修改并在崩溃后进行恢复,确保数据库的一致性和数据的持久性。 记录 binlog 在一条更新语句执行完成后,然后开始记录该语句对应的 binlog。 此时记录的 binlog 会被保存到 binlog cache,并没有刷新到硬盘上的 binlog 文件。 在事务提交时,才会统一将该事务运行过程中的所有 binlog 刷新到硬盘。 老架构师尼恩提示:Binlog(Binary Log) 在 MySQL 中主要用于 主从复制和 数据恢复,它通过协调 redo log 和 binlog 的写入,确保事务的一致性( 包括两个一致性:崩溃一致性&主从一致性),特别是在分布式场景下的 主从一致性。 事务提交,以两阶段提交 为例: prepare 阶段:将 redo log 对应的事务状态设置为 prepare,然后将 redo log 刷新到硬盘; commit 阶段:将 binlog 刷新到磁盘,接着调用引擎的提交事务接口,将 redo log 状态设置为 commit(将事务设置为 commit 状态后,刷入到磁盘 redo log 文件); 老架构师尼恩提示:原始的两阶段提交 的性能比较低,更高性能的提交方式是 组提交,说白了就是批量提交。但是原始的两阶段提交比较好理解,为了方便说明,这里不说组提交的过程,只说两阶段提交. 至此,一条更新语句执行完成。
1.4 以下面以一条简单的 SQL update 语句为例,介绍sql更新流程
update table set name=“塔尖技术社区 技术自由圈” where id = 1000;
执行器:找存储引擎取到 id = 1000 这一行记录 存储引擎:根据主键索引树找到这一行,如果 id = 1000 这一行所在的数据页本来就在内存池(Buffer Pool)中,就直接返回给执行器;否则,需要先从磁盘读入内存池,然后再返回 执行器:拿到存储引擎返回的行记录,把 name 字段设置为 “塔尖技术社区 技术自由圈”,得到一行新的记录,然后再调用存储引擎的接口写入这行新记录 存储引擎:将这行新数据更新到内存中,同时将这个更新操作记录到 redo log 里面,为 redo log 中的事务打上 prepare
标识。然后告知执行器执行完成了,随时可以提交事务注意不要把这里的提交事务和我们 sql 语句中的提交事务 commit 命令搞混了哈,我们这里说的提交事务,指的是事务提交过程中的一个小步骤,也是最后一步。当这个步骤执行完成后,commit 命令就执行成功了。 执行器:生成这个操作的 bin log,并把 bin log 写入磁盘 执行器:调用存储引擎的提交事务接口 存储引擎:把刚刚写入的 redo log 状态改成提交( commit
)状态,更新完成
如果 redo log 里面的事务是完整的,也就是已经有了 commit 标识,则直接提交 如果 redo log 里面的事务处于 prepare 状态,则判断对应的事务 binlog 是否存在并完整
a. 如果 binlog 存在并完整,则提交事务; b. 否则,回滚事务。
尼恩提示:以上内容比较复杂,后面会在《尼恩Java面试宝典》配套视频中,进行详细解读。
2. undolog 实现 ACID 中的 原子性 + 隔离性
什么是undolog ?
事务回滚 MVCC
什么是事务回滚?
事务进行insert操作,undo log记录delete操作 事务进行delete操作,undo log记录insert操作 事务进行update操作(value1 改为value2 ),undolog记录update操作(value2 改为value3 )
trx_id代表事务id,记录了这一系列事务操作是基于哪个事务; roll_pointer代表回滚指针,就是当要发生rollback回滚操作时,就通过roll_pointer进行回滚,这个链表称为版本链。
Buffer Pool 是 InnoDB 的内存缓存,用于存储数据页和索引页,以便快速访问。它通过减少磁盘 I/O,提高数据库的整体性能。 在 Buffer Pool 中,除了数据页外,还可以存储 Undo Log 页,这样可以加速事务的回滚和数据恢复。
尼恩提示:以上内容比较复杂,后面会在《尼恩Java面试宝典》配套视频中,进行详细解读。
什么是MVCC和事务的隔离性?
MVCC
机制主要通过三个组件实现:隐藏字段
Undo-log
日志ReadView
。
基础知识-- Buffer Pool
空闲页 干净页 脏页【类似操作系统中,修改位为1】
如果数据页已经在内存中,服务器可以直接返回数据,而不需要等待磁盘IO操作。 如果数据页不在内存中,服务器会从磁盘读取数据,并将其存储在Buffer Pool中,以便后续查询可以直接从内存中获取数据。
一个大的Buffer Pool可以缓存更多的数据页,从而减少对磁盘的IO操作,提高查询性能。 但是过大的Buffer Pool可能会占用太多的服务器内存资源导致其他服务器的性能下降。
索引页存储了InnoDB表的索引结构, 数据页存储了InnoDB表的实际数据行, Undo页存储了旧版本的数据,用于支持事务的ACID属性中的原子性、隔离性(Isolation)。
LRU链表是Buffer Pool中最主要的链表,用于管理缓存页的访问顺序和淘汰策略。 free链表管理未被使用的空闲页, flush链表管理需要被刷新到磁盘的脏页。
可以通过调整 innodb_buffer_pool_size
参数来配置Buffer Pool的大小。此外, innodb_buffer_pool_instances
参数用于将InnoDB Buffer Pool分割成多个实例,每个实例拥有自己的LRU算法和hash索引,这有助于提高并发性能。innodb_buffer_pool_chunk_size
参数用于设置每个Buffer Pool实例的块大小,这有助于减少内存碎片。
SHOW STATUS
命令查看Buffer Pool的使用情况,如Innodb_buffer_pool_read_requests
表示从Buffer Pool中读取的次数,Innodb_buffer_pool_reads
表示直接从磁盘读取的次数等。尼恩提示:以上内容比较复杂,后面会在《尼恩Java面试宝典》配套视频中,进行详细解读。
3. redo log 实现 ACID 中的 持久性
什么是 redo log ?
事务提交前崩溃,通过 undo log 回滚事务 事务提交后崩溃,通过 redo log 恢复事务
尼恩提示:以上内容比较复杂,后面会在《尼恩Java面试宝典》配套视频中,进行详细解读。
redo log buffer的进行刷盘
Master Thread每秒刷盘一次 redo log buffer 剩余空间 < 1/2, 刷盘一次 通过innodb_flush_log_at_trx_commit参数控制 - 0:有事务提交的情况下,每秒刷盘一次 1:每次提交事务,刷盘一次(默认值,性能差) 2:每次提交事务,把日志记录放到OS内核缓冲区,刷盘时机交给OS(性能好,低可靠)
0 :设置为 0 的时候,表示每次事务提交时不进行刷盘操作。有事务提交的情况下,每秒刷盘一次。(性能好,低可靠) 1 :设置为 1 的时候,表示每次事务提交时都将进行刷盘操作(默认值)。(高可靠, 低性能) 2 :设置为 2 的时候,表示每次事务提交时都只把 redo log buffer 内容写入 page cache,刷盘时机交给OS
不同刷盘策略的流程演示
innodb_flush_log_at_trx_commit=1 流程图
含义:每当一个事务提交时,InnoDB 会将日志缓冲区的内容写入文件系统缓存,并立即将该日志从文件系统缓存刷新到磁盘( fsync
)。持久性:提供最强的持久性,保证每次事务提交后日志都已经持久化到磁盘。如果数据库崩溃,最多丢失未提交的事务。 性能:性能最差,因为每次事务提交都会执行磁盘写操作,尤其在高并发写入的场景下,可能会成为性能瓶颈。
innodb_flush_log_at_trx_commit=2 流程图
含义:在每次事务提交时,InnoDB 会将日志缓冲区的内容写入操作系统的文件系统缓存page cache(不执行 fsync
),由操作系统负责将日志写入磁盘。持久性:如果数据库崩溃,而如果服务器没有崩溃,数据不会丢失。如果服务器也崩溃,page cache 默认是缓存5s的数据,最多丢失最近5 秒内的事务数据,但与 innodb_flush_log_at_trx_commit=0
不同的是,日志至少会被写入文件系统缓存,这在某些情况下可以提供更好的安全性。性能:性能较高,因为事务提交时只需要将日志写入内存中的文件系统缓存,而不需要立即进行磁盘 I/O。
操作系统定期启动后台线程(如 Linux 的 pdflush
或flush
线程)将脏页(dirty pages,即修改过但尚未刷到磁盘的页)从 Page Cache 刷写到磁盘。默认情况下,Linux 系统大约每 5 秒启动一次刷盘操作。该周期由内核参数 dirty_writeback_centisecs 控制,默认值为 500,即 5 秒。
innodb_flush_log_at_trx_commit=0 流程图
含义:InnoDB 每秒将日志缓存(Redo Log Buffer)刷新到磁盘,但不会在每次事务提交时刷新。即使事务提交,也只是将日志写到内存中的日志缓冲区,1 秒后由后台线程将其写入磁盘。 持久性:如果数据库崩溃,可能会丢失最近 1 秒内的事务数据。 性能:性能最高,因为写磁盘的频率最小,但持久性最弱。
如何选择 redo log 参数刷盘?
数据安全性:参数 1 > 参数 2 > 参数 0 写入性能:参数 0 > 参数 2> 参数 1
redolog日志文件的写入机制:循环写入
write pos:当前记录写到的位置,或者说 当前redo log文件写到了哪个位置 checkpoint:当前要擦除的位置,或者说 目前redo log文件哪些记录可以被覆盖
当数据页进行刷盘操作(CheckPoint)时,check point指针也会顺时针进行覆盖(黄色变成绿色); 当write pos追上了check point就说明 redo log 文件存满了,那就要强制CheckPoint了,将Buffer pool 缓冲池中的脏页刷盘,然后再移动check point指针,这样就可以继续向重做日志组中写入数据了。
write pos - checkpoint:待写入的部分 checkpoint - write pos:还未刷入磁盘的记录
尼恩提示:以上内容比较复杂,后面会在《尼恩Java面试宝典》配套视频中,进行详细解读。
通过redo log实现crash-safe 能力
发生崩溃 ,如何通过redo log实现数据的恢复? 后面尼恩会写一篇文章进行详细的介绍,具体请参见 尼恩的技术自由圈 公众号。
4. bin log 实现 ACID 中的 一致性
什么是binlog ?
备份恢复,实现崩溃一致性(Crash Consistency) 主从复制,实现 主从复制的一致性
老架构师尼恩提示:原始的两阶段提交 的性能比较低,更高性能的提交方式是 组提交,说白了就是批量提交。但是原始的两阶段提交比较好理解,为了方便说明,这里不说组提交的过程,只说两阶段提交.
bin log的二进制日志格式
STATEMENT:增删改SQL语句,存储空间要求小 ROW:记录表行的更改情况,存储空间要求大 MIXED:混合场景,默认情况下STATEMENT,少数情况下ROW
STATEMENT:可读性较高,日志量少,但是不够严谨 ROW :可读性很低,日志量大,足够严谨
binlog 刷盘时机
尼恩提示:
参数 binlog_cache_size 用于控制单个线程内 binlog cache 所占内存的大小。 如果超过了这个参数规定的大小,就要暂存到磁盘(Swap)。
图中的 write,指的就是指把日志写入到 page cache ,但是并没有把数据持久化到磁盘,因为数据还缓存在文件系统的 page cache 里,write 的写入速度还是比较快的,因为不涉及磁盘 I/O。 图中的 fsync,才是将数据持久化到磁盘的操作,这里就会涉及磁盘 I/O,所以频繁的 fsync 会导致磁盘的 I/O 升高。
sync_binlog = 0 的时候,表示每次提交事务都只 write,不 fsync,后续交由操作系统决定何时将数据持久化到磁盘; sync_binlog = 1 的时候,表示每次提交事务都会 write,然后马上执行 fsync; sync_binlog =N(N>1) 的时候,表示每次提交事务都 write,但累积 N 个事务后才 fsync。
sync_binlog
参数,可以在数据安全性和性能之间取得平衡。bin log 与 两阶段提交
bin log刷盘后,redo log还未来得及刷盘,数据库宕机,数据不一致。 redo log刷盘后,bin log还未来得及刷盘,数据库宕机,数据不一致。
Prepare:XID(内部 XA 事务的 ID) 写入到 redo log,同时将 redo log 对应的事务状态设置为 prepare,然后将 redo log 持久化到磁盘(默认redo log刷盘策略); Commit:XID 写入到 bin log,马上将 bin log 刷盘(sync_binlog = 1),接着调用引擎的提交事务接口,将 redo log 状态设置为 commit,只要 bin log 写磁盘成功,就算 redo log 的状态还是 prepare 也没有关系,一样会被认为事务已经执行成功。
sync_binlog = 1 表示每次提交事务都会 write binlog,然后马上执行 fsync; innodb_flush_log_at_trx_commit=1(默认值):设置为 1 的时候,表示每次事务提交时都将进行redo log刷盘操作(默认值),所以默认是高可靠, 低性能
尼恩提示:以上内容比较复杂,后面会在《尼恩Java面试宝典》配套视频中,进行详细解读。
当事务在prepare阶段crash,数据库recovery的时候,该事务未写入binlog log并且存储引擎未提交,将该事务rollback。 当事务在Commit 阶段 写 binlog阶段crash,此时日志还没有成功写入到磁盘中,启动时会rollback此事务。 当事务在Commit 阶段 写 binlog阶段 并且已经fsync()到磁盘后crash,但是InnoDB没有来得及commit,此时MySQL数据库recovery的时候将会读出binlog日志的Xid_log_event,然后告诉InnoDB提交这些XID的事务,InnoDB提交完这些事务后会回滚其它的事务,使存储引擎和二进制日志始终保持一致。
事务的一致性:当事务提交后,binlog 和 redo log 保持一致。如果事务提交成功,则 binlog 和 redo log 都会反映出相同的操作;如果失败,则事务会被回滚,binlog 也不会记录到这个事务。 数据恢复:当 MySQL 恢复时,系统可以根据 redo log 和 binlog 的状态,确保事务的一致性,避免部分提交或丢失。
binlog的日志结构
binlog日志文件结构
...
HOSTNAME-bin.0000101
HOSTNAME-bin.0000102
HOSTNAME-bin.0000103
...
HOSTNAME-bin.index
...
if binlog-version > 1 {
8 position
}
string[p] name of the next binlog
create table test(text varchar(20));
insert into test values ('test_text');
select * from test;
flush logs;
show binlog events in 'binlog.000029';
show binary logs; #查看binlog列表
show master status; #查看最新的binlog
中继日志 relay-log与主从复制一致性
mysql主从复制流程
master 写入binlog:master 服务器会将 SQL 记录通过多 dump 线程写入到 binary log 中。 连接master:slave 服务器连接master。开启一个 io thread 线程向服务器发送请求,向 master 服务器请求 binary log。 推送binlog:master 服务器在接收到请求之后,根据偏移量将新的 binary log 发送给 slave 服务器。 写入中继日志:slave 服务器收到新的 binary log 之后,写入到自身的 relay log 中,这就是所谓的中继日志。 执行中继日志:slave 服务器,单独开启一个 sql thread 读取 relay log 之后,写入到自身数据中。
中继日志 relay-log 的文件结构
HOSTNAME-relay.0000101
HOSTNAME-relay.0000102
HOSTNAME-relay.0000103
...
HOSTNAME-relay.index
中继日志 relay-log 的回放流程
Master收到客户端请求语句,在语句结束之前向二进制日志写入一条记录,可能包含多个事件。 此时,一个Slave连接到Master,Master的dump线程从binlog读取日志并发送到Slave的IO线程。 IO线程从master.info读取到上一次写入的最后的位置。 IO线程写入日志到relay-log中继日志,如果超过指定的relay-log大小,写入轮换事件,创建一个新的relay-log。 更新master.info的最后位置 SQL线程从relay-log.info读取进上一次读取的位置 SQL线程读取日志事件 在数据库中执行sql 更新relay-log.info的最后位置 Slave记录自己的binlog日志
先记录中继日志,然后更新master.info位置 此时服务器崩溃,写入master.info失败 服务器恢复,再次同步从master.info获取到的是上一次的位置,会导致事件重复执行
Binlog 与两大数据一致性
第一个数据一致性: 崩溃一致性(Crash Consistency)
第一阶段(Prepare 阶段):
当一个事务执行完所有操作并准备提交时,InnoDB 首先会将修改操作写入到 redo log,并将其标记为 prepare 状态。这意味着事务的物理修改操作已经记录到了 redo log 中,但事务尚未真正提交。 此时,如果系统崩溃,事务可以通过 undo log 回滚,保持一致性。
写入 binlog:将 binlog 刷新到磁盘。这时,binlog 确保了主从库在复制时具有相同的操作逻辑。 提交 redo log:InnoDB 会将 redo log 的状态修改为 commit,表示事务已经正式提交。
当事务在prepare阶段crash,数据库recovery的时候,该事务未写入binlog log并且存储引擎未提交,将该事务rollback。 当事务在Commit 阶段 写 binlog阶段crash,此时日志还没有成功写入到磁盘中,启动时会rollback此事务。 当事务在Commit 阶段 写 binlog阶段 并且已经fsync()到磁盘后crash,但是InnoDB没有来得及commit,此时MySQL数据库recovery的时候将会读出binlog日志的Xid_log_event,然后告诉InnoDB提交这些XID的事务,InnoDB提交完这些事务后会回滚其它的事务,使存储引擎和二进制日志始终保持一致。
事务的一致性:当事务提交后,binlog 和 redo log 保持一致。如果事务提交成功,则 binlog 和 redo log 都会反映出相同的操作;如果失败,则事务会被回滚,binlog 也不会记录到这个事务。 数据恢复:当 MySQL 恢复时,系统可以根据 redo log 和 binlog 的状态,确保事务的一致性,避免部分提交或丢失。
第2个数据一致性:中继日志与主从复制的一致性
主库提交事务时会先写入 binlog 从库则通过读取主库的 binlog 重新执行相同的操作。
只有当事务在主库提交成功(即 binlog 和 redo log 一致)后,主库才会将 binlog 传递给从库。 从库应用 binlog 以确保主库和从库的数据保持一致。
崩溃恢复时的判断规则
如果 redo log 里面的事务是完整的,也就是已经有了 commit 标识,则直接提交 如果 redo log 里面的事务处于 prepare 状态,则判断对应的事务 binlog 是否存在并完整
a. 如果 binlog 存在并完整,则提交事务; b. 否则,回滚事务。
commit阶段写入 binlog 之前发生了崩溃,事务回滚
commit阶段写入 binlog 之后发生了崩溃,事务恢复
statement 格式的 bin log,最后会有 COMMIT row 格式的 bin log,最后会有 XID event
binlog-checksum
参数,用来验证 bin log 内容的正确性。undo log、redo log、binlog的定义和对比
定义和作用 | 所在架构层级 | 日志形式 | 所在文件和默认名称,组织结构 | 是否缓存,如何缓存 | 写文件方式 | |
尼恩架构团队的塔尖 sql 面试题
说在最后:有问题找老架构取经
被裁之后, 空窗1年/空窗2年, 如何 起死回生 ?
上岸奇迹:中厂大龄34岁,被裁8月收一大厂offer, 年薪65W,转架构后逆天改命!
案例2:42岁被裁2年,天快塌了,急救1个月,拿到开发经理offer,起死回生
案例3:35岁被裁6个月, 职业绝望,转架构急救上岸,DDD和3高项目太重要了
案例4:失业15个月,学习40天拿offer, 绝境翻盘,如何实现?
被裁之后,100W 年薪 到手, 如何 人生逆袭?
100W案例,100W年薪的底层逻辑是什么? 如何实现年薪百万? 如何远离 中年危机?
如何 逆天改命,包含AI、大数据、golang、Java 等
实现职业转型,极速上岸
关注职业救助站公众号,获取每天职业干货
助您实现职业转型、职业升级、极速上岸
---------------------------------
实现架构转型,再无中年危机
关注技术自由圈公众号,获取每天技术千货
一起成为牛逼的未来超级架构师
几十篇架构笔记、5000页面试宝典、20个技术圣经
请加尼恩个人微信 免费拿走
暗号,请在 公众号后台 发送消息:领电子书
如有收获,请点击底部的"在看"和"赞",谢谢