干货十足!MySQL Binlog 技术原理和业务应用案例分析
本文转自 | 爱奇艺的技术产品团队 作者 | 帆叔
导语:MySQL Binlog用于记录用户对数据库操作的结构化查询语言(Structured Query Language,SQL)语句信息。是MySQL数据库的二进制日志,可以使用mysqlbin命令查看二进制日志的内容。爱奇艺在会员订单系统使用到了 MySQL Binlog,用来实现订单事件驱动。在使用Binlog 后在简化系统设计的同时帮助系统提升了可用性和数据一致性。
本文将从实际应用角度出发理解 MySQL中的相关技术原理,从技术原理和工作实践相结合,帮助大家以及在相关设计中存在的潜在问题,希望能给大家有所帮助和启发,共同进步。
作者介绍:帆叔目前主要负责爱奇艺会员交易系统的技术和架构工作,专注异步编程、服务治理、代码重构等领域,热爱技术,乐于分享。
基于 Binlog 的事件驱动
图1:直接发送消息的订单事件驱动
图2:基于 Binlog 的订单事件驱动
暗 藏 问 题
MySQL 数据更新相关原理
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>>>> 两阶段提交
-
如果 Redo Log 有 Commit 标识,说明 Redo Log 其实已经 Commit 成功。这时直接提交事务; -
如果 Redo Log 没有 Commit 标识,则使用 XID(事务 ID)查询 Binlog 相应日志,并检查日志的完整。如果 Binlog 是完整的,则提交事务,否则回滚;
>>>> MySQL 数据更新流程
-
执行器先找引擎取 ID=2 这一行。ID 是主键,引擎直接用树搜索找到这一行。如果 ID=2 这一行所在的数据页本来就在内存中,就直接返回给执行器;否则,需要先从磁盘读入内存,然后再返回。 -
执行器拿到引擎给的行数据,把这个值加上1,比如原来是 N,现在就是 N+1,得到新的一行数据,再调用引擎接口写入这行新数据。 -
引擎将这行新数据更新到内存中。然后将对内存数据页的更新内容记录在 Redo Log Buffer 中(这里不详细介绍 Redo Log Buffer。只需知道对 Redo Log 的操作并不会直接写在文件上,而是先记录在内存中,然后在特定时刻才会写入磁盘)。此时完成了数据更新操作。 -
接下来要进行事务提交的操作。事务提交时,Redo Log 被标记为 Prepare 状态。通常此时,Redo Log 会从 Buffer 写入磁盘(innodb_flush_log_at_trx_commit,值为1时,每次提交事务 Redo Log 都会写入磁盘)。然后 InnoDB 告知执行器执行完成,可以提交事务。 -
执行器生成本次操作的 Binlog,并把 Binlog 写入磁盘。 -
执行器调用引擎的提交事务接口,引擎把刚刚写入的 Redo Log 改成提交 Commit 状态,更新完成。
问题解析
问题的解决方法
你「在看」吗?