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

推荐学习

  • 周一福利到!献上“独家全新”MySQL进阶套餐 , 简直就是血赚
  • “吃”完这本Java性能调优实战 , MySQL+JVM+Tomcat等问题一键全消

几年了,作为一个码农终于把MySQL日记看懂了文章插图
一、写作背景大家都清楚 , 日志是 MySQL数据库的重要组成部分 , 记录着数据库运行期间各种状态信息 。 MySQL日志主要包括错误日志、查询日志、慢查询日志、二进制日志(binlog)和事务日志(redo log、undo log)几大类 。
其中 , 二进制日记和事务日记尤为重要 , 一直被人重视、深入研究;可是事实很残忍 , 重视或者说大多数人一般都是了解个表面 , 真正懂得人并不多 。 真想攻破这两块日记必须下血本 , 而且还不一定能攻破 。 但是不要紧 , 为了让你们省下血本还能顺利攻破这两块日记 , 我连续研究几周MySQL日记 , 最终肝出了这篇文章 。
二、文章指引文章指导:文章第三节内容切莫跳过 , 但如果觉得第四、第五、第六和第七节没意思或者已经有了概念 , 直接进入文章第八节一举攻破拿下 。
文章方向:理论、原理篇 。
三、必要概念字典介绍基础不牢地动山摇 , 还是常规套路 , 先把必要知识普及/温习一遍 , 当后续文章出现疑虑反过来看下这些概念字典 , 说不定能 “柳暗花明又一村” 呢?
写了又写 , 想了又想 , 纠结了好久 , 这部分知识确实有点多 , 最后还是决定将这些必要概念字典单独分出一个文章 , 后续打算用截图方式引入各个章节中 , 建议遇到不懂名词查阅一下字典 。
几年了,作为一个码农终于把MySQL日记看懂了文章插图
图1:进阶知识部分示意图
四、认识二进制日记(Binlog)4.1 Binlog概念Binlog 是逻辑日记 , 用于记录数据库执行的写入操作(查询不记录)信息 , Server层记录和引擎层无关 , 并且是以追加方式进行写入 , 可以通过参数 max_binlog_size 设置每个Binlog文件的大小 , 文件大小达到设定值时会生成新的文件来保存日记 。
几年了,作为一个码农终于把MySQL日记看懂了文章插图
几年了,作为一个码农终于把MySQL日记看懂了文章插图
4.2 Binlog 作用在实际应用中 , 主要用在两个场景:主从复制和数据恢复
  • 主从复制场景:在Master主端开启Binlog , 将Binlog发生到各个Slave从端 , Slave从端重放Binlog从而达到主从数据一致
  • 数据恢复场景:通过使用 mysqlbinlog 工具来恢复数据
4.3 Binlog 记录过程及刷盘时机Binlog何时记录将在第六点进行介绍 , 大致记录过程是先写Binlog Buffer , 然后通过刷盘时机 , 控制刷入OS Buffer , 控制fsync()进行写入Binlog File日记磁盘的过程 。
几年了,作为一个码农终于把MySQL日记看懂了文章插图
对于Binlog , MySQL是通过参数sync_binlog参数来控制刷盘时机 , 取值是0、1和N三种值 。 0表示由系统自行判断何时调用sync()写入磁盘;1表示每次事务commit都要调用fsync()写入磁盘;N表示每N个事务 , 才会调用fsync()写入磁盘 。
几年了,作为一个码农终于把MySQL日记看懂了文章插图
图2:内存和磁盘日记结构图
4.4 Binlog 记录格式MySQL5.7.7版本之前默认格式是STATEMENT , 版本之后默认是ROW , 可以通过参数 binlog-format指定 。
几年了,作为一个码农终于把MySQL日记看懂了文章插图
五、认识事务日记(Undo log)5.1 Undo log 概念Undo log是逻辑日记、回滚日记 。 比如一条修改+3的逻辑语句 , Undo log会记录对应一条-3的逻辑日记 , 一条插入语句则会记录一条删除语句 , 这样发生错误时 , 根据执行Undo log就可以回滚到事务之前的数据状态 。
5.2 Undo log 作用
  • 回滚数据:当程序发生异常错误时等 , 根据执行Undo log就可以回滚到事务之前的数据状态 , 保证原子性 , 要么成功要么失败 。
  • MVCC一致性视图:通过Undo log找到对应的数据版本号 , 是保证MVCC视图的一致性的必要条件 。
5.3 Undo log 记录过程及刷盘时机刷盘过程及时机类似于Binlog和Redo , 可以参考Redo log刷盘时机章节给出的图片 , 已经体现出来了 。
5.4 Undo log 总结Undo log日记内容不是很多 , 重点是回滚和多版本控制MVCC那块 。 此外 , 我记得印象笔记深刻的是长事务会导致日记过多 , 这个日记就是Undo log 。 因为长事务存在 , 导致需要保存很多视图快照 , 其实这里就是涉及到Undo log何时删除和生成的问题 , 当时纠结好久 , 其实很简单 。 生成是事务开始后写Redo log之前生成 , 当没有事务需要用到Undo log时就会被删除 。 举个例子 , 如果事务A一直存活 , 那么事务A之后产生的事务B、C...等等就算提交了 , 也不会被删除 , 因为事务A需要用到B、C...事务去找A的版本 。 所以避免长事务可以减少Undo log日记量 , 当然还可以提高性能 。