InnoSQL/MySQL并行复制的实现与配置

http://www.innomysql.net/article/6276.html

并行复制之前的解决方案

InnoSQL在5.5.30-v4版本中支持了从机并行复制的功能。总所周知,MySQL数据库slave服务器延迟的现象是非常普遍的,这导致了虽然对比Oracle、Microsoft SQL Server,MySQL复制允许从机进行SELECT操作,但是在实际线上环境下,由于从机延迟的关系,很难将读取操作转向到从机。这就导致了有了以下一些潜规则:“实时性要求不高的读取操作可以放到slave服务器,实时性要求高的读取操作放到master服务器”,“从机仅能做前一天的统计类查询”。

网易的易信项目、RDS也深受这个问题的困扰,所以我们打算彻底的解决这个问题。在v3版本之前我们的解决方案是使用batch commit,即将slave服务器回放的一个个事务,进行批量的回放。虽然还是单线程,但是由于大大减少commit的次数,也能有非常明显的效果,重要的是他对二进制日志的格式没有要求。缺点当然也有,比如还是单线程回放,不能充分利用磁盘的性能。另外,存储引擎必须要求是InnoDB或TokuDB事务引擎。batch commit方案已经在易信和RDS项目上使用,取得了比较明显的效果,但是InnoSQL的目标永远是追求卓越。

并行复制的实现

所以InnoSQL团队打算实现并行复制,虽然有各种想法,但是一直没有好的实现思路。淘宝有公布他们的并行复制实现方案,但是因为是基于row格式二进制日志的,我们线上业务并没有具体限制二进制日志格式。另外,淘宝放出的patch完成度比较低,很多复制错误也未能处理,感觉也是处于原型阶段(大概1年多前,现在可能已经成熟)。另外,对于并行的判断感觉比较复杂,而且全局的hash表感觉会是一个性能瓶颈。好在MariaDB的大牛Kristian最终解决了并行复制的问题,他的实现堪称完美。即一个组提交中的事务都是可以并行执行的。因为既然处于组提交中,这意味着事务之间没有冲突,否则不可能进行这个阶段。MariaDB的实现基于gtid实现,不过我们5.5的版本并没有实现gtid,所以需要做一些变通的实现。我们增加了一个event类型,称之为Gcid_event,表示组提交的编号。如:

1
2
3
4
5
6
7
8
9
10
11
mysql> show binlog events in 'mysqld-bin.000004' limit 50;
+---------------------------------+------+-------------------+-----------+-------------+---------------------------------------------+
| Log_name                        | Pos  | Event_type        | Server_id | End_log_pos | Info                                        |
+---------------------------------+------+-------------------+-----------+-------------+---------------------------------------------+
| mysqld-bin.000004 |    4 | Format_desc       |        11 |         150 | Server ver: 5.5.30vsr-ha-log, Binlog ver: 4 |
| mysqld-bin.000004 |  150 | Binlog_checkpoint |        11 |         204 | DavidmatoMacBook-Pro-bin.000004             |
| mysqld-bin.000004 |  204 | Gcid_event        |        11 |         231 | GCID id=231077                              |
| mysqld-bin.000004 |  231 | Query             |        11 |         301 | BEGIN                                       |
| mysqld-bin.000004 |  301 | Table_map         |        11 |         356 | table_id: 35 (sbtest.sbtest1)               |
| mysqld-bin.000004 |  356 | Update_rows       |        11 |         766 | table_id: 35 flags: STMT_END_F              |
......

组提交中的事务是可以并行执行的,所以可以看到一个组提交中的事务拥有相同的Gtid_event,即231077:

1
2
3
4
5
6
| mysqld-bin.000004 |  204 | Gcid_event        |        11 |         231 | GCID id=231077                              |
......
| mysqld-bin.000004 |  1258 | Gcid_event        |        11 |         1285 | GCID id=231077                              |
......
| mysqld-bin.000004 |  2312 | Gcid_event        |        11 |         2339 | GCID id=231077                              |
......

通过查看二进制日志可以知道组提交中事务的个数,这样的查询方式比较繁琐。InnoSQL提供了状态来观察组提交的情况,这里一个组提交平均包含8个事务:

1
2
3
4
5
6
7
8
mysql> show global status like '%commit%';
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
......
| Commit_group_num | 92     |
| Commit_num       | 730    |
....

在InnoSQL版本中还可以通过参数binlog_commit_wait_count和binlog_commit_wait_usec来增大组提交的比例,副作用是事务的响应时间会变慢,性能会有损耗,所以这两个参数的调整需要一定的技巧。参数binlog_commit_wait_count表示一个组提交中至少有多个事务才进行提交,参数binlog_commit_wait_usec表示等待多少毫秒再进行组提交。这样的优化对于共享存储设备能有极大的帮助,根据InnoSQL的测试,根据适当的参数调整,MySQL的响应时间仅下降了3%,但是共享存储的I/O使用率缺下降了50%之多。

InnoSQL对于并行复制的实现另一个重要的特点就是支持crash safe,也就是服务器,亦或者是复制服务出现任何错误时,都要保证主从数据是完全正确的。因此,我们将原来复制的relay-info信息文件保存为了一张表,这和官方MySQL 5.6的处理方式一样,和Percona的处理方式不一样,Percona是将slave的二进制位置写入InnoDB的事务段头,恢复时通过这部分的内容来替换relay-info文件。这样处理看似比较简单易懂,但是这个方案的最大问题是其仅支持InnoDB存储引擎。网易内部还有使用TokuDB引擎和自己开发的TNT引擎,要兼容这些引擎需要将relay-info存表,存储引擎选择相应的类型即可。这种方式完美的适配于我们自己开发的TNT引擎。replication crash safe

实现并行复制最为关键的是order commit的实现,即事务在slave上是并行执行执行的,但是提交顺序是和master服务器一致的。这样能保证主从产生的二进制日志顺序是一致的。另外,并行复制实现最为复杂的是对于出错的处理,InnoSQL在方面提交了很多patch给MaraiDB并被接受。

并行复制配置

要实现一个完美的crash-safe并行复制环境,需要根据如下参数进行配置,首先master服务器根据如下进行配置:

1
2
3
4
5
6
7
8
[mysqld]
server-id=xxx
log-bin=xxx
sync_binlog=1 #保证master crash safe,该参数必须设置为1
innodb_support_xa=1 #保证master crash safe,该参数必须设置为1
binlog_commit_wait_count=xxx #根据自身业务进行调整
binlog_commit_wait_usec=xxx #根据自身业务进行调整
enable_table_relay_info=1 #如果需要进行双主的配置

slave服务器进行如下的配置:

1
2
3
4
5
6
[mysqld]
server-id = xxx
log-bin = xxx
enable_table_relay_info = 1
slave_parallel_threads = 32 #并行复制的线程数
relay_log_recovery = 1 #从机crash safe要求重新同步master日志

当然,以上的配置仅能保证并行复制是crash safe的,但不能保证在进行failover后数据不丢失。如果应用需要保证数据不丢失,那么需要再开启InnoSQL的VSR(Virtual Sync Replication)功能,这样能保证怎样的切换主从数据都是一致的。该功能已经在网易内部上百台服务器中使用了近2年的时间。下一篇文件即将介绍InnoSQL的VSR已经高可用同步套件功能。

并行复制性能测试

InnoSQL的并行复制性能测试报告已经发布,小伙伴们可以从http://pan.baidu.com/s/1bn6b3mJ进行下载。当然,我们更环境小伙们自己进行测试,你会发现为什么InnoSQL是最有诚意的MySQL分支版本。InnoSQL 5.5.30-v4下载地址:http://pan.baidu.com/s/1bnpgzpH

如果需要进行任何InnoSQL咨询服务,可以访问:http://www.innosql.net/?p=48

InnoSQL/MySQL并行复制的实现与配置的更多相关文章

  1. mysql并行复制降低主从同步延时的思路与启示

    一.缘起 mysql主从复制,读写分离是互联网用的非常多的mysql架构,主从复制最令人诟病的地方就是,在数据量较大并发量较大的场景下,主从延时会比较严重. 为什么mysql主从延时这么大? 回答:从 ...

  2. [转载自阿里丁奇]各版本MySQL并行复制的实现及优缺点

    MySQL并行复制已经是老生常谈,笔者从2010年开始就着手处理线上这个问题,刚开始两三年也乐此不疲分享,现在再提这个话题本来是难免"炒冷饭"嫌疑.    最近触发再谈这个话题,是 ...

  3. MySQL 并行复制演进及 MySQL 8.0 中基于 WriteSet 的优化

    MySQL 8.0 可以说是MySQL发展历史上里程碑式的一个版本,包括了多个重大更新,目前 Generally Available 版本已经已经发布,正式版本即将发布,在此将介绍8.0版本中引入的一 ...

  4. 各版本 MySQL 并行复制的实现及优缺点

    MySQL并行复制已经是老生常谈,笔者从2010年开始就着手处理线上这个问题,刚开始两三年也乐此不疲分享,现在再提这个话题本来是难免“炒冷饭”嫌疑. 最近触发再谈这个话题,是因为有些同学觉得“5.7的 ...

  5. 【58沈剑架构系列】mysql并行复制优化思路

    一.缘起 mysql主从复制,读写分离是互联网用的非常多的mysql架构,主从复制最令人诟病的地方就是,在数据量较大并发量较大的场景下,主从延时会比较严重. 为什么mysql主从延时这么大? 回答:从 ...

  6. MySQL并行复制的一个坑

    早上巡检数据库,发现一个延迟从库的sql_thread中断了. Last_SQL_Errno: 1755 Last_SQL_Error: Cannot execute the current even ...

  7. MySQL并行复制(MTS)原理(完整版)

    目录 MySQL 5.6并行复制架构 MySQL 5.7并行复制原理 Master 组提交(group commit) 支持并行复制的GTID slave LOGICAL_CLOCK(由order c ...

  8. MySQL 并行复制从库发生自动重启分析

    并行复制从库发生自动重启分析 背景 半同步复制从库在晚上凌晨2点半发生自动重启,另一个异步复制从库在第二天凌晨3点也发生了自动重启. 分析 版本mysql 5.7.16 mysql> show ...

  9. MySQL 并行复制(MTS) 从库更新的记录不存在实际却存在

    目录 背景 版本 分析 测试 背景 开了并行复制的半同步从库SQL 线程报1032错误,异步复制从库没有报错,偶尔会出现这种 版本 mysql 5.7.16 redhat 6.8 mysql> ...

随机推荐

  1. 《Lua程序设计》第6章 深入函数 学习笔记

    在Lua中,函数是一种“第一类值(First-Class Value)”,它们具有特定的词法域(Lexical Scoping).“词法域”:函数可以潜逃在另一个函数中,内部的函数可以访问外部函数中的 ...

  2. Android使用Handler造成内存泄露的分析及解决方法

    一.什么是内存泄露? Java使用有向图机制,通过GC自动检查内存中的对象(什么时候检查由虚拟机决定),如果GC发现一个或一组对象为不可到达状态,则将该对象从内存中回收.也就是说,一个对象不被任何引用 ...

  3. Englis - 英文字母和音标

    英语学习基础基础是一切的根本 学习是一个长期积累知识的过程,正确掌握各科学习方法显得尤其重要!很多孩子学习成绩不好.记忆力不佳都是因为没有掌握正确的学习方法而造成的. 最基本的是:26个英文字母 48 ...

  4. Android 本地tomcat服务器接收处理手机上传的数据之案例演示

    上一篇:Android 本地tomcat服务器接收处理手机上传的数据之环境搭建     本篇基于上一篇搭建的服务器端环境,具体介绍Android真机上传数据到tomcat服务器的交互过程   场景:A ...

  5. android开发,权限获取

    转:http://blog.csdn.net/yawinstake/article/details/6748897 访问登记属性 android.permission.ACCESS_CHECKIN_P ...

  6. FPGA时序约束的几种方法 (转)

    FPGA时序约束的几种方法 对自己的设计的实现方式越了解,对自己的设计的时序要求越了解,对目标器件的资源分布和结构越了解,对EDA工具执行约束的效果越了解,那么对设计的时序约束目标就会越清晰,相应地, ...

  7. Mac下更新SVN

    Mac下自带的SVN版本还是1.6的,而最新的Versions已经更新到支持1.7版本了,在Windows下面使用1.7版本久了所以也想更新下Mac版本. OK,废话不多说,简单描述操作步骤: 去Ap ...

  8. wpgcms---设置应用模板

    wpgcms设置应用模板,找了好半天才找到. 第一步:找到对应的应用(例如:案例) 选择“界面”,前台页面 设置列表模板: 设置详情模板:

  9. 从UE(用户体验)到道家誓学再到李小龙

    公司大Boss经常会给我做技术培训,感觉他什么都知道,也挺喜欢听他的课. 本文记录可能比较天马行空,我的语文比较差,很难把自己想表达的说出来,为此我就是记录一样关键字,可能这样还会更好些 背景是讲用户 ...

  10. HDU 6343 - Problem L. Graph Theory Homework - [(伪装成图论题的)简单数学题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6343 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...