几年了,作为一个码农终于把MySQL日记看懂了( 二 )


六、认识事务日记 (Redo log)6.1 Redo log 概念Redo log 是重做日记 , 属于InnoDB引擎的日记 。 是物理日记 , 日记记录的内容的是数据页的更改 , 这个页 “做了什么改动” 。 如:add xx记录 to Page1 , 向数据页Page1增加一个记录 。
几年了,作为一个码农终于把MySQL日记看懂了文章插图
6.2 Redo log 作用

  • 前滚操作:具备crash-safe能力 , 提供断电重启时解决事务丢失数据问题 。
  • 提高性能:先写Redo log记录更新 。 当等到有空闲线程、内存不足、Redo log满了时 “刷脏” 。 写Redo log是顺序写入 , 刷脏是随机写 , 节省的是随机写磁盘的 IO 消耗(转成顺序写) , 所以性能得到提升 。 此技术称为WAL技术:Write-Ahead Logging , 它的关键点就是先写日记磁盘 , 再写数据磁盘 。
6.3 Redo log 的两阶段提交更新内存后引擎层写Redo log将状态改成prepare为预提交第一阶段 , Server层写Binlog , 将状态改成commit为提交第二阶段 。 两阶段提交可以确保Binlog和Redo log数据一致性 。
6.4 Redo log 容灾恢复过程MySQL的处理过程如下
  • 判断redo log是否完整 , 如果判断是完整(commit)的 , 直接用Redo log恢复
  • 如果redo log只是预提交prepare但不是commit状态 , 这个时候就会去判断binlog是否完整 , 如果完整就提交Redo log , 用Redo log恢复 , 不完整就回滚事务 , 丢弃数据 。
只有在redo log状态为prepare时 , 才会去检查binlog是否存在 , 否则只校验redo log是否是 commit就可以啦 。怎么检查binlog:一个完整事物binlog结尾有固定的格式 。
6.5 Redo log 刷盘时机Undo log的刷盘时机和Redo log差不多 , 但是对于Undo log我没找到对应的刷盘参数设计 , 所以不再提 。 Redo log每次先写入Redo Log Buffer中 , 然后通过刷盘时机控制刷入OS Buffer时间和刷入日记磁盘的时间 。
几年了,作为一个码农终于把MySQL日记看懂了文章插图
图3:内存和磁盘日记结构图
在Undo Log中 , MySQL是通过参数innodb_flush_log_at_trx_commit来控制刷盘时机 , 取值是0、1和2三种值 。 0表示事务提交后 , 每秒写入OS Buffer并调用fsync()写入日记磁盘中;1表示每次事务提交会写入OS Buffer并调用fsync()将日记写入日记磁盘中 。 2表示事务每次提交写入到OS Buffer , 每秒调用fsync()写入日记磁盘 。 可见参数为1是最安全的 , 同时也是默认值 。
几年了,作为一个码农终于把MySQL日记看懂了文章插图
图4:Redo log刷盘时机参数对应操作图
6.6 Redo log 存储方式
几年了,作为一个码农终于把MySQL日记看懂了文章插图
图5:Redo log File环形存储结构图
上图是日记磁盘的Redo log环形设计图(从头写 , 写到结束又从头开始写~循环) 。 write pos和check point是两个指针 , write pos指针指向当前日记文件写入的位置 , check point指针指向当前要擦除的开始位置 。 图中绿色部分是可以写入Redo log地方 , 每次写入 , write pos指针会顺时针推进 , 当然基本不会与check point指针重合 , 因为MySQL有这种机制去实现 , 每次触发检查点checkpoint , check point会指针向前推进 , 这个过程就是需要进行刷日记和数据磁盘 , 记录相应的LSN , 引出难点LSN 。
6.7 Redo Log 检查点啥时候会触发检查点checkpoint , 网上找了点资料:啥时候数据库会触发检查点checkpoint
几年了,作为一个码农终于把MySQL日记看懂了文章插图
【几年了,作为一个码农终于把MySQL日记看懂了】图6:检查点触发时机
Checkpoint发生的时间、条件及脏页的选择等都非常复杂 。 而Checkpoint所做的事情无外乎是将缓冲池中的脏页刷回到磁盘 , 不同之处在于每次刷新多少页到磁盘 , 每次从哪里取脏页 , 以及什么时间触发Checkpoint 。 这些本文不会去研究 。
6.8 Redo Log LSNLSN这个概念 , 比较复杂 , 我介绍完你们不一定懂!LSN称为日志的逻辑序列号(log sequence number) , 在innodb存储引擎中 , lsn占用8个字节 。 LSN的值会随着日志的写入而逐渐增大 。 可以简单理解SLN就是记录从开始到现在已经产生了多少字节的Redo log值 。
存储方式两个指针又是通过LSN计算得到指向位置 , 因为LSN记录的是文件的大小字节 , 当超过文件大小时 , 需要用取模计算出这两个指针位置 , 取模使得写入就会从头开始写 , 这样使得两个指针在一个文件中 , 一直落在循环位置 , 你追我赶的过程 。 这就是Redo log 环形逻辑思想设计实现 。