5.5版本历史:
5.5版本从2010年12月份破土动工,工程师们总会一个月更新一个小版本,一年之后GA版本发布,mysql的工程师们对5.5做了这些更新, 这个版本秉持提高性能、稳定性的原则。这篇文章就仅仅介绍半同步复制,半同步复制最早是google mysql team实现的一个补丁,本来是google提交给Heikki的,但是由于等不及就自己实现了。
导读:
作为5.5版本中的新特性,为了保证主从数据的一致性,mysql发布了半同步复制功能,之前版本为异步复制,半同步的意思表示MASTER 只需要接收到其中一台SLAVE的返回信息,就会commit;否则需等待直至切换成异步再提交。在异步复制的模式下会存在下面的缺点,如果主机crash,已经commit的事务不会被传送到任何的slave上。
再来总结下几个功能点:
- 保证主从服务器上数据的一致性
- 跳过某实例的复制事件
- 主从复制能自动使用字段类型的转换
- 当CRASH SLAVE 时能自动从错误中恢复同步(笔者在5.1.40上测试过,确实无法自动跳过错误)
安装步骤:
Master端的安装过程
- INSTALL PLUGIN rpl_semi_sync_master SONAME ‘semisync_master.so’;
- SHOW VARIABLES LIKE ‘rpl_semi_sync_master_enabled ‘ 值为ON,表示开启;否则检查失败原因
- SET GLOBAL rpl_semi_sync_master_timeout=100000(利于观察);
- SET GLOBAL rpl_semi_sync_master_wait_no_slave=1(用于以下实验,也是默认值,表示即使没有SLAVE也会等待过期时间结束)
Slave端的安装过程
- INSTALL PLUGIN rpl_semi_sync_slave SONAME ‘semisync_slave.so’;
- SHOW VARIABLES LIKE ‘rpl_semi_sync_slave_enabled ‘ 值为ON,表示开启;否则失败检查原因
实例测试:
测试1表明半同步复制生效,下面例子表示没有SLAVE返回给MASTER,commit之后就开始等待直到切换为异步,Rpl_semi_sync_master_no_tx表示SLAVE没有响应MASTER的次数,该语句的执行时间恰好rpl_semi_sync_master_timeout=100s。
Session1(master) | Session2(SLAVE) |
Show status like ‘Rpl_semi_sync_master_no_tx’| Rpl_semi_sync_master_no_tx | 4 | | |
Stop slave; | |
Start transaction; | |
UPDATE task SET c1=3 WHERE c1=2;Query OK, 1773939 rows affected (9.56 sec) | |
Commit;Query OK, 0 rows affected (1 min 40.00 sec)==100s | |
Show status like ‘Rpl_semi_sync_master_no_tx’| Rpl_semi_sync_master_no_tx | 5 | | |
测试2表明使用的是异步复制,slave返回给master,commit之后不等待
Session1(master) | Session2(SLAVE) |
ALTER TABLE task DROP COLUMN c1; | |
Show status like ‘Rpl_semi_sync_master_no_tx’| Rpl_semi_sync_master_no_tx | 4 | | |
ALTER TABLE task DROP COLUMN c1;Query OK, 1773940 rows affected (20.76 sec)<100S | |
Show status like ‘Rpl_semi_sync_master_no_tx’| Rpl_semi_sync_master_no_tx | 4 | | |
另外像下面的测试案例,你是否认为半同步复制生效呢?:
- 设置SLAVE复制出错
- 按照测试2步骤继续测试
得到的结果是不生效。原因是MASTER会收到SLAVE返回的信息包
测试3 跳过某个SERVER_ID的复制事件
Session1(master) | Session2(SLAVE) |
CREATE TABLE sbtest_semi(i int not null); | |
mysql>show slave status\G ************ 1. row *************Slave_IO_State: Waiting for master to send event
…. …. Slave_IO_Running: Yes Slave_SQL_Running: Yes …. …. Replicate_Ignore_Server_Ids: Master_Server_Id: 3307 | |
mysql> SELECT * FROM sbtest_semi; Empty set (0.00 sec) | |
STOP SLAVE;CHANGE MASTER TO Ignore_Server_Ids=(3307);START SLAVE; | |
INSERT INTO sbtest_semi VALUES(1);MYSQL> SELECT * FROM sbtest_semi; +—+
| i | +—+ | 1 | | |
mysql> SELECT * FROM sbtest_semi; Empty set (0.00 sec) | |