这篇我们分享MySQL 日志。会回答下面的几个问题:
- 事务持久性怎么实现的?
- 为什么需要redolog?
- binlog 、redolog区别在哪里?
- binlog、redolog、undolog
- 什么是两阶段提交?
- 两阶段提交过程?
- 为什么需要两阶段提交?
- 数据库备份?
事务持久性怎么实现的?
MySQL 数据持久性由InnoDB 保障使用的是WAL 方案。在buffer pool 中完操作的数据对应状态在写入磁盘表文件之前会先写入Redolog 中,之后再由后台线程再由后台刷盘线程统一定时批量写入到数据文件中。这个就叫WAL (write head log)技术。
为什么需要redolog?
- redolog 作用是故障恢复。保障的是数据的落盘安全,是MySQL WAL 方案的承载体。在数据库出现崩溃时可以在启动时通过读取redolog 进行故障恢复。对于主从架构来说,redolog 还记录了事务主从同步状态,在崩溃时通过查询同步标记状态可以进行主从数据同步的故障恢复。
- 对于Innodb 来说,事务写进 redolog 就算是执行完成了。剩下的,如果有主从同步就是两阶段任务了 prepare - commited.
分别介绍一下 undolog、redolo、binlog?
- undolog: 保证事务原子性。用于事务回滚和MVCC。undolog 详细记录的每条数据的历史版本。
- redolog: 保障事务持久性,用于故障恢复。redolog 记录方式是循环式的记录。undolog 不是。触发redolog 数据落盘到数据文件的时机见下:
- MySQL 正常退出关闭
- buffer pool redolog 大于默认配置一半时(默认16M)
- 后台周期线程每 1s 触发
- 每次事务提交时。可通过innodb_flush_log_at_rtx_commit 配置落盘策略{参数 0、1、2}
- binlog: 二进制通用格式日志,主要用于主从同步。触发从buffer 中写入到文件的时机是每次事务提交时。
redolog 循环写
偷两张小林哥的图
循环写示意图
redolog 采用类似于ring buffer (队尾进对头出)循环写(滚动方向顺时针)的方式,通过两个指针控制日志滚动:
- write_point: 当前唤醒队列的队尾
- check_point: 环形队列的对头
上面示意图同:
- 蓝色部分,待落盘数据
- 红色部分,可用空间
binlog、redolog 区别在哪里?
1.使用场景不同
- binlog 主要用于主从同步,是服务层通用日志,所有引擎通用
- redolog innodb 专用日志,用于故障恢复,保障事务持久性
2.文件格式不同
- binlog 有三种格式: statement, row, mixed
- redolog 是物理日志,记录某个数据页的变更历史
3.写入方式不同
- binlog 是追加写,写慢一个文件会 创建新文件继续写,不会做滚动日志。
- redolog 是滚动日志
MySQL 主从同步 三种模式
- 同步模式: 发送binlog,等待同步响应同步完成。
- 异步模式,只管发binlog,不管从库响应,直接返回
- 半同步,发binlog 给从库,只要有半数及以上从库返回同步成功消息就返回。
什么是两阶段提交?
两阶段提交主要说的是数据落盘 redolog和binlog 所记录事务转台变更的两阶段 prepare-commited
主从同步大致分为三个步骤:
- 写入binlog:主库写binlog,提交事务更新本地数据
- 发送binlog, 从库接收binlog 暂存
- 从库回访binlog,更新本地数据
两阶段提交过程?
偷个小林哥的图
事务执行commit后,MySQL 会生成一个内部XA事务,分两阶段完成落盘事务。
- prepare: 讲XAID 写入到redolog 中,同时将对应事务状态改为prepare 并将redolog写入到磁盘
- commit: 把XAID写入到binlog中,将binlog写入到磁盘,将prepare 阶段标记的对应的事务状态改为commit. --- 用户commit 的事务算是提交成功,即使只是写入page chache 也算。
为什么需要两阶段提交?
- 两阶段存在的目的为了保证数据能正确落盘,将提交的事务数据写入redolog 和binlog 的流程绑定,保证redolog 和 binlog的数据一致性。
两阶段提交出现故障崩毁会怎么样?
两阶段过程中崩溃可以大致分为两种情况(主要是prepare 阶段的故障异常处理, 因为commit状态了,就是已经算是写入数据文件了,commit 是完成的记录):
- prepare 阶段种崩溃(事务状态标记仍是prepare),在redolog 有XAID,binlog没有XAID: 说明数据还没来得及刷盘,回滚
- prepare 阶段种崩溃(事务状态标记仍是prepare),在redolog 有XAID,binlog有XAID: 说明binlog已经记录完成,继续提交事务,改为commit 状态
数据库备份
这里主要分享数库本分的一些方法:
- 全量备份
- 逻辑备份: 根据表生成insert 语句,恢复直接运行导出的insert脚本. (mysqldump)
- 物理备份: 8.0 提供了 clone plugin. (clone loacal data directory = 'clone_path')
- 增量备份
- binlog 日志订阅 (mysqlbinlog)
为了保证备份有效,还需要校验备份数据是否正确,备份系统还需要有一个备份文件校验功能。