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追赶上之后,继续切换到半同步模式。
具体配置
注,mysql5.5半同步插件是由谷歌提供,
mysql5.5 版本支持半同步复制功能(Semisynchronous Replication),但还不是原生的支持,是通过plugin来支持的,并且默认是没有安装这个插件的。 不论是二进制发布的,还是自己源代码编译的,都会默认生成这个插件,一个是针对master 的一个是针对slave的,在使用之前需要先安装这俩plugins, 具体位置/usr/local/mysql/lib/plugin/下,一个是master用的semisync_master.so,一个是slave用的semisync_slave.so,下面我们就来具体配置一下
master:
(1).安装插件
首先先检查 mysql是否支持动态添加插件,
mysql> select @@have_dynamic_loading ;
+————————+
| @@have_dynamic_loading |
+————————+
| YES |
+————————+
1 row in set (0.00 sec)
支持动态增减插件,
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME ‘semisync_master.so’;
Query OK, 0 rows affected (0.01 sec)
添加完插件后,系统会默认的增加了几个系统参数
mysql> show global 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> 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)
mysql> show global variables like ‘rpl_semi_sync%’;
+————————————+——-+
| Variable_name | Value |
+————————————+——-+
| rpl_semi_sync_master_enabled | ON?? |
| rpl_semi_sync_master_timeout | 1000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_no_slave | ON |
+————————————+——-+
4 rows in set (0.00 sec)
(2).修改配置文件,添加下面2行到[mysqld]中
[root@localhost teddylu]# grep “rpl_semi_sync” /etc/my.cnf
rpl_semi_sync_master_enabled=1 #启用半同步
rpl_semi_sync_master_timeout=1000#超时时间为1s
(3).重新启动服务
/etc/init.d/mysqld restart
slave:
(1).安装插件
mysql> select @@have_dynamic_loading ;
+————————+
| @@have_dynamic_loading |
+————————+
| YES |
+————————+
1 row in set (0.00 sec)
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME ‘semisync_slave.so’;
Query OK, 0 rows affected (0.01 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.00 sec)
(2).修改配置文件,添加一行
[root@localhost ~]# grep rpl_semi_sync /etc/my.cnf
rpl_semi_sync_slave_enabled=1
(3).重新启动服务
/etc/init.d/mysqld restart
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 | 602 |
| Rpl_semi_sync_master_net_wait_time | 1205 |
| Rpl_semi_sync_master_net_waits | 2 |
| Rpl_semi_sync_master_no_times | 1 |
| Rpl_semi_sync_master_no_tx | 2 |
| 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| 2|
+——————————————–+——-+
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)
MySQL5.5实现主从半复制