MySQL 主从之半同步

1.半同步复制

在说明半同步复制之前我们先来了解一下,什么是同步复制?同步复制:同步复制可以定义为数据在同一时刻被提交到一台或多台机器,通常这是通过众所周知的“两阶段提交”做到的。虽然这确实给你在多系统中保持一致性,但也由于增加了额外的消息交换而造成性能下降。使用MyISAM或者InnoDB存储引擎的MySQL本身并不支持同步复制,然而有些技术,例如分布式复制块设备(简称DRBD),可以在下层的文件系统提供同步复制,允许第二个MySQL服务器在主服务器丢失的情况下接管(使用第二服务器的复本)。了解了同步复制我们正下面来说一下,什么是半同步复制?

MYSQL 5.5开始,支持半自动复制。之前版本的MySQL Replication都是异步(asynchronous)的,主库在执行完一些事务后,是不会管备库的进度的。如果备库不幸落后,而更不幸的是主库此时又出现Crash(例如宕机),这时备库中的数据就是不完整的。简而言之,在主库发生故障的时候,我们无法使用备库来继续提供数据一致的服务了。Semisynchronous Replication(半同步复制)则一定程度上保证提交的事务已经传给了至少一个备库。Semi synchronous中,仅仅保证事务的已经传递到备库上,但是并不确保已经在备库上执行完成了。

此外,还有一种情况会导致主备数据不一致。在某个session中,主库上提交一个事务后,会等待事务传递给至少一个备库,如果在这个等待过程中主库Crash,那么也可能备库和主库不一致,这是很致命的。如果主备网络故障或者备库挂了,主库在事务提交后等待10秒(rpl_semi_sync_master_timeout的默认值)后,就会继续。这时,主库就会变回原来的异步状态。

MySQL在加载并开启Semi-sync插件后,每一个事务需等待备库接收日志后才返回给客户端。如果做的是小事务,两台主机的延迟又较小,则Semi-sync可以实现在性能很小损失的情况下的零数据丢失。

2.异步与半同步异同

默认情况下MySQL的复制是异步的,Master上所有的更新操作写入Binlog之后并不确保所有的更新都被复制到Slave之上。异步操作虽然效率高,但是在Master/Slave出现问题的时候,存在很高数据不同步的风险,甚至可能丢失数据。

MySQL5.5引入半同步复制功能的目的是为了保证在master出问题的时候,至少有一台Slave的数据是完整的。在超时的情况下也可以临时转入异步复制,保障业务的正常使用,直到一台salve追赶上之后,继续切换到半同步模式。

3.具体配置

注,mysql5.5半同步插件是由谷歌提供,具体位置/usr/local/mysql/lib/plugin/下,一个是master用的semisync_master.so,一个是slave用的semisync_slave.so,下面我们就来具体配置一下。(亲测也适用5.7)

master:
(1).安装插件
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';  
Query OK, 0 rows affected (0.39 sec)
mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1; 
Query OK, 0 rows affected (0.00 sec)
mysql> SET GLOBAL rpl_semi_sync_master_timeout = 1000; 
Query OK, 0 rows affected (0.00 sec)

(2).修改配置文件
[root@node1 ~]# vim /etc/my.cnf
[mysqld]
rpl_semi_sync_master_enabled=1 #启用半同步
rpl_semi_sync_master_timeout=1000 #超时时间为1s

(3).重新启动服务
[root@node1 ~]# service mysqld restart 
Shutting down MySQL... SUCCESS!   
Starting MySQL.. SUCCESS!
slave:
(1).安装插件
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';  
Query OK, 0 rows affected (0.38 sec)
mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;  
Query OK, 0 rows affected (0.00 sec)
mysql> STOP SLAVE IO_THREAD; 
Query OK, 0 rows affected (0.00 sec)
mysql> START SLAVE IO_THREAD;
Query OK, 0 rows affected (0.01 sec)

(2).修改配置文件
[root@node2 ~]# vim /etc/my.cnf
[mysqld]
rpl_semi_sync_slave_enabled=1  #启用半同步复制

(3).重新启动服务
[root@node2 ~]# service mysqld restart 
Shutting down MySQL. SUCCESS!   
Starting MySQL.. SUCCESS!
4.查看一下状态
master:
mysql> SHOW GLOBAL STATUS LIKE 'rpl_semi%'; 
+--------------------------------------------+-------+  
| 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.00 sec)


slave:
mysql> SHOW GLOBAL STATUS LIKE 'rpl_semi%'; 
+----------------------------+-------+  
| Variable_name              | Value |  
+----------------------------+-------+  
| Rpl_semi_sync_slave_status | ON    |  
+----------------------------+-------+  
1 row in set (0.01 sec)

参考:http://blog.51cto.com/freeloda/1282329

你可能感兴趣的:(mysql,mysql,mysql)