首頁 > 軟體

MySQL主從複製之半同步semi-sync replication

2022-02-21 19:00:23

一、半同步簡介

  • MASTER節點在執行完使用者端提交的事務後不是立刻返回結果給使用者端,而是等待至少一個SLAVE節點接收並寫到relay log中才返回給使用者端。
  • 半同步相對於非同步複製而言,提高了資料的安全性,同時也造成了一定程度的延遲,這個延遲最少是一個TCP往返的時間。所以,半同步複製最好在低延時的網路中使用。
  • MySQL從5.5開始就支援半同步複製,在5.7.2版本的時候對半同步複製進行了一次改進;原先的半同步策略為 AFTER_COMMIT 改進後的策略為 AFTER_SYNC 兩者的差異在於SLAVE節點ACK應答MASTER的時機不同。

二、兩種模式介紹

AFTER_COMMIT 模式介紹

MASTER將每個事務寫入到二進位制紀錄檔並刷盤儲存,同時將事務傳送給SLAVE,然後將事務提交給儲存引擎處理並進行提交,然後等待SLAVE返回確認資訊,在收到確認資訊後,MASTER將結果返回給使用者端,然後當前使用者端可以繼續工作。

AFTER_SYNC 模式介紹

MASTER將每個事務寫入到二進位制紀錄檔並刷盤儲存,同時將事務傳送給SLAVE,然後等待SLAVE返回確認資訊,收到確認資訊後,將事務提交給儲存引擎處理並進行提交,並將結果返回給使用者端,然後當前使用者端可以繼續工作。

三、兩種方式比較

對於第一種 AFTER_COMMIT 方式,當前使用者端只有在伺服器向儲存引擎提交資料並收到SLAVE返回的確認後,才會收到事務的返回結果。在事務提交之後收到SLAVE返回確認資訊之前,此刻其他使用者端可以看到當前使用者端提交的事務資訊。
如果SLAVE節點由於網路等原因並未收到MASTER節點傳遞過來的事務,而MASTER節點此刻crash了。HA進行故障轉移,使用者端都連到SLAVE節點上,這時先前在MASTER節點看到的事務在SLAVE節點並未看到,就會發生事務丟失的情況。

對於第二種 AFTER_SYNC 方式,當事務被SLAVE確認後MASTER在儲存引擎層面進行提交事務後,所有使用者端才能看到事務造成的資料更改。因此,所有使用者端在MASTER上同一時刻看到是相同的資料。
當MASTER節點crash的情況下,所有在MASTER上提交的事務都被複制到SLAVE(儲存到中繼紀錄檔中)。 MASTER伺服器意外crash。此刻HA進行故障轉移到SALVE後,使用者端看到的資料是無失真的,因為SLAVE是最新的。
注意,然而,在這種情況下,MASTER不能直接恢復使用,因為它的二進位制紀錄檔可能包含未提交的事務,此刻當二進位制紀錄檔恢復並用於業務需求時,可能會導致與SLAVE的衝突。

四、如何開啟半同步

方式1:半同步以外掛的形式存在,咱們可以直接線上開啟即可(本次採用這次方式)

主節點開啟:

[root@GreatSQL][(none)]>INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
Query OK, 0 rows affected (0.02 sec)

從節點開啟:

[root@GreatSQL][(none)]>INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK, 0 rows affected (0.02 sec)

 PS:一般情況下所有節點都同步部署master和slave外掛,這樣故障切換的時候會比較方便處理

方式2:在my.cnf設定中進行開啟

 主從節點都同步設定開啟:

plugin-load="rpl_semi_sync_master=semisync_master.so;rpl_sync_slave=semisync_slave.so"
rpl_semi_sync_master_enabled=1
rpl_semi_sync_slave_enabled=1

五、檢視外掛開啟情況

方式1:查詢plugin

主節點檢視:

[root@GreatSQL][test]>show plugins;
| rpl_semi_sync_master | ACTIVE | REPLICATION | semisync_master.so | GPL |

從節點檢視:

[root@GreatSQL][(none)]>show plugins;
| rpl_semi_sync_slave | ACTIVE | REPLICATION | semisync_slave.so | GPL |

方式二:查詢information_schema.plugins資訊更全面

主節點資訊:

(Thu Feb 17 03:03:12 2022)[root@GreatSQL][(none)]>select * from information_schema.plugins where plugin_name like "%semi%"G;
*************************** 1. row ***************************
           PLUGIN_NAME: rpl_semi_sync_master
        PLUGIN_VERSION: 1.0
         PLUGIN_STATUS: ACTIVE
           PLUGIN_TYPE: REPLICATION
   PLUGIN_TYPE_VERSION: 4.0
        PLUGIN_LIBRARY: semisync_master.so
PLUGIN_LIBRARY_VERSION: 1.10
         PLUGIN_AUTHOR: Oracle Corporation
    PLUGIN_DESCRIPTION: Semi-synchronous replication master
        PLUGIN_LICENSE: GPL
           LOAD_OPTION: ON
1 row in set (0.00 sec)

ERROR:
No query specified

# 從節點資訊
(Thu Feb 17 16:05:19 2022)[root@GreatSQL][(none)]>select * from information_schema.plugins where plugin_name like "%semi%"G;
*************************** 1. row ***************************
           PLUGIN_NAME: rpl_semi_sync_slave
        PLUGIN_VERSION: 1.0
         PLUGIN_STATUS: ACTIVE
           PLUGIN_TYPE: REPLICATION
   PLUGIN_TYPE_VERSION: 4.0
        PLUGIN_LIBRARY: semisync_slave.so
PLUGIN_LIBRARY_VERSION: 1.10
         PLUGIN_AUTHOR: Oracle Corporation
    PLUGIN_DESCRIPTION: Semi-synchronous replication slave
        PLUGIN_LICENSE: GPL
           LOAD_OPTION: ON
1 row in set (0.00 sec

六、開啟半同步功能

因為上面是線上安裝外掛的,所以外掛安裝完成後,服務還要啟動一下

主節點啟用半同步複製:

[root@GreatSQL][test]>SET GLOBAL rpl_semi_sync_master_enabled = on;
Query OK, 0 rows affected (0.00 sec)

 從節點啟用半同步複製:

t@GreatSQL][(none)]>SET GLOBAL rpl_semi_sync_slave_enabled = on;
Query OK, 0 rows affected (0.00 sec)

以上設定完成後,從節點重啟IO執行緒

(Mon Feb 14 15:19:58 2022)[root@GreatSQL][(none)]>
(Mon Feb 14 15:19:58 2022)[root@GreatSQL][(none)]>STOP SLAVE IO_THREAD;
Query OK, 0 rows affected, 1 warning (0.01 sec)

(Mon Feb 14 15:21:41 2022)[root@GreatSQL][(none)]>START SLAVE IO_THREAD;
Query OK, 0 rows affected, 1 warning (0.01 sec)

七、檢視半同步是否執行

 主節點:

[root@GreatSQL][test]>show status like 'Rpl_semi_sync_master_status';
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | ON    |
+-----------------------------+-------+
1 row in set (0.00 sec)

 從節點:

[root@GreatSQL][(none)]>show status like 'Rpl_semi_sync_slave_status';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.01 sec)

檢視主節點error.log,可以看出來從節點已經啟用半同步複製了

# 關鍵資訊 Start semi-sync binlog_dump to slave (server_id: 3306)
2022-02-14T02:16:35.411061-05:00 13 [Note] [MY-010014] [Repl] While initializing dump thread for slave with UUID <652ade08-8b1c-11ec-9f62-00155dcff90a>, found a zombie dump thread with the same UUID. Master is killing the zombie dump thread(12).
2022-02-14T02:16:35.411236-05:00 13 [Note] [MY-010462] [Repl] Start binlog_dump to master_thread_id(13) slave_server(3306), pos(, 4)
2022-02-14T02:16:35.411263-05:00 13 [Note] [MY-011170] [Repl] Start asynchronous binlog_dump to slave (server_id: 3306), pos(, 4).
2022-02-14T02:16:35.411419-05:00 12 [Note] [MY-011171] [Repl] Stop asynchronous binlog_dump to slave (server_id: 3306).
2022-02-14T02:19:33.913084-05:00 9 [Note] [MY-011130] [Repl] Semi-sync replication initialized for transactions.
2022-02-14T02:19:33.913133-05:00 9 [Note] [MY-011142] [Repl] Semi-sync replication enabled on the master.
2022-02-14T02:19:33.913638-05:00 0 [Note] [MY-011166] [Repl] Starting ack receiver thread.
2022-02-14T02:21:46.899725-05:00 14 [Note] [MY-010014] [Repl] While initializing dump thread for slave with UUID <652ade08-8b1c-11ec-9f62-00155dcff90a>, found a zombie dump thread with the same UUID. Master is killing the zombie dump thread(13).
2022-02-14T02:21:46.899894-05:00 14 [Note] [MY-010462] [Repl] Start binlog_dump to master_thread_id(14) slave_server(3306), pos(, 4)
2022-02-14T02:21:46.899953-05:00 14 [Note] [MY-011170] [Repl] Start semi-sync binlog_dump to slave (server_id: 3306), pos(, 4).

以上,MySQL半同步複製搭建完畢!

八、半同步引數資訊

主節點引數資訊:

[root@GreatSQL][test]>show variables like '%Rpl%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_read_size                             | 8192       |
| rpl_semi_sync_master_enabled              | ON         |
| rpl_semi_sync_master_timeout              | 10000      |
| rpl_semi_sync_master_trace_level          | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1          |
| rpl_semi_sync_master_wait_no_slave        | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
| rpl_stop_slave_timeout                    | 31536000   |
+-------------------------------------------+------------+
8 rows in set (0.00 sec)

部分引數簡單說明:

 從節點引數資訊:

[root@GreatSQL][test]>show variables like '%Rpl%';
+---------------------------------+----------+
| Variable_name                   | Value    |
+---------------------------------+----------+
| rpl_read_size                   | 8192     |
| rpl_semi_sync_slave_enabled     | ON       |
| rpl_semi_sync_slave_trace_level | 32       |
| rpl_stop_slave_timeout          | 31536000 |
+---------------------------------+----------+
4 rows in set (0.00 sec)

部分引數簡單說明:

九、半同步狀態資訊

主節點檢視:

[root@GreatSQL][test]> show status like '%Rpl_semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 0     |
| Rpl_semi_sync_master_no_times              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
| Rpl_semi_sync_master_tx_wait_time          | 0     |
| Rpl_semi_sync_master_tx_waits              | 0     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 0     |
+--------------------------------------------+-------+
14 rows in set (0.00 sec)

部分引數用途簡要說明:

從節點轉態資訊:

show global status like '%semi%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.00 sec)

引數簡單說明:

十、測試一下半同步的同步情況

  • 半同步是否會降級為非同步複製?是會的。
  • 當半同步複製發生超時時(由rpl_semi_sync_master_timeout引數控制,單位是毫秒,預設為10000,即10s),會暫時關閉半同步複製,轉而使用非同步複製。
  • 當MASTER DUMP 執行緒傳送完一個事務的所有事件之後,如果在rpl_semi_sync_master_timeout內,收到了從庫的響應,則主從又重新恢復為半同步複製。

1.從節點暫時先關掉IO執行緒

[root@GreatSQL][(none)]>STOP SLAVE IO_THREAD;
Query OK, 0 rows affected, 1 warning (0.02 sec)

2.主節點寫入幾條測試資料

[root@GreatSQL][test]>insert into ptype values(4,'4','4'),(5,'5','5'),(6,'6','6');
Query OK, 3 rows affected (0.02 sec)

3.等待10s後檢視複製狀態,半同步已經關掉了

[root@GreatSQL][test]>show status like 'Rpl_semi_sync_slave_status';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | OFF   |
+----------------------------+-------+
1 row in set (0.00 sec)

4.從節點開啟IO執行緒

[root@GreatSQL][(none)]>START SLAVE IO_THREAD;
Query OK, 0 rows affected, 1 warning (0.02 sec)

5.再次檢視複製狀態,半同步複製自動開啟了

t@GreatSQL][test]>show status like 'Rpl_semi_sync_slave_status';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.00 sec)

到此這篇關於MySQL主從複製之半同步semi-sync replication的文章就介紹到這了,更多相關MySQL半同步semi-sync replication內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com