读书频道 > 网站 > 网页设计 > MySQL管理之道:性能调优、高可用与监控
2.4.2 半同步复制与异步复制的切换
14-02-20    奋斗的小年轻
收藏    我要投稿   
本书由资深MySQL专家撰写,以最新的MySQL版本为基础,以构建高性能MySQL服务器为核心,从故障诊断、表设计、SQL优化、性能参数调优、mydumper逻辑、xtrabackup热备份与恢复、MySQL高可用集群搭建与管理、MySQL服立即去当当网订购

它的工作原理就是当slave从库的IO_Thread线程将binlog日志接收完毕时,要给master主库一个确认,如果rpl_semi_sync_master_timeout=10 000(10秒)超过10秒未收到slave从库的接收确认信号,那么就会自动转换为传统的异步复制模式。

场景一:stop slave

在slave从库上,停止I/O接收binlog线程,执行以下操作:
MySQL> stop slave io_thread;
Query OK, 0 rows affected (0.04 sec)

该操作会将IO_Thread线程关闭,等待10秒后,如果master主库未收到slave从库的接收确认信号,此时看下面的程序:
MySQL> show status like '%semi%';  
+------------------------------------------------------------------------+--------+
| Variable_name | Value |
+------------------------------------------------------------------------+--------+
| Rpl_semi_sync_slave_status | OFF   |
+------------------------------------------------------------------------+--------+
1 rows in set (0.00 sec)

可以发现,此时已经转换为异步复制模式。

再次到slave从库上执行以下操作:
MySQL> start slave;
Query OK, 0 rows affected (0.01 sec)

然后查看以下程序:
MySQL> show status like '%semi%';  
+------------------------------------------------------------------------+---------+
| Variable_name                                                               ??      | Value |
+------------------------------------------------------------------------+---------+
| Rpl_semi_sync_slave_status                                              | ON     ??|
+------------------------------------------------------------------------+---------+
1 rows in set (0.00 sec)

可以看到,此时已经由原先的异步复制模式转换为半同步复制模式。

场景二:模拟同步报错

我们来试着这样操作:先在slave从机上drop database test删除一个test库;然后到master主机上再次执行drop database test,删除一个test库,这时主从同步复制就会报错,如下所示。
MySQL> show slave status\G;
*************************** 1. row ***************************
                                 slave_IO_State: Waiting for master to send event
                                       master_Host: 192.168.8.22
                                       master_User: repl
                                       master_Port: 3306
                                    Connect_Retry: 60
                                master_Log_File: MySQL-bin.000003
                            Read_master_Log_Pos: 378
                                 Relay_Log_File: vm02-relay-bin.000020
                                   Relay_Log_Pos: 445
                         Relay_master_Log_File: MySQL-bin.000003
                               slave_IO_Running: Yes
                              slave_SQL_Running: No
                                 Replicate_Do_DB:
                            Replicate_Ignore_DB:
                              Replicate_Do_Table:
                         Replicate_Ignore_Table:
                       Replicate_Wild_Do_Table:
    Replicate_Wild_Ignore_Table:
                                     Last_Errno: 1008
                                     Last_Error: Error 'Can't drop database 'sdf'; database doesn't exist' on query. Default database: 'sdf'. Query: 'drop database sdf'
                                   Skip_Counter: 0
                            Exec_master_Log_Pos: 299
                                Relay_Log_Space: 1016
                                Until_Condition: None
                                 Until_Log_File:
                                  Until_Log_Pos: 0
                             master_SSL_Allowed: No
                             master_SSL_CA_File:
                             master_SSL_CA_Path:
                                master_SSL_Cert:
                              master_SSL_Cipher:
                                 master_SSL_Key:
                  Seconds_Behind_master: NULL
master_SSL_Verify_Server_Cert: No
                                  Last_IO_Errno: 0
                                  Last_IO_Error:
                                 Last_SQL_Errno: 1008
                                 Last_SQL_Error: Error 'Can't drop database 'sdf'; database doesn't exist' on query. Default database: 'sdf'. Query: 'drop database sdf'
    Replicate_Ignore_Server_Ids:
                               master_Server_Id: 22
1 row in set (0.00 sec)

查看半同步复制状态:
MySQL> show status like '%semi%';  
+------------------------------------------------------------------------+--------+
| Variable_name | Value |
+------------------------------------------------------------------------+--------+
| Rpl_semi_sync_slave_status | ON     |
+------------------------------------------------------------------------+--------+
1 rows in set (0.00 sec)

从上面的状态信息可以看出,没有转化为异步复制模式,仍然是半同步复制模式,可见半同步复制跟IO_THREAD是有直接关系的,但跟SQL_THREAD没关系。也就是说,slave从库接收完二进制日志后会给master主库一个确认,但它并不会管relay-log中继日志是否执行完。

场景三:commit提交等待

我们先在slave从机上关闭主从复制,为了方便看出效果,调整rpl_semi_sync_master_timeout = 200 000毫秒,约等于3分钟。

rpl_semi_sync_master_wait_no_slave = on,表示允许master每个事务提交后等待slave的接收确认信号。

下面是操作步骤:

1)在slave从库,停止同步复制,执行命令:“Stop slave;”。

2)master主库上,执行下面的操作:
MySQL> use test;
Database changed
MySQL> begin;
Query OK, 0 rows affected (0.00 sec)

MySQL> update t set name='ccd' where id=3;
Query OK, 2 rows affected (0.07 sec)
Rows matched: 2  Changed: 2  Warnings: 0

MySQL> select * from t;
+------+---------+
| id    | name |
+------+---------+
|     1 | a         |
|     1 | a         |
|     2 | b         |
|     2 | b         |
|     3 | ccd     |
|     3 | ccd     |
+------+---------+
6 rows in set (0.01 sec)

MySQL> commit;
Query OK, 0 rows affected (3 min 20.00 sec)

可以看到,一个简单的update需要耗时3分20秒,原因就是半同步复制需要等待slave从库的接收确认,因为rpl_semi_sync_master_timeout设置的是200 000毫秒,约等于3分钟,所以提交就变慢了。

点击复制链接 与好友分享!回本站首页
分享到: 更多
您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:1.3 功能
下一篇:1.5 小结
相关文章
图文推荐
JavaScript网页动画设
1.9 响应式
1.8 登陆页式
1.7 主题式
排行
热门
文章
下载
读书

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训
版权所有: 红黑联盟--致力于做最好的IT技术学习网站