【MySQL | 第一篇】 深入理解三大日志(undo Redo Bin)
目录Undo Log日志Redo Log日志Redo Log与Bin Log的区别Bin Log日志三大日志全流程Undo Log日志一、核心定义UndoLog是MySQL InnoDB存储引擎特有的事务回滚日志核心作用是记录事务执行前的数据版本用于事务回滚、MVCC实现是InnoDB事务原子性、一致性的核心保障。二、核心作用事务回滚事务执行失败/手动ROLLBACK时通过Undo Log还原数据到执行前状态保证事务要么全部成功要么全部失败。MVCC实现快照读一致性非锁定读读取历史数据版本避免读写阻塞提升并发性能。崩溃恢复数据库崩溃重启时利用Undo Log回滚未提交事务保证数据一致性。三、存储结构与类型1. 存储位置不单独存文件存储在InnoDB的共享表空间ibdata1或独立undo表空间。分为回滚段Rollback Segment默认128个回滚段每个回滚段管理多个Undo Log。2. 两种类型1INSERT Undo Log仅记录INSERT操作的反向信息删除插入的行。事务提交后立即删除无MVCC复用价值因为是新数据没有历史undo log链条。2UPDATE Undo Log记录UPDATE/DELETE操作的旧数据版本。事务提交后不立即删除保留供MVCC读取历史版本由purge线程异步清理。四、工作原理1. 事务执行流程事务开始InnoDB分配Undo Log空间。执行DMLINSERT/UPDATE/DELETE先写Undo Log记录旧数据。再修改Buffer Pool中的数据页。事务提交INSERT Undo Log直接删除。UPDATE Undo Log标记为可清理等待purge线程回收。事务回滚读取Undo Log执行反向操作还原数据。2. MVCC实现原理每行数据隐含trx_id事务ID、roll_pointer回滚指针。roll_pointer指向Undo Log中的历史版本链。快照读时根据事务ID读取对应版本无需加锁。五、Purge线程清理机制1. 作用异步清理已提交、无活跃事务引用的UPDATE Undo Log释放空间。2. 触发条件事务提交后Undo Log标记为可清理。系统空闲时purge线程批量清理。3. 影响清理不及时会导致Undo Log膨胀占用磁盘空间影响性能。Redo Log日志redo log重做日志是 InnoDB 存储引擎独有的物理日志核心作用保证事务持久性、崩溃恢复、提升写入性能是 InnoDB 实现 ACID 中D持久性的关键。一、作用崩溃恢复MySQL 宕机重启后通过 redo log 恢复未刷盘的脏页数据避免数据丢失。提升写入性能事务提交时先写 redo log顺序写再异步刷脏页到磁盘随机写顺序写远快于随机写。保证持久性只要 redo log 落盘事务就“持久化成功”即使内存数据丢失也能恢复。二、内容数据页的物理修改如“在第100号数据页的第20个偏移量写入值10”。每条redo记录由“表空间号数据页号偏移量修改数据长度具体修改的数据”组成三、两阶段写入WAL 机制声明两阶段写入WAL两阶段提交prepare commit 不一样WALWrite-Ahead Logging预写日志先写日志再写数据。(说的是磁盘阶段先落盘日志再刷盘数据页)事务修改数据 → 内存中修改脏页未刷盘。生成 redo log → 写入 redo log buffer。事务提交 → redo log buffer 刷入磁盘commit 必须落盘。后台线程异步将脏页刷入磁盘。这里所说的脏页是在缓冲池中的数据页本质先改内存中的数据在写内存中的redo log之后先刷盘log最后再异步刷盘数据三、组成buffer 磁盘文件1. redo log buffer内存临时存放 redo log。刷盘时机事务提交默认innodb_flush_log_at_trx_commit1必刷。每秒后台线程刷一次。buffer 满 1/2 时自动刷。2. redo log file磁盘固定大小、循环使用的日志文件。两个关键指针write pos 是当前记录的位置一边写一边后移checkpoint是当前要擦除的位置也是往后推移可用空间 write pos ~ checkpoint写满则阻塞写入等待 checkpoint 推进。四、刷盘策略补充的是三中的redo log buffer内存决定 redo log 落盘强度直接影响性能 vs 数据安全1默认性能低最安全每次事务提交redo log 必刷磁盘fsync不丢数据。2性能和安全居中提交时写入操作系统文件缓存每秒刷一次磁盘MySQL挂了不丢操作系统宕机可能丢 1 秒数据。0高性能不安全仅后台线程每秒刷盘MySQL/OS 宕机都可能丢数据。Redo Log与Bin Log的区别特性redo logbinlog引擎InnoDB 独有MySQL 服务层所有引擎通用日志类型物理日志数据页修改逻辑日志SQL/行变化作用崩溃恢复主从复制、数据恢复写入方式循环写固定大小追加写无限增长写入时机事务执行中持续写事务提交时一次性写关键写入内存时机redo log执行时写 bufferbin log执行时写 cache→两者都是边执行边写内存写入磁盘时机最大区别redo log随时刷后台 / 满了 / 提交bin log必须提交才刷事务未提交时redo log可能已经刷盘bin log绝对不会刷盘崩溃时redo log可恢复未提交事务崩溃恢复bin log未提交事务不会存在因为没刷盘Bin Log日志bin log是 MySQL 记录所有数据库结构变更、数据修改的二进制日志不记录查询类操作一、作用数据恢复通过 bin log 回滚误操作、恢复到指定时间点主从复制主库将 bin log 发给从库从库重放实现数据同步审计追溯数据库的所有修改操作二、记录内容只记录写操作INSERT、UPDATE、DELETE、CREATE、ALTER、DROP、TRUNCATE 等不记录读操作SELECT、SHOW、DESC 等记录事务提交InnoDB 事务提交后才写入 bin log保证一致性三、三种记录格式1. STATEMENT语句级默认早期记录执行的 SQL 语句优点日志量小、性能好缺点不确定函数NOW()、UUID()、RAND()、存储过程会导致主从数据不一致2. ROW行级推荐记录每行数据的变更修改前/后的值优点主从绝对一致、恢复精准缺点日志量大、批量操作如 UPDATE 全表日志暴增3. MIXED混合普通 SQL 用 STATEMENT不确定函数用 ROW兼顾性能与一致性折中方案四、刷盘策略关键参数 sync_binlog1每次提交事务都会执行fsync0每次提交事务都只write由系统自行判断什么时候执行fsyncN每次提交事务都write但累积N个事务后才fsync五、主从复制主库事务提交 → 写入 bin logdump 线程读取 bin log发送给从库从库IO 线程接收 → 写入relay logSQL 线程读取 relay log → 重放 SQL从库数据与主库一致六、日志文件组成二进制日志文件mysql-bin.000001、mysql-bin.000002… 写满自动滚动索引文件mysql-bin.index记录所有 bin log 文件名列表三大日志全流程伪代码BEGIN; UPDATE ...; INSERT ...; COMMIT;一、BEGIN事务开始InnoDB 分配Undo Log 空间事务开始状态活跃、未提交此时无 prepare无 commit无 Bin Log只有 Undo Log 准备好二、执行 UPDATE ...顺序Undo → 改内存 → Redo写 Undo LogUPDATE 类型记录修改前的旧数据用于回滚 MVCC修改 Buffer Pool 数据页在内存中是数据本身的缓存区和日志无关写 Redo Log Buffer普通 redo不是 prepare记录物理修改还没落盘只是内存三、执行 INSERT ...同样顺序Undo → 内存 → Redo写 Undo LogINSERT 类型修改 Buffer Pool写 Redo Log Buffer此时事务仍未提交无 prepare无 commit无 Bin Log只有 Undo Log、Redo Log Buffer、内存数据四、执行 COMMIT最关键两阶段提交只有执行 COMMIT才会进入 prepare→ binlog → commit第1步Redo prepare准备提交Redo Log 标记为prepare事务进入提交中状态此时还不算提交成功第2步写 Bin Log落盘把整个事务的逻辑操作写入 Bin LogBin Log 必须落盘成功此时仍不算提交成功第3步Redo commit真正提交Redo Log 标记为commit这一刻事务才算真正提交成功不可回滚五、提交完成后INSERT Undo Log立即删除UPDATE Undo Log保留等待 purge 线程清理Redo Log后台刷盘Bin Log追加写入永久保留数据页后台刷盘六、崩溃时怎么判断数据库在COMMIT过程中崩溃重启后 InnoDB 会执行崩溃恢复先扫描 Redo Log找出所有 “未收尾” 的事务筛选出3类事务Redo Log 标记为 commit事务已完成两阶段提交Redo Log 标记为 prepare事务卡在提交过程中只完成 prepare没到 commit无 prepare/commit 标记事务只执行了 DML 没触发 commit属于 “未提交事务”对于上面3类事务对应下面的三种情况Redo Log 标记为 commit判断事务已完全提交Bin Log已写成功否则到不了commit 阶段处理执行Redo Log 重做把修改同步到磁盘Redo Log 标记为 prepare校验 Bin Log检查 Bin Log 中是否有该事务的完整记录通过事务 ID 匹配✅Bin Log 有该事务说明 “写 Bin Log” 步骤已完成只是没来得及写 Redo commit处理InnoDB 会补全 Redo commit 标记然后重做 Redo Log最终提交事务❌Bin Log 无该事务说明 “写 Bin Log” 步骤没完成就崩溃了处理用 Undo Log 回滚该事务恢复到修改前的状态无 prepare/commit 标记只执行了 DML 没触发 commit判断事务从未进入提交流程属于未提交事务处理用 Undo Log 直接回滚恢复数据到事务执行前的状态补充“Redo prepare → 写 Bin Log → Redo commit” 的顺序是硬约束只有 Bin Log 落盘成功才会执行 Redo commit所以 “Redo commit” 一定意味着 Bin Log 已写成功无需再校验Bin Log 是 “最终证据”MySQL 保证Bin Log 写成功 事务可以安全提交Bin Log 没写成功 事务必须回滚否则主从复制会丢数据Undo Log 只用于回滚只有 “Bin Log 无记录” 或 “未进入提交流程” 的事务才会触发 Undo Log 回滚七、总结BEGIN → 写 Undo → 改内存 → 写 Redo普通 COMMIT → Redo prepare → 写 Bin Log → Redo commit真正提交 崩溃prepare 看 Bin Log有就提交无就回滚上述内容也同步在我的飞书欢迎访问https://my.feishu.cn/wiki/QLauws6lWif1pnkhB8IcAvkhncc?fromfrom_copylink如果我的内容对你有帮助请点赞评论收藏。创作不易你们的支持就是我坚持下去的动力
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2451874.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!