后端分布式系列:分布式存储-MySQL 数据库事务与复制
好久没有写技术文章了,因为一直在思考 「后端分布式」这个系列到底怎么写才合适。最近基本想清楚了,「后端分布式」包括「分布式存储」和 「分布式计算」两大类。结合实际工作中碰到的问题,以寻找答案的方式来剖解技术,很多时候我们都不是在创造新技术,而是在应用技术。为了更有效率与效果的用好技术,我们需要了解一些技术的原理与工作方式。带着问题从使用者的角度去剖析技术原理,并将开源技术产品和框架作为一类技术的参考实现来讲解。以讲清原理为主要目的,对于具体实现的技术细节若无特别之处则尽可能点到即止。
事务与复制
近期参与了一个数据分布化相关的项目,涉及到数据库 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 记录事务前的原始数据。所以当一个事务执行时实际发生过程简化描述如下:
- 先记录 undo/redo log,确保日志刷到磁盘上持久存储。
- 更新数据记录,缓存操作并异步刷盘。
- 提交事务,在 redo log 中写入 commit 记录。
在 MySQL 执行事务过程中如果因故障中断,可以通过 redo log 来重做事务或通过 undo log 来回滚,确保了数据的一致性。这些都是由事务性存储引擎来完成的,但 binlog 不在事务存储引擎范围内,而是由 MySQL Server 来记录的。那么就必须保证 binlog 数据和 redo log 之间的一致性,所以开启了 binlog 后实际的事务执行就多了一步,如下:
- 先记录 undo/redo log,确保日志刷到磁盘上持久存储。
- 更新数据记录,缓存操作并异步刷盘。
- 将事务日志持久化到 binlog。
- 提交事务,在 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 数据库事务与复制的更多相关文章
- MySQL 数据库事务与复制
好久没有写技术文章了,因为一直在思考 「后端分布式」这个系列到底怎么写才合适. 最近基本想清楚了,「后端分布式」包括「分布式存储」和 「分布式计算」两大类. 结合实际工作中碰到的问题,以寻找答案的方式 ...
- 后端分布式系列:分布式存储-HDFS 与 GFS 的设计差异
「后端分布式系列」前面关于 HDFS 的一些文章介绍了它的整体架构和一些关键部件的设计实现要点. 我们知道 HDFS 最早是根据 GFS(Google File System)的论文概念模型来设计实现 ...
- MySQL数据库事务剖析
MySQL数据库事务剖析 事务就是一组原子性的SQL查询,是一个独立的执行单元.事务内的语句,要么全部执行成功,要么全部执行失败. 1.事务的标准特征 一个运行良好的事务处理系统,必须具备原子性.一致 ...
- mysql数据库事务详细剖析
在写之前交代一下背景吧! 做开发也好久了,没怎么整理过知识,现在剖析一下自己对数据库事务的认识,以前用sqlserver,现在转java后又用mysql.oracle.我这块就主要解释一下mysql数 ...
- Mysql数据库事务隔离级别
事务(transaction)是数据库管理系统的执行单位,可以是一个数据库操作(如Select操作)或者是一组操作序列.事务ACID属性,即原子性(Atomicity).一致性(Consistency ...
- MySql数据库事务正常提交,回滚失败
问题:在初次练习Mysql数据库事务时,事务正常提交,但是在遇到异常应当回滚时,回滚失败. 代码如下: //2.更新操作. public void update(Connection conn, St ...
- Mysql数据库事务的隔离级别和锁的实现原理分析
Mysql数据库事务的隔离级别和锁的实现原理分析 找到大神了:http://blog.csdn.net/tangkund3218/article/details/51753243 InnoDB使用MV ...
- 数据库事务系列-MySQL跨行事务模型
说来和MySQL倒是有缘,毕业的第一份工作就被分配到了RDS团队,主要负责把MySQL弄到云上做成数据库服务.虽说整天和MySQL打交道,但说实话那段时间并没有很深入的理解MySQL内核,做的事情基本 ...
- MySQL数据库事务各隔离级别加锁情况--read uncommitted篇(转)
本文转自https://m.imooc.com/article/details?article_id=17291,感谢作者 1.目的 1.1 合适人群 1.数据库事务特征我只是背过,并没有很深刻的理解 ...
随机推荐
- bzoj1043[HAOI2008]下落的圆盘 计算几何
1043: [HAOI2008]下落的圆盘 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1598 Solved: 676[Submit][Stat ...
- Linux input子系统 io控制字段【转】
转自:http://www.cnblogs.com/leaven/archive/2011/02/12/1952793.html http://blog.csdn.net/guoshaobei/arc ...
- (ubuntu)linux C编程之sleep()和usleep()的使用和区别
### 函数名: sleep 头文件: #include <windows.h> // 在VC中使用带上头文件 #include <unistd.h> // 在gcc编译器中, ...
- VMWare 学习目录
Linux介绍 Linux入门--个人感想 Google怎么用linux 初入Linux Windows XP硬盘安装Ubuntu 12.04双系统图文详解 实例讲解虚拟机3种网络模式(桥接.nat. ...
- Mysql--开篇&目录
Mysql 现在是互联网公司中使用得非常广泛的数据库产品了,开源.免费.小巧.易用等诸多特性奠定了其夯实的基础.自己从事 JavaWeb 也有一段时间了,工作中也是用的 Mysql,也会涉及到分析.慢 ...
- Java中的网络支持InetAddress&URL
针对网络通信的不同层次,Java提供的网络功能有四大类 InetAddress:用于标识网络上的硬件资源.(说白了就是IP地址的相关信息) URL:统一资源定位符,通过URL可以直接读取或写入网络上的 ...
- 01_Struts2概述及环境搭建
1.Struts2概述: Struts2是一个用来开发MVC应用程序的框架. Struts2提供了web应用程序开发过程中一些常见问题的解决方案; 对用户输入的数据进行合法性验证 统一的布局 可扩展性 ...
- Docker镜像的实现原理
Docker 镜像是怎么实现增量的修改和维护的? 每个镜像都由很多层次构成,Docker 使用 Union FS 将这些不同的层结合到一个镜像中去. 通常 Union FS 有两个用途, 一方面可以实 ...
- RDO Stack: Failed connect to server
Issue: When you create an instance, but cannot connect to the VNC Server because of the error messag ...
- SQL Server AlwaysON从入门到进阶(2)——存储
本文属于SQL Server AlwaysON从入门到进阶系列文章 前言: 本节讲解关于SQL Server 存储方面的内容,相对于其他小节而言这节比较短.本节会提供一些关于使用群集或者非群集系统过程 ...