MySQL Semisync

默認狀況下,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

1. 開啓半同步

個人環境是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.

2. 半同步的參數說明

在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/

相關文章
相關標籤/搜索