最新消息:

MySQL的半同步复制原理与实战

MYSQL lu 486浏览

文章目录

  • 一,为什么要使用半同步复制?
  • 二,半同步复制原理
  • 三,半同步复制的实现
  • 四 , 半同步测试

一,为什么要使用半同步复制?

在mysql异步复制的情况下,Mysql Master Server将自己的Binary Log通过复制线程传输出去以后,Mysql Master Sever就自动返回数据给客户端,而不管slave上是否接受到了这个二进制日志。在半同步复制的架构下,当master在将自己binlog发给slave上的时候,要确保slave已经接受到了这个二进制日志以后,才会返回数据给客户端。对比两种架构:异步复制对于用户来说,可以确保得到快速的响应结构,但是不能确保二进制日志确实到达了slave上;半同步复制对于客户的请求响应稍微慢点,但是他可以保证二进制日志的完整性。

异步模式中,从库每次从主库读取binlog日志放到自己的relaylog里,主库不会关心从库读取多少binlog这样就就不会影响主库的性能,但是当主库宕机,但是从库binglog读取差异很大从而导致数据差异很大。实时同步这样会影响主库的性能。半同步是一个中间产品,他的机制是采用的是实时同步加异步。主库等待从库响应回答,如果超时主库就才用异步同步,当规定时间响应采用同步。系统默认是10s ,mysql5.5 本身自带半同步插件。

二,半同步复制原理

半同步复制过程如下所示:

1a

半同步复制的概念:  1,当Slave主机连接到Master时,能够查看其是否处于半同步复制的机制。2,当Master上开启半同步复制的功能时,至少应该有一个Slave开启其功能。此时,一个线程在Master上提交事务将受到阻塞,直到得知一个已开启半同步复制功能的Slave已收到此事务的所有事件,或等待超时。

3,当一个事务的事件都已写入其relay-log中且已刷新到磁盘上,Slave才会告知已收到。在 Master 实例上,有一个专门的线程(ack_receiver)接收备库的响应消息,并以通知机制告知主库备库已经接收的日志,可以继续执行。

4,如果等待超时,也就是Master没被告知已收到,此时Master会自动转换为异步复制的机制。当至少一个半同步的Slave赶上了,Master与其Slave自动转换为半同步复制的机制。

5,半同步复制的功能要在Master,Slave都开启,半同步复制才会起作用;否则,只开启一边,它依然为异步复制。

6,半同步特性的出现,就是为了保证在任何时刻主备数据一致的问题。相对于异步复制,半同步复制要求执行的每一个事务,都要求至少有一个备库成功接收后,才返回给用户。

三,半同步复制的实现

环境 :多实例 主从同步3306 3307         主从复制配置教程 http://www.ourob.com/13188.html

实现半同步复制很简单,只需要在主和从服务器上各安装一个插件, mysql5.5 已经自带这个插件。

  1. 查看半同步插件的位置
mysql> show variables like 'plugin_dir';
+---------------+--------------------------------+
| Variable_name | Value |
+---------------+--------------------------------+
| plugin_dir | /application/mysql/lib/plugin/ |
+---------------+--------------------------------+
1 row in set (0.00 sec)
[root@m01 /]# ll /application/mysql/lib/plugin/ 
total 876
-rwxr-xr-x 1 root root 13038 Dec 19 19:06 adt_null.so
-rwxr-xr-x 1 root root 24683 Dec 19 19:06 auth.so
-rwxr-xr-x 1 root root 12564 Dec 19 19:06 auth_socket.so
-rwxr-xr-x 1 root root 22977 Dec 19 19:06 auth_test_plugin.so
-rw-r--r-- 1 root root 227 Jul 2 2013 daemon_example.ini
drwxr-xr-x 2 root root 4096 Dec 19 19:24 debug
-rwxr-xr-x 1 root root 421101 Dec 19 19:02 ha_archive.so
-rwxr-xr-x 1 root root 28380 Dec 19 19:06 libdaemon_example.so
-rwxr-xr-x 1 root root 17779 Dec 19 19:06 mypluglib.so
-rwxr-xr-x 1 root root 17567 Dec 19 19:06 qa_auth_client.so
-rwxr-xr-x 1 root root 23278 Dec 19 19:06 qa_auth_interface.so
-rwxr-xr-x 1 root root 12902 Dec 19 19:06 qa_auth_server.so
-rwxr-xr-x 1 root root 172984 Dec 19 19:06 semisync_master.so
-rwxr-xr-x 1 root root 94098 Dec 19 19:06 semisync_slave.so

2、安装半同步插件并开启

在master安装
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
在slave 安装
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
安装完毕检查
mysql> show plugins;
查看当前半同步状态
主库上 mysql> SHOW VARIABLES LIKE 'rpl_semi_sync%';
+------------------------------------+-------+
| 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 |

从库mysql> SHOW VARIABLES LIKE 'rpl_semi_sync%';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled | OFF |
| rpl_semi_sync_slave_trace_level | 32 |
+---------------------------------+-------+
开启半同开关
master 端开启
mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;
设置超时时间:
mysql> SET GLOBAL rpl_semi_sync_master_timeout = 10000; #设置超时时间(单位毫秒)
检查
mysql> SHOW VARIABLES LIKE 'rpl_semi_sync%'; 
+------------------------------------+-------+
| 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 |
+------------------------------------+-------+
slave 开启
mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW VARIABLES LIKE 'rpl_semi_sync%'; 
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled | ON |
| rpl_semi_sync_slave_trace_level | 32 |
slave 上需要重启slave
mysql> stop slave IO_THREAD;
Query OK, 0 rows affected (0.00 sec)

mysql> start slave IO_THREAD; 
Query OK, 0 rows affected (0.00 sec)

master 查看半同步状态
mysql> show status like 'Rpl_semi_sync%';
查看主服务器上的semi_sync是否开启,注意clients从库数量 变为1 ,证明主从半同步复制连接成功:

3、修改配置文件永久生效

如果需要开机时,自动能够实现半同步则需要在Master和Slave的my.cnf中编辑:
# On Master 
 [mysqld] 
 rpl_semi_sync_master_enabled=1 #启动模块
 rpl_semi_sync_master_timeout=10000 #此单位是毫秒
# On Slave 
 [mysqld] 
 rpl_semi_sync_slave_enabled=1 
配置完后需要重启服务

监控半同步复制的状态变量(几个常用的):

Rpl_semi_sync_master_clients #记录支持半同步的slave的个数
Rpl_semi_sync_master_net_avg_wait_time #master 等待slave回复的平均等待时间,单位微秒
Rpl_semi_sync_master_net_wait_time #master 总的等待时间
Rpl_semi_sync_master_net_waits #master 等待slave回复的的总的等待次数
Rpl_semi_sync_master_no_times #master 关闭半同步复制的次数
Rpl_semi_sync_master_no_tx #master 查看有多少事务没有用半同步复制的机制进行复制。
Rpl_semi_sync_master_status #标记master现在是否是半同步复制状态
Rpl_semi_sync_master_timefunc_failures #时间函数未正常工作的次数
Rpl_semi_sync_master_tx_avg_wait_time #开启Semi-sync,事务返回需要等待的平均时间
Rpl_semi_sync_master_tx_wait_time #事务等待备库响应的总时间
Rpl_semi_sync_master_tx_waits #事务等待备库响应的总次数
Rpl_semi_sync_master_wait_pos_backtraverse #改变当前等待最小二进制日志的次数
Rpl_semi_sync_master_wait_sessions #当前有多少个session 因为slave 的回复而造成等待
Rpl_semi_sync_master_yes_tx #master 查看有多少事务是通过半同步复制机制成功复制。

四,半同步测试

先在主库修改表看响应时间
mysql> use oldboy;
mysql> create table tb1(id int);  
mysql> create table tb2(id int); #看响应时间,可多创建几个
然后在从库停掉IO_THREAD
mysql> stop slave IO_THREAD;  ##
再到主库修改表
mysql> create table tb22(id int); ##这次响应时间10秒,也就是到10秒超时,自动降为异步。
mysql> create table tb222(id int); 再修改表时间又会变短,因为已经成为异步了。
再到从库开启IO_THREAD
mysql> start slave IO_THREAD;
再到主库修改表,响应时间正常了。
mysql> create table tb26(id int); 
到从库查看表已经同步过来了
show databases;

然后把从服务器上的复制进程开启,

 

转载请注明:鲁金杰博客 » MySQL的半同步复制原理与实战

发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址