MySQL 复制问题的最后一篇,关于双向同步复制架构设计的一些设计要点与制约。
问题和制约
数据库的双主双写并双向同步场景,主要考虑数据完整性、一致性和避免冲突。对于同一个库,同一张表,同一个记录中的同一字段的两地变更,会引发数据一致性判断冲突,尽可能通过业务场景设计规避。双主双写并同步复制可能引发主键冲突,需避免使用数据库自增类主键方案。另外,双向同步潜在可能引发循环同步的问题,需要做回环控制。
如上图所示,复制程序写入时也会产生 binlog,如何识别由复制程序产生的 binlog 并将其过滤掉是避免循环复制的关键。
原生 Dual Master 方案
MySQL 自身支持双主配置,但并没有去解决潜在的主键和双写带来的数据一致性冲突。对于双向同步潜在的循环复制问题,MySQL 在 binlog 中记录了当前 MySQL 的 server-id。一旦有了 server-id 的值之后,MySQL 就很容易判断某个变更是从哪一个 Server 最初产生的,所以就很容易避免出现循环复制的情况。而且,还可以配置不打开记录 slave 的 binlog 选项(–log-slave-update),MySQL 就不会记录复制过程中的变更到 binlog 中,就更不用担心可能会出现循环复制的情形了。
从 MySQL 自身的方案中可以找到切入点,就是如果能在 binlog 中打上标记,就有办法判断哪些 binlog 是复制产生的,并将其过滤。使用 MySQL 的方案则过于耦合 MySQL 的配置,在大规模部署的线上生产系统中容易因为 MySQL 配置错误导致问题。
自定义标记 SQL 方案
为了和 MySQL 配置解耦合,可以考虑一种通用的标记 SQL 方案。简单来说,就是在同步复制入库时插入特殊的标记 SQL 语句来标记这是来自复制程序的变更,这个标记 SQL 会进入 binlog 中。而在复制程序读取时,通过识别这个标记 SQL 来过滤判断。
binlog 中存储了对数据产生变更影响的的 SQL 语句,这些 SQL 语句组成了一段一段的事务,如下图所示:
绿色区是业务运行产生的正常事务,红色区是复制程序写入产生的事务,其中蓝色块是标记 SQL。标记 SQL 分别在事务开始后与事务结束前,标记 SQL 更新一张预定义的区别于业务表的标记表。那么每次复制程序去批量读取 binlog 内容时,可能存在下面 5 种情况,如下图所示:
- 批量读取范围全落在绿色区内。
- 批量读取范围起点落在绿色区,终点落在红色区。
- 批量读取范围起点落在红色区,终点落在绿色区。
- 批量读取范围起点和终点都在绿色区,但中间涵盖了一段红色区。
- 批量读取范围全落在红色区。
如上只有第 5 种情况,一个事务被拆成 3 段来同步。中间一段因为没有事务头和尾的标记,复制程序读取时将无法判断,导致循环同步,需要避免。通过把复制程序的批量读取范围固定设置为至少大于或等于写入的事务长度范围,避免了第 5 种情况。复制程序批量读取 binlog 日志事件时,通过标记 SQL 来过滤,避免了循环复制,实现了回环控制。
总结
本文考虑了在 MySQL 双主写入场景下双向同步复制的一些设计要点和制约。以原生实现为参考,给出了一种自定义实现方式的设计要点分析。而对于同库同表同记录同字段的同时两地变更,则必然引发数据一致性冲突,在复制同步层面无法区分哪边的更新为准。通常会考虑以最后时间戳来恢复到一致状态,但时间戳实际也会产生误差,此类场景不多见最好还是尽可能还是在业务场景设计上来规避。
参考
[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 与开发者指南.
[7] csdn. 高性能 MySQL 主从架构的复制原理及配置详解.
[8] agapple. Otter 双向回环控制.
下面是我的微信公众号 「瞬息之间」,除了写技术的文章、还有产品、行业和人生的思考,希望能和更多走在这条路上同行者交流。
<script type="text/javascript">
$(function () {
$('pre.prettyprint code').each(function () {
var lines = $(this).text().split('\n').length;
var $numbering = $('<ul/>').addClass('pre-numbering').hide();
$(this).addClass('has-numbering').parent().append($numbering);
for (i = 1; i <= lines; i++) {
$numbering.append($('<li/>').text(i));
};
$numbering.fadeIn(1700);
});
});
</script>
分享到:
相关推荐
Mysql5.5数据库双向同步
这是关于linux下Mysql数据库单双向同步详细配置文档,已经经过试验验证。
双主双写并同步复制可能引发主键冲突,需避免使用数据库自增类主键方案。另外,双向同步潜在可能引发循环同步的问题,需要做回环控制。 如上图所示,复制程序写入时也会产生 binlog,如何识别由复制程序产生...
mysql,两个数据库,实现实时数据同步,对于需要实现mysql同步的用户非常有用
拥有它,烦人的数据库同步将迎刃而解 mysql双向主主同步关键性文档
Mysql两个数据库表之间双向数据同步方案.docx
1.1 环境搭建 准备两台Windows NT ...分别在A、B节点上登陆mysql 数据库,创建同步帐户并赋予同步权限,如下: A节点操作: 运行cmd, cd进入iKEY版本安装目录下的iKEY\mysql\bin下,然后执行mysql –uroot –p12345
linux下实现mysql同步,达到表级同步
帮助需要配置mysql同步却又不熟悉方法的人,即使小白也能通过文档快速操作,实现mysql数据库的双向同步,并配置keepalvied实现虚ip自动切换。
MySQL数据库实现双活是指在多个数据中心中安装有相同的MySQL服务,实现两个数据中心之间的数据库同步,达到数据双向同步的效果,保证数据的高可用性和容灾性。避免主从同步的延迟在双主复制的基础上,需要进行一些...
通过mysql自带的数据同步机制,可以方便的实现mysql数据库的数据同步。如果需要实现双向同步,则从A-B配置单向同步后,再从B-A配置一遍即可。
windows下mysql双向同步备份实现方法以下的文章主要讲述的是在windows环境下实现MySQL数据库的主从同步备份的正确操作方案,我在一些相关的网站看见关于windows环境下实现MySQL数据库的主从同步备份的操作步骤描述,...
● 支持双向同步 ● 支持二进制字段 ● 秒级实时同步 ● 高可靠无遗漏 能长期无人值守同步,即使发生断网、断电等故障,也只影响当时;一旦故障解除,同步就会自动恢复,且不会遗漏数据。 ● 异常提醒通知
SQLite DBSync是开源嵌入式数据库SQLite的数据同步引擎,实现了SQLite与SQLite数据库之间以及SQLite与异构数据库Oracle、MySQL、SQLServer之间的增量的、双向的数据同步功能。在文章中对SQLite DBSync 的体系结构、...
mysql linix 主备同步 写数据库 读数据库
1.1、创建一个复制用户,具有replication slave 权限。 mysql>grant replication slave on *.* to ‘repl’@’192.168.1.22’ identified by ‘repl’; 1.2、编辑my.cnf文件 vi /etc/my.cnf 添加 server-id=1 并...
实现了mysql数据库的单向数据同步,和双向数据同步
支持指定双向同步 支持主流的关系型数据库:mysql,db2,postgresql,oracle,sqlserver 本程序由java编写,基于1.8版本,方便打包移植。本程序的最大用处就是生成集市或数仓所需要的基础层数据源。 简单的预期一定...
一、mysql主从复制介绍 mysql的主从复制并不是数据库磁盘上的文件直接拷贝,而是通过逻辑的binlog日志复制到要同步的服务器本地,然后由本地的线程读取日志里面的sql语句,重新应用到mysql...双主双向同步 (A -> B
通过BDB可以快速建立数据库模型、并随时与实体数据库进行双向同步。 同时它还可以为您的应用程序创建数据库自动安装(或自动升级)程序、 以及实现不同数据库平台间数据库迁移等。 <br>此外、在BDB中提供...