默認狀況下,MySQL的複製功能是異步的。master把binlog發送給slave時,這個複製動做就已經完成,master不會驗證slave是否接收完畢(相似於Oracle DataGuard Maximum Performance)。異步複製同時意味着在把數據從一個mysqld實例拷貝到另外一個mysqld時有一個延時,即master當前提交的事務不會在同一時刻拷貝到slave。這也帶來了必定的風險,當master或slave發生故障時,slave有可能會沒有接收到master發送過來的binlog,這樣就會形成了master/slave的數據不一直,甚至在恢復時也會形成數據的損失。
爲了解決這個問題,MySQL 在5.5之後引入了一種半同步模式,slave在接收binlog並寫入relay log後會給服務器發送一個反饋,告訴master接收完成,當出現超時狀況時,master會暫時切換到異步複製模式,和Oracle DataGuard Maximum Available的處理方式比較類似。半同步複製模式必須在master和slave端同時啓用,不然master會使用默認的異步模式。php
個人環境是RHEL 6.5 x86_64, Percona-Server-server-56(RPM),已經配置了異步的同步模式。
檢查動態加載選項和插件列表。html
mysql> select @@have_dynamic_loading ; +------------------------+ | @@have_dynamic_loading | +------------------------+ | YES | +------------------------+ 1 row in set (0.00 sec) mysql> show plugins; ......
默認並無加載半同步插件,rpm發行版的插件.so文件的位置
/usr/lib64/mysql/plugin/semisync_master.so
/usr/lib64/mysql/plugin/semisync_slave.so
而後在M/S上都加載插件並啓用同步。初次加載插件後,MySQL會將該插件記錄到系統表mysql.plugin中,下次mysqld啓動時會自動加載,無需INSTALL PLUGINmysql
mysql> INSTALL PLUGIN rpl_semi_sync_master soname 'semisync_master.so' ; Query OK, 0 rows affected (0.01 sec) mysql> INSTALL PLUGIN rpl_semi_sync_slave soname 'semisync_slave.so'; Query OK, 0 rows affected (0.00 sec) mysql> SET GLOBAL rpl_semi_sync_master_enabled=ON; mysql> SET GLOBAL rpl_semi_sync_slave_enabled=ON;
要將rpl_semi_sync_master_enabled和rpl_semi_sync_slave_enabled參數寫入配置文件my.cnfsql
rpl_semi_sync_master_enabled = 1 rpl_semi_sync_slave_enabled =1
日誌文件會顯示:bash
2014-08-14 14:13:23 5927 [Note] Semi-sync replication initialized for transactions. 2014-08-14 14:13:23 5927 [Note] Semi-sync replication enabled on the master.
在master上有4個相關參數,slave中有2個.服務器
mysql> show global variables like 'rpl_semi%'; +------------------------------------+-------+ | Variable_name | Value | +------------------------------------+-------+ | rpl_semi_sync_master_enabled | ON | --master上是否開啓了半同步複製模式 | rpl_semi_sync_master_timeout | 10000 | --該參數默認爲10000毫秒,可動態調整。它用來表示若是主庫中某個事務等待時間超過10秒,則降級爲異步複製模式。 | rpl_semi_sync_master_trace_level | 32 | --開啓半同模式的調試級別 | rpl_semi_sync_master_wait_no_slave | ON | --表示是否容許master每一個事物提交後都要等待slave的接收等待確認信號,默認爲ON。 | rpl_semi_sync_slave_enabled | ON | --slave是否開啓了半同步複製模式 | rpl_semi_sync_slave_trace_level | 32 | +------------------------------------+-------+ 6 rows in set (0.00 sec)
3. 半同步與異步的切換網絡
執行完上面的步驟後,咱們在M/S上檢查半同步的狀態,發現rpl_semi_sync_slave_status都是關閉的。這說明雖然啓用了半同步的功能,但slave不會自動從異步模式轉換到半同步模式。session
mysql> show status like "%semi%"; +--------------------------------------------+-------+ | Variable_name | Value | +--------------------------------------------+-------+ | Rpl_semi_sync_master_clients | 1 | --有多少slave配置成了semi-sync模式 | Rpl_semi_sync_master_net_avg_wait_time | 677 | --等待slave確認的平均等待時間,單位微秒。 | Rpl_semi_sync_master_net_wait_time | 3385 | --master的總等待時間,單位微秒 | Rpl_semi_sync_master_net_waits | 5 | --等待slave確認的的總的等待次數 | Rpl_semi_sync_master_no_times | 0 | --關閉半同步複製的次數 | Rpl_semi_sync_master_no_tx | 0 | --slave確認的不成功提交次數 | Rpl_semi_sync_master_status | ON | --master如今是不是半同步複製狀態 | Rpl_semi_sync_master_timefunc_failures | 0 | --半同步所用的時間函數失敗的次數 | Rpl_semi_sync_master_tx_avg_wait_time | 776 | --事務等待slave確認的平均等待時間,單位微秒 | Rpl_semi_sync_master_tx_wait_time | 3881 | --事物等待slave確認的總等待時間,單位微秒 | Rpl_semi_sync_master_tx_waits | 5 | --等待slave確認的的總的等待次數 | Rpl_semi_sync_master_wait_pos_backtraverse | 0 | --改變當前等待最小二進制日誌的次數 | Rpl_semi_sync_master_wait_sessions | 0 | --當前有多少個session 由於slave 的回覆而形成等待 | Rpl_semi_sync_master_yes_tx | 5 | --slave確認的成功提交次數 | Rpl_semi_sync_slave_status | OFF | --該server的slave是否處於半同步狀態 +--------------------------------------------+-------+
過上面的參數也說明了開啓半同步會致使一部分額外的開銷:
(1). 完成單條事務增長了額外的等待延遲,延遲的大小取決於網絡的好壞。
(2). Semi-sync不是分佈式事務,主庫會在本身完成事務後,等待備庫接收事務日誌。
接下來從新啓動slave。異步
mysql> stop slave; Query OK, 0 rows affected (0.01 sec) mysql> start slave ; Query OK, 0 rows affected (0.03 sec) 這是Master和Slave中的日誌中會提示: --- master --- 2014-08-14 14:26:10 5927 [Note] Start semi-sync binlog_dump to slave (server_id: 2), pos(mysql-bin.000009, 1507) --- slave --- 2014-08-14 14:26:09 5969 [Note] Slave I/O thread: Start semi-sync replication to master 'rep@172.19.17.210:3306' in log 'mysql-bin.000009' at position 1507
次檢查slave的狀態:分佈式
mysql> show status like "%semi%"; +--------------------------------------------+-------+ | Variable_name | Value | +--------------------------------------------+-------+ | Rpl_semi_sync_master_status | ON | ...... | Rpl_semi_sync_slave_status | ON | +--------------------------------------------+-------+ 15 rows in set (0.01 sec)
參考:通常狀況下,當slave的io線程將binlog接受完畢後,要給master發送一個確認。若是超過rpl_semi_sync_master_timeout=10000(10秒)內未收到該確認信號,那麼就自動轉換爲異步複製模式。這種狀況下要排查錯誤並重啓slave來恢復半同步模式。
http://dev.mysql.com/doc/refman/5.5/en/replication-semisync.html
http://www.orczhou.com/index.php/2011/06/mysql-5-5-semi-sync-replication-setup-config/