mysql5.6半同步主从复制配置 http://www.bieryun.com/3145.html
在谈这个特性之前,我们先来看看MySQL的复制架构衍生史。
在2000年,MySQL 3.23.15版本引入了Replication。Replication作为一种准实时同步方式,得到广泛应用。这个时候的Replicaton的实现涉及到两个线程,一个在Master,一个在Slave。Slave的I/O和SQL功能是作为一个线程,从Master获取到event后直接apply,没有relay log。这种方式使得读取event的速度会被Slave replay速度拖慢,当主备存在较大延迟时候,会导致大量binary log没有备份到Slave端。
在2002年,MySQL 4.0.2版本将Slave端event读取和执行独立成两个线程(IO线程和SQL线程),同时引入了relay log。IO线程读取event后写入relay log,SQL线程从relay log中读取event然后执行。这样即使SQL线程执行慢,Master的binary log也会尽可能的同步到Slave。当Master宕机,切换到Slave,不会出现大量数据丢失。
在2010年MySQL 5.5版本之前,一直采用的是这种异步复制的方式。主库的事务执行不会管备库的同步进度,如果备库落后,主库不幸crash,那么就会导致数据丢失。于是在MySQL在5.5中就顺其自然地引入了半同步复制,主库在应答客户端提交的事务前需要保证至少一个从库接收并写到relay log中。那么半同步复制是否可以做到不丢失数据呢?下面分析。
在2016年,MySQL在5.7.17中引入了一个全新的技术,称之为InnoDB Group Replication。目前官方MySQL 5.7.17基于Group replication的全同步技术已经问世,全同步技术带来了更多的数据一致性保障。相信是未来同步技术一个重要方向,值得期待。MySQL 5.7 Group Replication
半同步机制:
1. 当Master上开启半同步复制的功能时,至少应该有一个Slave开启其功能。此时,一个线程在Master上提交事务将受到阻塞,直到得知一个已开启半同步复制功能的Slave已收到此事务的所有事件,或等待超时。
2. 当Slave主机连接到Master时,能够查看其是否处于半同步复制的机制。
3. 当一个事务的事件都已写入其relay-log中且已刷新到磁盘上,Slave才会告知已收到。
4. 如果等待超时,也就是Master没被告知已收到,此时Master会自动转换为异步复制的机制。当至少一个半同步的Slave赶上了,Master与其Slave自动转换为半同步复制的机制。
5. 半同步复制的功能要在Master,Slave都开启,半同步复制才会起作用;否则,只开启一边,它依然为异步复制。
由于5.7之后的版本引入的全同步,测试半同步必须用5.6的版本进行。
1.配置半同步的主从复制必须先配置好异步的主从复制,先检查一下异步的主从是否完好。
master:
[html] view plain copy- mysql> mysql> show master status;
- +------------------+----------+--------------+------------------+-------------------+
- | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
- | mysql_bin.000013 | 601 | | | |
- 1 row in set (0.00 sec)
slave:
- mysql> show slave status\G
- *************************** 1. row ***************************
- Slave_IO_State: Waiting for master to send event
- Master_Host: 172.17.61.131
- Master_User: repl
- Master_Port: 3306
- Connect_Retry: 60
- Master_Log_File: mysql_bin.000013
- Read_Master_Log_Pos: 601
- Relay_Log_File: mysqld-relay-bin.000002
- Relay_Log_Pos: 374
- Relay_Master_Log_File: mysql_bin.000013
- Slave_IO_Running: Yes
- Slave_SQL_Running: Yes
- ...
- Exec_Master_Log_Pos: 601
- Relay_Log_Space: 548
- Until_Condition: None
- ...
- Master_Server_Id: 10000
- Master_UUID: 82acea94-3e6f-11e8-b4a7-000c29d02daa
- Master_Info_File: /u01/mysql/master.info
- SQL_Delay: 0
- SQL_Remaining_Delay: NULL
- Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
- Master_Retry_Count: 86400
2.master安装半同步模块并启动(此模块就在/usr/local/mysql/lib/plugin/semisync_master.so)
PS:如果想卸载异步模块就使用uninstall即可。
- mysql> show global variables like '%semi%';
- Empty set (0.00 sec)
- mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
- Query OK, 0 rows affected (0.06 sec)
- mysql> show global variables like '%semi%';
- +------------------------------------+-------+
- | 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 |
- 4 rows in set (0.00 sec)
rpl_semi_sync_master_enabled参数是指是否已启动半同步
rpl_semi_sync_master_timeout参数连接salve超时的时间,单位为毫秒,默认为10秒
在配置文件中修改这两个参数并重启数据库
- [root@qht131 ~]# cat /etc/my.cnf
- 。。。
- [mysqld]
- rpl_semi_sync_master_enabled = 1
- rpl_semi_sync_master_timeout = 2000
- [root@qht131 ~]# service mysql restart
- Shutting down MySQL.... [ OK ]
- Starting MySQL.. [ OK ]
- | rpl_semi_sync_master_enabled | ON |
- | rpl_semi_sync_master_timeout | 2000 |
3.slave安装半同步模块
- mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
- Query OK, 0 rows affected (0.03 sec)
- +---------------------------------+-------+
- | Variable_name | Value |
- | rpl_semi_sync_slave_enabled | OFF |
- | rpl_semi_sync_slave_trace_level | 32 |
- 2 rows in set (0.00 sec)
修改配置文件打开半同步
- [root@qht132 backup]# cat /etc/my.cnf
- 。。。。
- rpl_semi_sync_slave_enabled=1
- [root@qht132 backup]# service mysql restart
- Shutting down MySQL.. [ OK ]
- | rpl_semi_sync_slave_enabled | ON |
需要重新连接master服务器,半同步才会生效:
- mysql> stop slave io_thread;
- Query OK, 0 rows affected (0.00 sec)
- mysql> start slave io_thread;
3.检查一下半同步是否完成
- mysql> show global status like 'rpl%';
- +--------------------------------------------+-------+
- | Variable_name | Value |
- | Rpl_semi_sync_master_clients | 1 |
- | 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 | ON |
- | 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 |
- 14 rows in set (0.03 sec)
现在半同步已经正常工作了,主要看Rpl_semi_sync_master_clients是否不为0,Rpl_semi_sync_master_status是否为ON。如果Rpl_semi_sync_master_status为OFF,说明出现了网络延迟或Slave IO线程延迟。
4.那么可以验证一下半同步超时,是否会自动降为异步工作。可以在Slave上停掉半同步协议,然后在Master上创建数据库看一下能不能复制到Slave上。
slave上先关闭半同步:
- mysql> set global rpl_semi_sync_slave_enabled = 0 ;
master:
- mysql> create database dbtest;
- Query OK, 1 row affected (2.01 sec)
- mysql> create database dbtest2;
- Query OK, 1 row affected (0.00 sec)
创建第一个数据库花了2.01秒,而我们前面设置的超时时间是2秒,而创建第二个数据库花了0.01秒,由此得出结论是超时转换为异步传送。可以在Master上查看半同步相关的参数值Rpl_semi_sync_master_clients和Rpl_semi_sync_master_status是否正常。
- mysql> show global status like '%semi%';
- | Rpl_semi_sync_master_clients | 0 |
- | Rpl_semi_sync_master_no_times | 1 |
- | Rpl_semi_sync_master_no_tx | 2 |
- | Rpl_semi_sync_master_status | OFF |
Rpl_semi_sync_master_clients已为0,Rpl_semi_sync_master_status已为OFF,现在主从复制已是异步状态。
5.还有一个问题,slave开启半同步后,master能自动开启半同步吗?
- mysql> set global rpl_semi_sync_slave_enabled = 1;
- Query OK, 0 rows affected (0.01 sec)
- 14 rows in set (0.00 sec)
当Slave开启半同步后,或者当主从之间网络延迟恢复正常的时候,半同步复制会自动从异步复制又转为半同步复制,还是相当智能的。