MySQL Binlog 技术原理和业务应用案例分析( 三 )

  • 接下来要进行事务提交的操作 。事务提交时 , Redo Log 被标记为 Prepare 状态 。通常此时 , Redo Log 会从 Buffer 写入磁盘(innodb_flush_log_at_trx_commit , 值为 1 时 , 每次提交事务 Redo Log 都会写入磁盘) 。然后 InnoDB 告知执行器执行完成 , 可以提交事务 。
  • 执行器生成本次操作的 Binlog , 并把 Binlog 写入磁盘 。
  • 执行器调用引擎的提交事务接口 , 引擎把刚刚写入的 Redo Log 改成提交 Commit 状态 , 更新完成 。

  • MySQL Binlog 技术原理和业务应用案例分析

    文章插图
     
    图中描述了 update 语句执行过程中 MySQL 执行器、InnoDB , 以及 Binlog、Redo Log 交互过程(图中深绿底色的是 MySQL 执行器负责的阶段 , 浅绿底色是 InnoDB 负责的阶段)
    问题解析从上面对 MySQL 原理的介绍我们得知 , 写 Binlog 发生在事务提交阶段 , 但是 MySQL 因为在 Server 层和存储引擎层都引入了不同的日志结构 , 从而引入了两阶段提交 。Binlog 的写入发生在存储引擎真正提交事务之前 , 这导致理论上通过 Binlog 同步数据的系统(MySQL 从库、其它数据库或业务系统)有可能早于 MySQL 主库使最新提交的数据生效 。
    所以上面提到的订单履约服务在收到基于 Binlog 的订单支付事件后却查到相应订单是未支付的 , 原因很可能是订单履约服务在查询数据时 , 订单支付数据更新操作在 MySQL 内部尚未彻底完成事务的提交 。
    我们通过开发验证程序重现了这一现象 。验证程序接收到事务提交完成后的完整 Binlog 时会再次在 MySQL 主库上查询对应的记录 , 结果会有一定概览获得事务提交前的数据 。
    另外经过了解 , 也有同行反映遇到过从库早于主库看到数据提交的问题 。
    问题的解决方法在了解问题背后的原因之后 , 我们需要思考如何解决此问题 。目前解决此问题有两个方法:重试和直接使用 Binlog 数据 。
    重试这种做法简单粗暴 , 既然问题原因是 Binlog 早于事务提交 , 那等一下再重试查询自然就解决了 。但在实践中 , 需要考虑重试的实现方法、以及是否会因为重试过多甚至无限重试导致服务异常 。对于重试的实现 , 可使用的方法有线程 Sleep 大法和消息重投等方式 。线程 Sleep 大法通常是不被推荐的 , 因为它会导致线程利用率降低 , 甚至导致服务无法响应 。但考虑到本次问题出现概率较低 , 我们认为线程 Sleep 大法是可以使用的 , 并且此方式简单易行 , 可用于问题的快速修复 。
    第二种重试方式是消息重投 , 比如 RocketMQ 中 Consumer 返回
    ConsumeConcurrentlyStatus.RECONSUME_LATER 即可触发消息重投 。但这种重试方法成本较前一种方法高 , 另外重试间隔也相对较大 , 对时间敏感的业务影响也较大 , 因此是否采用此方法需从业务和技术两个角度综合考虑 。
    除了考虑用何种方式重试 , 还要考虑 ABA 问题 , 即状态变化按照 A->B->A 的方式进行 。业务系统期待的状态是 B , 但实际可能没办法再变成 B 了 。因此在用重试解决此问题之前 , 需要先排除业务系统存在 ABA 问题的可能 。对于状态 ABA 问题 , 可用状态机等方式解决 , 这里不再展开讨论 。
    除了重试 , 另一种方法就是直接使用 Binlog 。因为 Binlog (row 格式) 直接反映了数据的变化情况 , 其中可以记录事务提交涉及到的完整数据 , 因此可直接用作业务处理 。这样还可以降低数据库 QPS 。如果是新设计的系统 , 我认为这样做法比较理想 。但对于已有系统 , 这种方式改动可能较大 , 是否采用需权衡成本和收益 。
    本文转载自公众号爱奇艺技术产品团队(ID:iQIYI-TP) 。
    原文链接:
    https://mp.weixin.qq.com/s?__biz=MzI0MjczMjM2NA==&mid=2247486912&idx=2&sn=8aa949ed12d68424b2df3a1016373db7&chksm=e97691e3de0118f5cbf6deeffb88a0b8fcc5c1936c31d4660f16257cec2bc31c77f435ecaa8e&scene=27#wechat_redirect




    推荐阅读