關於MySQL的複製架構,大致有下面三種方式,異步,全同步複製,半同步複製。html
第一種是異步複製,是比較經典的主從複製,搭建主從默認的架構方式,就是屬於異步的,相對來講性能要好一些。可是仍是會有丟失數據的狀況。mysql
第二種是全複製,好比說MySQL Cluster這樣的方式,是屬於全複製的,實際上MySQL Cluster其實發展並不大順利,更多時候是一個實驗室產品,可是時間定格在2016年12月12日,MySQL 5.7.17 GA的重大特性group replication插件推出,加強了MySQL原有的高可用方案(原有的Replication方案),提供了重要的特性—多寫,保證組內高可用,確保數據最終一致性。有點相似Oracle裏面的RAC.sql
第三種是在異步和全複製之間的一種方案,就是半同步semi-sync replication。自MySQL 5.5推出,是對異步和全複製的一種補充,確切的說,應該是對MySQL Cluster這種方案的補充。數據庫
若是把這個和Oracle聯繫起來,其實和Oracle高可用模式有點相似,Oracle中是最大性能模式,最大保護模式,最大高可用模式,其中最大性能模式就是異步的方式,相似於異步複製的角色,最大保護模式是徹底的數據同步,有點相似於全複製的方案,而最大高可用模式是介於二者之間,甚至能夠達到動態切換,和半同步複製的角色差很少。
微信
要開啓半同步,咱們須要安裝插件,這個過程就很簡單了。基本的要求是在知足異步複製的狀況下,版本在5.5以上,而且變量have_dynamic_loading爲YES網絡
> show variables like '%have_dynamic_loading%';
在base目錄下,能夠很容易找到所需的插件。當前的base目錄爲/usr,能夠根據關鍵字找到插件。架構
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| have_dynamic_loading | YES |
+----------------------+-------+
1 row in set (0.00 sec)
# find . -name "semisync_master.so"
異步
./lib64/mysql/plugin/semisync_master.so
./lib64/mysql/plugin/debug/semisync_master.so
要安裝插件就是兩個簡單的命令。性能
> install plugin rpl_semi_sync_master soname 'semisync_master.so';
安裝後查看mysql.plugin看看插件記錄是否存在,或者使用show plugins也能夠。
Query OK, 0 rows affected (0.11 sec)
> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
Query OK, 0 rows affected (0.00 sec)
學習
> select * from mysql.plugin;
固然默認半同步的開關尚未打開。
+----------------------+--------------------+
| name | dl |
+----------------------+--------------------+
| rpl_semi_sync_master | semisync_master.so |
| rpl_semi_sync_slave | semisync_slave.so |
+----------------------+--------------------+
2 rows in set (0.00 sec)
> show variables like 'rpl_semi_sync_master%';
這裏涉及到兩個參數rpl_semi_sync_master_enabled和rpl_semi_sync_slave_enabled,比較直觀。
+------------------------------------+-------+
| 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)
打開便可。set global rpl_semi_sync_master_enabled=1;
若是在master端簡單驗證,也能夠使用show status
set global rpl_semi_sync_slave_enabled=1;
> show status like 'rpl_semi_sync_master_status';
固然在slave端也須要作一樣的操做,而後在slave端重啓IO_Thread便可。
+-----------------------------+-------+
| Variable_name | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | ON |
+-----------------------------+-------+
> STOP SLAVE IO_THREAD;
Master端檢查
Query OK, 0 rows affected (0.01 sec)
> START SLAVE IO_THREAD;
Query OK, 0 rows affected (0.01 sec)Rpl_semi_sync_master_status
Slave端檢查
Rpl_semi_sync_slave_status
MySQL 5.7中新增了一個參數來控制半同步模式下 主庫在返回給會話事務成功以前提交事務的方式。
> show variables like 'rpl_semi_sync_master_wait_point';
而在MySQL 5.6中是什麼設置呢,是AFTER_COMMIT
+---------------------------------+------------+
| Variable_name | Value |
+---------------------------------+------------+
| rpl_semi_sync_master_wait_point | AFTER_SYNC |
+---------------------------------+------------+
1 row in set (0.00 sec)
這兩個參數該怎麼理解。我參考了https://sanwen8.cn/p/105GRDe.html 中的圖片。
master的數據寫入了binlog,slave 刷新到磁盤(relay log),因此在OLTP的場景下,master須要等待slave 反饋收到relay log,只有收到ACK後master纔將commit OK結果反饋給客戶端
而MySQL 5.7中的半同步複製,有個叫法是Loss-Less半同步複製。實現的方式有了一些差異。
這種模式(AFTER_SYNC),事務是在提交以前發送給Slave,當Slave沒有接收成功,而且若是發生Master宕機的場景,不會致使主從不一致,由於此時Master端尚未提交,因此主從都沒有數據。
咱們來簡單看看半同步複製的一些小測試。
create database testsync;
而後建立一個表,插入一行數據。很明顯執行速度很快。
> create table testsync.test(id int);
咱們模擬網絡延遲的狀況,直接把slave停掉。
Query OK, 0 rows affected (0.07 sec)
> insert into testsync.test values(100);
Query OK, 1 row affected (0.01 sec)
stop slave;
這個時候在Master端插入數據就會有很慢。這個過程持續了大概10秒多。
> insert into testsync.test values(101);
這裏爲何是10秒,和一個扮同步複製的參數有關。單位是毫秒,因此換算下來就是10秒。
Query OK, 1 row affected (10.00 sec)
> show variables like 'rpl_semi_sync_master_timeout';
+------------------------------+-------+
| Variable_name | Value |
+------------------------------+-------+
| rpl_semi_sync_master_timeout | 10000 |
+------------------------------+-------+
咱們看看扮同步複製的開關。
> show status like 'Rpl_semi_sync_master_status';
slave端也是OFF的狀態。
+-----------------------------+-------+
| Variable_name | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | OFF |
+-----------------------------+-------+
咱們恢復狀態,把slave啓動。而後在Master端繼續插入一條記錄,速度就很快了。
> insert into testsync.test values(102);
此時的開關是打開的。
Query OK, 1 row affected (0.00 sec)
> show status like 'Rpl_semi_sync_master_status';
查看數據庫日誌,其實也能看到很明確的信息。
+-----------------------------+-------+
| Variable_name | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | ON |
+-----------------------------+-------+
2017-02-04T23:37:44.551667+08:00 2145633 [Warning] Timeout waiting for reply of binlog (file: mysql-bin.000017, pos: 1056976828), semi-sync up to file mysql-bin.000017, position 1056976573.
2017-02-04T23:37:44.551713+08:00 2145633 [Note] Semi-sync replication switched OFF.
2017-02-04T23:41:05.824146+08:00 2145900 [Note] Start binlog_dump to master_thread_id(2145900) slave_server(13058), pos(mysql-bin.000017, 1056976573)
2017-02-04T23:41:05.824194+08:00 2145900 [Note] Start semi-sync binlog_dump to slave (server_id: 13058), pos(mysql-bin.000017, 1056976573)
2017-02-04T23:41:05.835505+08:00 0 [Note] Semi-sync replication switched ON at (mysql-bin.000017, 1056977083)
關於半同步複製還須要持續的深刻理解。今天暫且測試到這裏。
本文分享自微信公衆號 - 楊建榮的學習筆記(jianrong-notes)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。