关于Mysql5.6半同步主从复制的开启方法

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介:

介绍

    先了解一下mysql的主从复制是什么回事,我们都知道,mysql主从复制是基于binlog的复制方式,而mysql默认的主从复制方式,其实是异步复制.

    主库实际上并不关心从库是否把数据拉完没有,也不关心从库有没有把数据写进硬盘入库,反正数据丢过去,让从库自己慢慢跑,而实际上这也并不影响主库任何使用的情况.

    细心的人就会发现,这种情况下,假如主库临时挂了,binlog还没传输完毕,即使是集群也不能保证说这挂了之后的数据一致性,因为你不能排除别人在主库是正常提交的,而从库没有数据的情况.

    然后在某个位面的时间上,就有人提出同步复制的概念,意思就是说,只要从库没写入,主库就不返回完成,这个时候即使主库挂了,这也只是一个未完成的事务,从库也不会记录,能保证数据一致性.

    看上去,数据一致性是解决了,但是呢,每个事务的延时就增大了,如果是大事务的话,就更惨,这得看网络带宽能不能顶得住,不然延时更低,性能更差.

    最后,在mysql5.5之后,半同步就提出来了,意思就是说,每个事务的复制,至少保证一个从库已经收到了binlog,主库才返回事务完成,但不需要理会从库是否写入硬盘.

    这样做虽然延时还是有,但是比起完全的同步方式还是好太多,对于数据一致性要求高的情况,牺牲性能来换取一定的价值,是在所难免的.

    光看文字难免有些虚,可以看看下面的图片来大致了解一下,wKiom1eN0FGDaHftAADNeqWw5TU365.png-wh_50

大家留意上面的数字,

第一部,客户端提交sql语句,

第二部,提交给存储引擎解析并处理数据修改,

第三部,事务在主库处理完毕,处于待完成状态,等待最终完成,

第四部,同时提交给各从库,等待完成,

第五部,从库返回状态给主库,标记已完成,半同步只需要一个从库返回就可以,其他会转成异步

第六部,返回客户端,整个事务已完成.

看上去还是比较不错,主从的数据一致性得到很大的提高,但是延时也不含糊,就是牺牲性能来提高一致性的问题了.

不过我还是得负责任的讲句,在极端的情况下,还是可能会丢一些数据的,所以定期做主从数据校验还是有必要的,例如使用PT工具什么的,至于为什么,这个不仿让大家思考一下,而对于大事务来说,半同步也是比较无力的情况,性能损耗较大.


安装使用

下面来看看如何安装使用半同步,大部分mysql本身并没有预装半同步的组件,需要另外安装,但是一般mysql的包里面会自带so文件,所以只要手动加载一下就可以用了.

先检查下有没有装

1
2
3
4
5
#查找是否有semisync字母,有就是装了,没有就是没装,默认是不安装的,所以请看下一步
mysql> show plugins;
         .
         .
         .

然后我们开始准备安装的事情:

1
2
3
4
5
6
7
8
#查找mysql插件目录位置
mysql> show variables like  'plugin_dir' ;
+---------------+------------------------------------+
| Variable_name | Value                              |
+---------------+------------------------------------+
| plugin_dir    |  /usr/local/mysql/lib/mysql/plugin/  |
+---------------+------------------------------------+
1 row  in  set  (0.00 sec)

去看一下相关文件夹:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#查看目录文件是否存在
[root@pingtest1 ~] # ll /usr/local/mysql/lib/mysql/plugin/
总用量 25328
-rwxr-xr-x 1 root root    16916 3月   4 01:18 adt_null.so
-rwxr-xr-x 1 root root   183009 3月   4 01:18 audit_log.so
-rwxr-xr-x 1 root root    44095 3月   4 01:18 auth_pam_compat.so
-rwxr-xr-x 1 root root    45929 3月   4 01:18 auth_pam.so
-rwxr-xr-x 1 root root    27406 3月   4 01:18 auth.so
-rwxr-xr-x 1 root root    13607 3月   4 01:18 auth_socket.so
-rwxr-xr-x 1 root root    26229 3月   4 01:18 auth_test_plugin.so
-rw-r--r-- 1 root root      227 3月   3 21:27 daemon_example.ini
drwxr-xr-x 2 root root     4096 3月   4 01:23 debug
-rwxr-xr-x 1 root root  4702357 3月   4 01:20 dialog.so
-rwxr-xr-x 1 root root  2212305 3月   4 01:18 handlersocket.so
-rwxr-xr-x 1 root root 14950125 3月   4 01:22 ha_tokudb.so
-rwxr-xr-x 1 root root   834597 3月   4 01:18 innodb_engine.so
-rwxr-xr-x 1 root root    39169 3月   4 01:18 libdaemon_example.so
-rwxr-xr-x 1 root root    27048 3月   4 01:18 libfnv1a_udf.so
-rwxr-xr-x 1 root root    27089 3月   4 01:18 libfnv_udf.so
-rwxr-xr-x 1 root root   779519 3月   4 01:18 libmemcached.so
-rwxr-xr-x 1 root root    28683 3月   4 01:18 libmurmur_udf.so
-rwxr-xr-x 1 root root    17898 3月   4 01:18 mypluglib.so
-rwxr-xr-x 1 root root    12224 3月   4 01:18 mysql_no_login.so
-rwxr-xr-x 1 root root    18574 3月   4 01:18 qa_auth_client.so
-rwxr-xr-x 1 root root    27059 3月   4 01:18 qa_auth_interface.so
-rwxr-xr-x 1 root root    13877 3月   4 01:18 qa_auth_server.so
-rwxr-xr-x 1 root root   395960 3月   4 01:18 query_response_time.so
-rwxr-xr-x 1 root root    56417 3月   4 01:18 scalability_metrics.so
-rwxr-xr-x 1 root root   537609 3月   4 01:18 semisync_master.so
-rwxr-xr-x 1 root root   289069 3月   4 01:18 semisync_slave.so
-rwxr-xr-x 1 root root   357058 3月   4 01:18 tokudb_backup.so
-rwxr-xr-x 1 root root   188402 3月   4 01:18 validate_password.so

看到下面两个,就是半同步的组件了,一个是主库组件,一个是从库组件,你可以两个都装上或者只装一个.

1
2
semisync_master.so
semisync_slave.so

下面开始正式安装:

1
2
3
4
5
#在主库上执行
mysql>  install  plugin rpl_semi_sync_master soname  'semisync_master.so' ;
mysql> show plugins;
#看到下面这个就证明成功了
rpl_semi_sync_master | ACTIVE | REPLICATION | semisync_master.so | GPL

从库当然也要做

1
2
3
4
5
#然后在从库执行
mysql>  install  plugin rpl_semi_sync_slave soname  'semisync_slave.so' ;
mysql> show plugins;
#看到下面这个就证明成功了
rpl_semi_sync_slave  | ACTIVE | REPLICATION | semisync_slave.so  | GPL

安装完了,就开始准备启动了,

主库很简单,只要设置一下半同步启动就可以了.

1
mysql>  set  global rpl_semi_sync_master_enabled = on;

当然,你也可以写到配置文件,不过写到配置文件要重启才生效,而且还要重新加载组件,所以这就没意思了.

然后到从库,slave要重启动IO线程来生效,否则还是异步的方式复制数据

1
2
3
mysql>  set  global rpl_semi_sync_slave_enabled = on;
mysql> stop slave IO_THREAD;
mysql> start slave IO_THREAD;

同样你也能写到配置文件,我就不多说了,反正这就启动完毕了.

下面来验证一下是否成功,以下是主库的信息,因为从库很多信息是没有的.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
mysql> show status like  '%Rpl_semi_sync%' ;
+--------------------------------------------+---------+
| Variable_name                              | Value   |
+--------------------------------------------+---------+
| Rpl_semi_sync_master_clients               | 1       |
| Rpl_semi_sync_master_net_avg_wait_time     | 746     |
| Rpl_semi_sync_master_net_wait_time         | 3788497 |
| Rpl_semi_sync_master_net_waits             | 5077    |
| Rpl_semi_sync_master_no_times              | 0       |
| Rpl_semi_sync_master_no_tx                 | 0       |
| Rpl_semi_sync_master_status                | ON      |
| Rpl_semi_sync_master_timefunc_failures     | 0       |
| Rpl_semi_sync_master_tx_avg_wait_time      | 614     |
| Rpl_semi_sync_master_tx_wait_time          | 2797020 |
| Rpl_semi_sync_master_tx_waits              | 4552    |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0       |
| Rpl_semi_sync_master_wait_sessions         | 0       |
| Rpl_semi_sync_master_yes_tx                | 5077    |
| Rpl_semi_sync_slave_status                 | OFF     |
+--------------------------------------------+---------+
15 rows  in  set  (0.00 sec)

解释几个重要的值。

Rpl_semi_sync_master_status:    是否启用了半同步(有时候可能网络超时导致切换成异步)。

Rpl_semi_sync_master_clients:    半同步模式下Slave一共有多少个。

Rpl_semi_sync_master_no_tx:    往slave发送失败的事务数量(最好不要有)。

Rpl_semi_sync_master_yes_tx:    往slave发送成功的事务数量。

看完上面的解析,大概你也知道我这个状态是正常的了.其他延时类别的,大家得看实际情况.


来看看我们能设置些什么关于半同步的参数

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> show variables like  '%Rpl%' ;
+------------------------------------+----------+
| Variable_name                      | Value    |
+------------------------------------+----------+
| rpl_semi_sync_master_enabled       | ON       |
| rpl_semi_sync_master_timeout       | 10000    |
| rpl_semi_sync_master_trace_level   | 32       |
| rpl_semi_sync_master_wait_no_slave | ON       |
| rpl_semi_sync_slave_enabled        | OFF      |
| rpl_semi_sync_slave_trace_level    | 32       |
| rpl_stop_slave_timeout             | 31536000 |
+------------------------------------+----------+
7 rows  in  set  (0.00 sec)

也来看看解析:

rpl_semi_sync_master_enabled:    显示是否已开启半同步机制

rpl_semi_sync_master_timeout:    Master等待slave响应的时间,单位是毫秒,默认值是10秒,超过这个时间,slave无响应,将自动转换为异步复制,如果探测到从库恢复后,又从新进入半同步状态

rpl_semi_sync_master_trace_level:    监控等级,一共4个等级(1,16,32,64)。

                * 1:general 等级,如:记录时间函数失效 

                * 16:detail 等级,记录更加详细的信息 
                * 32:net wait等级,记录包含有关网络等待的更多信息 
                * 64:function等级,记录包含有关function进入和退出的更多信息

rpl_semi_sync_master_wait_no_slave:    是否允许master 每个事物提交后都要等待slave的receipt信号。默认为on ,每一个事务都会等待,如果slave当掉后,当slave追赶上master的日志时,可以自动的切换为半同步方式,如果为off,则slave追赶上后,也不会采用半同步的方式复制了,需要手工配置。


毫无疑问,这些参数都能通过配置文件或直接set来更改,只要你觉得这个适合你的需求,例如一般我们会把响应时间设成1秒.


最后,我们来看看同样的命令在从库会有些什么信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
mysql> show status like  '%Rpl_semi_sync%' ;
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 0     |
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 0     |
| Rpl_semi_sync_master_no_times              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | OFF   |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
| Rpl_semi_sync_master_tx_wait_time          | 0     |
| Rpl_semi_sync_master_tx_waits              | 0     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 0     |
| Rpl_semi_sync_slave_status                 | ON    |
+--------------------------------------------+-------+
15 rows  in  set  (0.00 sec)

也正如我刚才说的,很多信息基本上没有,只有最后一行是不一样的,也只是证明从库半同步正常连接中.


再看看这个

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> show variables like  '%Rpl%' ;
+------------------------------------+----------+
| Variable_name                      | Value    |
+------------------------------------+----------+
| rpl_semi_sync_master_enabled       | OFF      |
| rpl_semi_sync_master_timeout       | 10000    |
| rpl_semi_sync_master_trace_level   | 32       |
| rpl_semi_sync_master_wait_no_slave | ON       |
| rpl_semi_sync_slave_enabled        | ON       |
| rpl_semi_sync_slave_trace_level    | 32       |
| rpl_stop_slave_timeout             | 31536000 |
+------------------------------------+----------+
7 rows  in  set  (0.00 sec)

主要就最后两行:

rpl_semi_sync_slave_enabled:    是否开启了从库半同步
rpl_semi_sync_slave_trace_level:    监控等级,默认也是32

rpl_stop_slave_timeout:    控制stop slave 的执行时间,在重放一个大的事务的时候,突然执行stop slave ,命令 stop slave会执行很久,这个时候可能产生死锁或阻塞,严重影响性能,可以通过这个参数控制stop slave 的执行时间,一般不需要修改.


问题汇总

5.7.3新加了一个半同步参数,至少有N个slave接收到日志,然后返回ack,这个半同步事务才能提交,默认是1。当这个值设置到和从库数量相等的话,则效果会等同于全同步复制。

1
2
#例如我有3个从库,我现在要设置两个从库应答才能返回事务提交成功
rpl_semi_sync_master_wait_for_slave_count = 2

5.7新功能,在控制半同步模式下 主库在返回给会话事务成功之前提交事务的方式。旧模式是AFTER_COMMIT,新模式是AFTER_SYNC,默认值:AFTER_SYNC 。master 将每个事务写入binlog ,传递到slave,并且刷新到磁盘。master等待slave 反馈接收到事务并刷新到磁盘。一旦接到slave反馈,master在主库提交事务并且返回结果给会话。 在AFTER_SYNC模式下,所有的客户端在同一时刻查看已经提交的数据。假如发生主库crash,所有在主库上已经提交的事务已经同步到slave并记录到relay log。此时切换到从库,可以保障最小的数据损失。

1
2
#显然新模式更好,不过5.7默认就是这个参数,可改可不改
rpl_semi_sync_master_wait_point = AFTER_SYNC

而当半同步复制设置N个slave应答,如果当前Slave小于N,取决于rpl_semi_sync_master_wait_no_slave的设置。

1
2
3
4
#设成0会立刻变成异步复制。
rpl_semi_sync_master_wait_no_slave = 0
#设成1仍然等待应答,直到超时。
rpl_semi_sync_master_wait_no_slave = 1

超时时间rpl_semi_sync_master_timeout的值,不应该短过应用(例如JDBC)连接池或线程池的超时时间,这样应用可能出现一直等待或者是抛出异常的问题。

1
2
#例如某些大数据量的操作,随时都超过5分钟,那么我们就要设大一点
set  global rpl_semi_sync_master_timeout = 300000







     本文转自arthur376 51CTO博客,原文链接:http://blog.51cto.com/arthur376/1827808 ,如需转载请自行联系原作者





相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
3月前
|
人工智能 运维 关系型数据库
数据库运维:mysql 数据库迁移方法-mysqldump
本文介绍了MySQL数据库迁移的方法与技巧,重点探讨了数据量大小对迁移方式的影响。对于10GB以下的小型数据库,推荐使用mysqldump进行逻辑导出和source导入;10GB以上可考虑mydumper与myloader工具;100GB以上则建议物理迁移。文中还提供了统计数据库及表空间大小的SQL语句,并讲解了如何使用mysqldump导出存储过程、函数和数据结构。通过结合实际应用场景选择合适的工具与方法,可实现高效的数据迁移。
655 1
|
26天前
|
存储 关系型数据库 MySQL
MySQL数据库中进行日期比较的多种方法介绍。
以上方法提供了灵活多样地处理和对比MySQL数据库中存储地不同格式地日子信息方式。根据实际需求选择适当方式能够有效执行所需操作并保证性能优化。
169 10
|
6月前
|
SQL 存储 关系型数据库
【YashanDB知识库】共享从 MySQL异常处理CONTINUE HANDLER的改写方法
【YashanDB知识库】共享从 MySQL异常处理CONTINUE HANDLER的改写方法
|
2月前
|
SQL Oracle 关系型数据库
比较MySQL和Oracle数据库系统,特别是在进行分页查询的方法上的不同
两者的性能差异将取决于数据量大小、索引优化、查询设计以及具体版本的数据库服务器。考虑硬件资源、数据库设计和具体需求对于实现优化的分页查询至关重要。开发者和数据库管理员需要根据自身使用的具体数据库系统版本和环境,选择最合适的分页机制,并进行必要的性能调优来满足应用需求。
101 11
|
6月前
|
关系型数据库 MySQL Shell
MySQL 备份 Shell 脚本:支持远程同步与阿里云 OSS 备份
一款自动化 MySQL 备份 Shell 脚本,支持本地存储、远程服务器同步(SSH+rsync)、阿里云 OSS 备份,并自动清理过期备份。适用于数据库管理员和开发者,帮助确保数据安全。
|
4月前
|
SQL 数据采集 关系型数据库
实现MySQL与SQL Server之间数据迁移的有效方法
总的来说,从MySQL到SQL Server的数据迁移是一个涉及到很多步骤的过程,可能会遇到各种问题和挑战。但只要精心规划、仔细执行,这个任务是完全可以完成的。
287 18
|
3月前
|
关系型数据库 MySQL
MySQL字符串拼接方法全解析
本文介绍了四种常用的字符串处理函数及其用法。方法一:CONCAT,用于基础拼接,参数含NULL时返回NULL;方法二:CONCAT_WS,带分隔符拼接,自动忽略NULL值;方法三:GROUP_CONCAT,适用于分组拼接,支持去重、排序和自定义分隔符;方法四:算术运算符拼接,仅适用于数值类型,字符串会尝试转为数值处理。通过示例展示了各函数的特点与应用场景。
|
5月前
|
SQL 关系型数据库 MySQL
【MySQL】SQL分析的几种方法
以上就是SQL分析的几种方法。需要注意的是,这些方法并不是孤立的,而是相互关联的。在实际的SQL分析中,我们通常需要结合使用这些方法,才能找出最佳的优化策略。同时,SQL分析也需要对数据库管理系统,数据,业务需求有深入的理解,这需要时间和经验的积累。
154 12
|
5月前
|
SQL 关系型数据库 MySQL
大数据新视界--大数据大厂之MySQL数据库课程设计:MySQL 数据库 SQL 语句调优方法详解(2-1)
本文深入介绍 MySQL 数据库 SQL 语句调优方法。涵盖分析查询执行计划,如使用 EXPLAIN 命令及理解关键指标;优化查询语句结构,包括避免子查询、减少函数使用、合理用索引列及避免 “OR”。还介绍了索引类型知识,如 B 树索引、哈希索引等。结合与 MySQL 数据库课程设计相关文章,强调 SQL 语句调优重要性。为提升数据库性能提供实用方法,适合数据库管理员和开发人员。
|
4月前
|
缓存 JSON 关系型数据库
MySQL 查询优化分析 - 常用分析方法
本文介绍了MySQL查询优化分析的常用方法EXPLAIN、Optimizer Trace、Profiling和常用监控指标。

推荐镜像

更多