好久没有写技术文章了,因为一直在思考 「后端分布式」这个系列到底怎么写才合适。最近基本想清楚了,「后端分布式」包括「分布式存储」和 「分布式计算」两大类。结合实际工作中碰到的问题,以寻找答案的方式来剖解技术,很多时候我们都不是在创造新技术,而是在应用技术。为了更有效率与效果的用好技术,我们需要了解一些技术的原理与工作方式。带着问题从使用者的角度去剖析技术原理,并将开源技术产品和框架作为一类技术的参考实现来讲解。以讲清原理为主要目的,对于具体实现的技术细节若无特别之处则尽可能点到即止。

事务与复制

近期参与了一个数据分布化相关的项目,涉及到数据库 MySQL 的数据分布化。简单来说就是需要在异地数据中心实现多点可写并保证分布后的数据能达成最终一致性。以前对 MySQL 作数据分布仅仅是读写分离,通过数据库自身的主从复制即可实现写主库、读从库。现在则需要双写主库并在经历一个短暂的延时后达成最终一致性,这个问题乍一想比较复杂,但归根结底还是数据最终一致性的问题。

先回到最简单的情况,只有一个 MySQL 数据库时,数据一致性是怎么保证的?了解数据库的都知道,这是通过数据库的事务特性来保证的,事务包括四大特性:

  • Atomicity 原子性
  • Consistency 一致性
  • Isolation 隔离性
  • Durability 持久性

事务的 ACID 四大特性不是本文重点,就不展开做学术性解说了,不了解的可以在后面参考文献里[3]去看相关文章。这里只想提一个问题,单一数据库事务能保证数据的一致性,那么 MySQL 在部署成主从架构时,如何保证主从之间数据的一致性的?

MySQL 为了提供主从复制功能引入了一个新的日志文件叫 binlog,它包含了引发数据变更的事件日志集合。从库请求主库发送 binlog 并通过日志事件还原数据写入从库,所以从库的数据来源为 binlog。这样 MySQL 主库只需做到 binlog 与本地数据一致就可以保证主从库数据一致(暂且忽略网络传输引发的主从不一致)。我们知道保证本地数据一致性是靠数据库事务特性来达成的,而数据库事务是如何实现的呢?先看下面这张图:

MySQL 本身不提供事务支持,而是开放了存储引擎接口,由具体的存储引擎来实现,具体来说支持 MySQL 事务的存储引擎就是 InnoDB。存储引擎实现事务的通用方式是基于 redo log 和 undo log。简单来说,redo log 记录事务修改后的数据, undo log 记录事务前的原始数据。所以当一个事务执行时实际发生过程简化描述如下:

  1. 先记录 undo/redo log,确保日志刷到磁盘上持久存储。
  2. 更新数据记录,缓存操作并异步刷盘。
  3. 提交事务,在 redo log 中写入 commit 记录。

在 MySQL 执行事务过程中如果因故障中断,可以通过 redo log 来重做事务或通过 undo log 来回滚,确保了数据的一致性。这些都是由事务性存储引擎来完成的,但 binlog 不在事务存储引擎范围内,而是由 MySQL Server 来记录的。那么就必须保证 binlog 数据和 redo log 之间的一致性,所以开启了 binlog 后实际的事务执行就多了一步,如下:

  1. 先记录 undo/redo log,确保日志刷到磁盘上持久存储。
  2. 更新数据记录,缓存操作并异步刷盘。
  3. 将事务日志持久化到 binlog。
  4. 提交事务,在 redo log 中写入提交记录。

这样的话,只要 binlog 没写成功,整个事务是需要回滚的,而 binlog 写成功后即使 MySQL Crash 了都可以恢复事务并完成提交。要做到这点,就需要把 binlog 和事务关联起来,而只有保证了 binlog 和事务数据的一致性,才能保证主从数据的一致性。所以 binlog 的写入过程不得不嵌入到纯粹的事务存储引擎执行过程中,并以内部分布式事务(xa 事务)的方式完成两阶段提交。进一步的细节就不展开了,可以参看后面参考文献[5]。

总结

我们前面先提出了一个问题,然后从数据一致性的角度去思考,参考了 MySQL 的实现方式。理清并分析了 MySQL 单机环境是如何保证复制机制的数据一致性,也就是 binlog 和事务数据的一致。后面我们才能基于 binlog 这个机制去实现复制并保证主从复制的一致性。主从复制又引入了网络因素,进一步增加了保证主从数据一致性的复杂度,后面还会撰文进一步分析这个问题。

参考

[1] MySQL Internals Manual. Replication.

[2] MySQL Internals Manual. The Binary Log.

[3] in355hz. 数据库 ACID 的实现.

[4] jb51. MySQL 对 binlog 的处理说明.

[5] repls. 浅析 innodb_support_xa 与 innodb_flush_log_at_trx_commit.

[6] 68idc. MySQL 5.6 之 DBA 与开发者指南.


下面是我的微信公众号 「瞬息之间」,除了写技术的文章、还有产品、行业和人生的思考,希望能和更多走在这条路上同行者交流。

后端分布式系列:分布式存储-MySQL 数据库事务与复制的更多相关文章

  1. MySQL 数据库事务与复制

    好久没有写技术文章了,因为一直在思考 「后端分布式」这个系列到底怎么写才合适. 最近基本想清楚了,「后端分布式」包括「分布式存储」和 「分布式计算」两大类. 结合实际工作中碰到的问题,以寻找答案的方式 ...

  2. 后端分布式系列:分布式存储-HDFS 与 GFS 的设计差异

    「后端分布式系列」前面关于 HDFS 的一些文章介绍了它的整体架构和一些关键部件的设计实现要点. 我们知道 HDFS 最早是根据 GFS(Google File System)的论文概念模型来设计实现 ...

  3. MySQL数据库事务剖析

    MySQL数据库事务剖析 事务就是一组原子性的SQL查询,是一个独立的执行单元.事务内的语句,要么全部执行成功,要么全部执行失败. 1.事务的标准特征 一个运行良好的事务处理系统,必须具备原子性.一致 ...

  4. mysql数据库事务详细剖析

    在写之前交代一下背景吧! 做开发也好久了,没怎么整理过知识,现在剖析一下自己对数据库事务的认识,以前用sqlserver,现在转java后又用mysql.oracle.我这块就主要解释一下mysql数 ...

  5. Mysql数据库事务隔离级别

    事务(transaction)是数据库管理系统的执行单位,可以是一个数据库操作(如Select操作)或者是一组操作序列.事务ACID属性,即原子性(Atomicity).一致性(Consistency ...

  6. MySql数据库事务正常提交,回滚失败

    问题:在初次练习Mysql数据库事务时,事务正常提交,但是在遇到异常应当回滚时,回滚失败. 代码如下: //2.更新操作. public void update(Connection conn, St ...

  7. Mysql数据库事务的隔离级别和锁的实现原理分析

    Mysql数据库事务的隔离级别和锁的实现原理分析 找到大神了:http://blog.csdn.net/tangkund3218/article/details/51753243 InnoDB使用MV ...

  8. 数据库事务系列-MySQL跨行事务模型

    说来和MySQL倒是有缘,毕业的第一份工作就被分配到了RDS团队,主要负责把MySQL弄到云上做成数据库服务.虽说整天和MySQL打交道,但说实话那段时间并没有很深入的理解MySQL内核,做的事情基本 ...

  9. MySQL数据库事务各隔离级别加锁情况--read uncommitted篇(转)

    本文转自https://m.imooc.com/article/details?article_id=17291,感谢作者 1.目的 1.1 合适人群 1.数据库事务特征我只是背过,并没有很深刻的理解 ...

随机推荐

  1. bzoj2560串珠子 状压dp+容斥(?)

    2560: 串珠子 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 515  Solved: 348[Submit][Status][Discuss] ...

  2. Excel实现双击插入当前日期时间

    用vba做一个事件驱动程序. 第一步:点击开发工具-visual basic. 第二步:在当前工作表中编制程序如下: Private Sub Worksheet_BeforeDoubleClick(B ...

  3. 5分钟快速打造WebRTC视频聊天

    百度一下WebRTC,我想也是一堆.本以为用这位朋友( 搭建WebRtc环境 )的SkyRTC-demo 就可以一马平川的实现聊天,结果折腾了半天,文本信息都发不出去,更别说视频了.于是自己动手. 想 ...

  4. Django Class Views

    一.Base views View class django.views.generic.base.View 主要的基于类的基本视图.所有其他基于类的视图都从这个基类继承而来.它不是一个通用的视图,因 ...

  5. 使设备I/O的核心模块工作,有哪两种方式?

    设备处理进程方式.文件操作方式.

  6. 以太坊MetaMask钱包插件简介

    MetaMask是一个以太坊钱包插件,虽然只能在Chrome浏览器中使用,但作为以太坊钱包的metamask却很受以太坊开发者欢迎. MetaMask 评价(5★):安装设置:★★★★界面操作:★★★ ...

  7. Linux之grep命令

    概述 所有的类linux系统都会提供一个名为grep(global regular expression print,全局正则表达式输出)的搜索工具.grep命令在对一个或多个文件的内容进行基于模式的 ...

  8. Spring MVC - 静态页面

    环境搭建 以下示例显示如何使用Spring MVC Framework编写一个简单的基于Web的应用程序,它可以使用<mvc:resources>标记访问静态页面和动态页面.首先使用Int ...

  9. Linux学习之CentOS(十二)------磁盘管理之 磁盘的分区、格式化、挂载(转)

    磁盘分区.格式化.挂载磁盘分区    新增分区    查询分区    删除分区磁盘格式化    mkfs    mke2fs磁盘挂载与卸载    mount    umount 磁盘的分区.格式化.挂 ...

  10. 关于一些基础的Java问题的解答(二)

    6. Hashcode的作用 官方对于hashCode的解释如下: Whenever it is invoked on the same object more than once during an ...