知识卡片

binlog格式选row而非Mixed:拒绝"半吊子"方案,避免中间状态最坑人

普通读书笔记卡

内容

MySQL binlog的记录格式有statement(记录SQL语句本身)、row(记录每一行数据变更前后的具体值)、mixed(混合模式:默认按statement记录,只有遇到某些容易导致主从不一致的SQL,比如包含UUID函数这类不确定性函数的语句时,才自动切换成row格式)三种可选。很多网上流传的文章会推荐使用Mixed模式,理由是它兼顾了statement模式的日志体积小和row模式的一致性保证,看起来是一个”两全其美”的折中方案。但这个案例给出了明确的反对意见,优先建议直接使用row格式,理由直指数据复制的可靠性本身:Mixed模式的问题在于它引入了一种”中间状态”——大部分时候用轻量的statement格式,只有系统判断这条SQL”容易导致不一致”时才切换成row格式,但这意味着到底哪些SQL会被自动转换、什么时候会转换,对使用者而言不是完全透明和可预期的,一旦系统对某条SQL的判断出现遗漏或边界情况,就会产生真正的主从数据不一致,而这类问题往往在长期运行后才被察觉,排查起来也格外棘手。原文用一句形象的话总结了这个判断:”既然要革命,就搞得彻底一些”——与其停留在”大部分时候更省资源、少数时候自动切换更安全”这种听起来面面俱到、实际上留有不确定性缝隙的中间方案,不如直接选择从一开始就完全放弃statement格式、始终用row格式记录每一行的真实变更,用日志体积增大这个确定的、可预期的代价,换取数据一致性这个不能有任何侥幸空间的核心保证。这个案例提示了一条评估”折中方案”的重要原则:不是所有”两者兼顾”的方案都真的划算,当折中方案引入的不确定性(哪些情况会走哪条路径、边界条件有没有被完全覆盖)本身可能造成比”多付出一点确定的代价”更严重的后果时,一个彻底、单一、行为完全可预期的方案,反而比看似更聪明的混合方案更值得信赖。

参考来源

- 位置:《高可用架构(第1卷)》第5章《运维保障》"5.3 单表60亿记录等大数据场景的MySQL优化和运维之道"节,"5.3.5 疑问与解惑"(源文件:_epub-src/OEBPS/Text/Chapter5_3_6.xhtml) - 结论依据:原文说明"对于binlog格式,为什么只推荐row,而不用网上大部分文章中推荐的Mix……这个主要是考虑到数据复制的可靠性,row更好。Mixed含义是指如果有一些容易导致主从不一致的SQL,比如包含UUID函数的这种,转换为row。既然要革命,就搞得彻底一些。这种Mix的中间状态最坑人了",直接支撑本卡片结论。 - 原始内容:这个主要是考虑到数据复制的可靠性,row更好。Mixed含义是指如果有一些容易导致主从不一致的SQL,比如包含UUID函数的这种,转换为row。既然要革命,就搞得彻底一些。这种Mix的中间状态最坑人了。