MySQL半同步複製原理與配置

来源:https://www.cnblogs.com/hc2012/archive/2018/04/16/8857745.html
-Advertisement-
Play Games

MySQL主從複製複製預設是非同步的,非同步複製可以提供最佳的性能, 主庫把binlog日誌發送給從庫,然後將結果返回給客戶端,並不會驗證從庫是否接收完畢。這也就意味著有可能出現當主庫或從庫發生故障的時候,從庫沒有接收到主庫發送過來的binlog日誌,導致主庫和從庫的數據不一致,甚至在恢復時造成數據的丟... ...


一 、非同步、同步和半同步複製概念

  非同步複製(Asynchronous replication),MySQL預設的複製是非同步的,主庫在執行完客戶端提交的事務後會立即將結果返給給客戶端,並不關心從庫是否已經接收並處理。原理最簡單,性能最好,但是主從之間數據不一致的概率很大。

  全同步複製(Fully synchronous replication),指當主庫執行完一個事務,所有的從庫都執行了該事務才返回給客戶端。因為需要等待所有從庫執行完該事務才能返回,所以全同步複製的性能必然會收到嚴重的影響。

  半同步複製(Semisynchronous replication),介於非同步複製和全同步複製之間,主庫在執行完客戶端提交的事務後不是立刻返回給客戶端,而是等待至少一個從庫接收到並寫到relay log中才返回給客戶端。相對於非同步複製,半同步複製犧牲了一定的性能,提高了數據的安全性。

二、半同步複製原理

  預設情況下,MySQL的主從複製是非同步的,非同步複製可以提供最佳的性能, 主庫把binlog日誌發送給從庫,然後將結果返回給客戶端,並不會驗證從庫是否接收完畢。這也就意味著有可能出現當主庫或從庫發生故障的時候,從庫沒有接收到主庫發送過來的binlog日誌,導致主庫和從庫的數據不一致,甚至在恢復時造成數據的丟失。

  為瞭解決上述出現的問題,MySQL 5.5 引入了一種半同步複製模式。該模式可以確保從庫接收完主庫發送的binlog日誌文件並寫入到自己的中繼日誌relay log里,然後會給主庫一個反饋,告訴主庫已經接收完畢,這時主庫才返回結果給客戶端告知操作完成。當出現從庫響應超時情況時,主庫會暫時切換到非同步複製模式,直到下一次同步沒有超時轉為半同步複製為止。(master的dump線程除了發送binlog數據到slave,還承擔了接收slave的ack工作。如果出現異常,沒有收到ack,那麼將自動降為普通的非同步複製,直到異常修複)

 三、半同步複製--MySQL5.7版

MySQL5.5半同步複製帶來的新問題:

  1)如果有故障發生,會切換為非同步的複製。 那麼從庫出現數據不一致的幾率會減少,並不是完全消失。

  2)主機dump線程承擔的工作變多了(發送binlog數據到slave,接收slave的ack。兩者是串列的,dump線程必須等待slave返回ack之後才會傳送下一個events事務。dump線程是整個半同步提高性能的瓶頸),這樣顯然會降低整個資料庫的性能。

  3)在MySQL 5.5和5.6使用after_commit的模式下, 如果slave沒有收到事務,也就是還沒有寫入到relay log之前,網路出現異常或者不穩定,此時剛好master掛了,系統切換到從庫,兩邊的數據就會出現不一致,slave會少一個事務的數據。

  在此情況下,MySQL5.7的半同步複製技術升級為全新的Loss-less Semi-Synchronous Replication架構,新版本的semi sync增加了rpl_semi_sync_master_wait_point參數, 來控制半同步模式下主庫在返回結果給會話之前提交事務的方式。

該參數有兩個值:

  1)AFTER_COMMIT(5.5,5.6預設值)

  master將每個事務寫入binlog之後,先提交事務,然後將binlog數據傳遞到slave並刷新到磁碟(relay log)。接著master等待slave反饋收到relay log,只有收到ack之後master才將commit OK結果反饋給客戶端。如圖一所示。

                  

  2)AFTER_SYNC(5.7預設值)

  master將每個事務寫入binlog,然後將binlog數據傳遞到slave並刷新到磁碟(relay log)。master等待slave反饋接收到relay log的ack之後,再提交事務並且返回commit OK結果給客戶端。即使主庫crash了,所有在主庫上已經提交的事務都能保證已經同步到slave的relay log中。如圖二所示。

  MySQL5.7的半同步複製引入after_sync模式,主要是解決了after_commit導致的主庫crash後主從之間數據不一致的問題。在引入after_sync模式後,所有提交的數據都已經被覆制,故障切換時數據一致性將得到提升。(另外,在5.7版本的semi sync框架中,獨立出一個ack collector thread,專門用於接收slave的反饋信息。這樣master上有兩個線程獨立工作,可以同時發送binlog到slave,和接收slave的反饋)

四、半同步複製的安裝

  開啟半同步複製,必須是MySQL5.5以上版本並且已經搭建好普通的主從非同步複製。此處以MySQL5.5版本演示,如下所示:

1、安裝半同步插件

#半同步功能主要是下麵兩個插件
[root@master ~]# ls -l /application/mysql/lib/plugin/
......
-rwxr-xr-x 1 mysql mysql 173396 Sep 15  2017 semisync_master.so
-rwxr-xr-x 1 mysql mysql  94066 Sep 15  2017 semisync_slave.so

#分別在主從庫載入上面兩個插件
master:
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
slave:
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';

#查看插件是否載入成功,有兩種方法
1)mysql> show plugins;
| rpl_semi_sync_master     | ACTIVE   | REPLICATION        | semisync_master.so | GPL     |

2)mysql> select plugin_name,plugin_status from information_schema.plugins where plugin_name like '%semi%';
+----------------------+---------------+
| plugin_name          | plugin_status |
+----------------------+---------------+
| rpl_semi_sync_master | ACTIVE        |
+----------------------+---------------+
1 row in set (0.10 sec)

2、開啟半同步複製

  在安裝完插件後,半同步複製預設是關閉的,這時需設置參數來開啟半同步。

mater:
mysql> set global rpl_semi_sync_master_enabled = 1;
slave:
mysql> set global rpl_semi_sync_slave_enabled = 1;

#以上的啟動方式是在命令行操作,是臨時生效的;永久生效需將如下設置寫在配置文件中。 master: plugin
-load = rpl_semi_sync_master=semisync_master.so #此項可以讓plugin在任何時候都被mysql載入 rpl_semi_sync_master_enabled = 1 slave: plugin-load = rpl_semi_sync_slave=semisync_slave.so rpl_semi_sync_slave_enabled = 1
#在有的高可用架構下,master和slave需同時啟動,以便在切換後能繼續使用半同步複製 plugin
-load = "rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so" rpl-semi-sync-master-enabled = 1 rpl-semi-sync-slave-enabled = 1

3、重啟slave上的IO線程使半同步生效

mysql> stop slave io_thread;

mysql> start slave io_thread;
#如果沒有重啟,則預設還是非同步複製,重啟後,slave會在master上註冊為半同步複製的slave角色。

#查看半同步是否在運行
master:
mysql> show status like 'Rpl_semi_sync_master_status';
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | ON    |
+-----------------------------+-------+

slave:
mysql> show status like 'Rpl_semi_sync_slave_status';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+

4、半同步複製測試

master:
mysql> create database db;
mysql> use db
Database changed
mysql> create table t1(id int);
mysql> insert into t1 values(1);
mysql> select * from t1;
+------+
| id   |
+------+
|    1 |
+------+
1 row in set (0.00 sec)
slave:
mysql> select * from db.t1;
+------+
| id   |
+------+
|    1 |
+------+
1 row in set (0.00 sec)

#可以看到數據很快同步到了從庫上,下麵關閉io_thread測試
slave:
mysql> stop slave io_thread;
Query OK, 0 rows affected (0.00 sec)
master:
mysql> insert into t1 values(2);   #此處有一個10s的超時等待時間,超時後轉為非同步插入
Query OK, 1 row affected (10.11 sec)
mysql> show status like 'Rpl_semi_sync_master_status';   #半同步已失效
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | OFF   |
+-----------------------------+-------+
slave:
mysql> show status like 'Rpl_semi_sync_slave_status';   #從庫的半同步也失效
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | OFF   |
+----------------------------+-------+
1 row in set (0.01 sec)
slave:
mysql> start slave io_thread;   #從庫開啟io線程
Query OK, 0 rows affected (0.00 sec)
master:
mysql> show status like 'Rpl_semi_sync_master_status';   #又重新轉為半同步複製
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | ON    |
+-----------------------------+-------+
1 row in set (0.00 sec)
slave:
mysql> select * from db.t1;   #從庫上數據已同步 
+------+
| id |
+------+
| 1 |
| 2 |
+------+
2 rows in set (0.00 sec)

5、其他說明

  1)環境變數

mysql> show variables like '%semi%';
+------------------------------------+-------+
| Variable_name                      | Value |
+------------------------------------+-------+
| rpl_semi_sync_master_enabled       | ON    |
| 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)

rpl_semi_sync_master_enabled=ON  表示開啟半同步複製

rpl_semi_sync_master_timeout=10000  單位為毫秒,即10秒超時,將切換為非同步複製

rpl_semi_sync_master_wait_no_slave  表示是否允許master每個事務都要等待slave接收確認。預設為ON,每一個事務都會等待,如果slave crash後,當slave追趕上master的日誌時,可以自動的切換為半同步方式。如果為OFF,則slave追趕上後,也不會採用半同步的方式複製了,需要手工配置。

rpl_semi_sync_master_trace_level=32  表示用於開啟半同步複製時的調試級別,預設32

補充:

rpl_semi_sync_master_wait_for_slave_count  MySQL 5.7.3引入的,該變數設置主庫需要等待多少個slave應答,才能返回給客戶端,預設為1。

  2)狀態變數

mysql> show status like '%semi%';
+--------------------------------------------+--------+
| Variable_name                              | Value  |
+--------------------------------------------+--------+
| Rpl_semi_sync_master_clients               | 1      |
| Rpl_semi_sync_master_net_avg_wait_time     | 21014  |
| Rpl_semi_sync_master_net_wait_time         | 126089 |
| Rpl_semi_sync_master_net_waits             | 6      |
| Rpl_semi_sync_master_no_times              | 1      |
| Rpl_semi_sync_master_no_tx                 | 1      |
| Rpl_semi_sync_master_status                | ON     |
| Rpl_semi_sync_master_timefunc_failures     | 0      |
| Rpl_semi_sync_master_tx_avg_wait_time      | 2186   |
| Rpl_semi_sync_master_tx_wait_time          | 4373   |
| Rpl_semi_sync_master_tx_waits              | 2      |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0      |
| Rpl_semi_sync_master_wait_sessions         | 0      |
| Rpl_semi_sync_master_yes_tx                | 4      |
+--------------------------------------------+--------+
14 rows in set (0.00 sec)

Rpl_semi_sync_master_status  標記master現在是否是半同步複製狀態

Rpl_semi_sync_master_clients  記錄支持半同步的slave的個數

Rpl_semi_sync_master_yes_tx  master成功接收到slave的回覆的次數

Rpl_semi_sync_master_no_tx  master沒有收到slave的回覆而提交的次數

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、概述 以前看到這樣一句話,語言只是工具,演算法才是程式設計的靈魂。的確,演算法在電腦科學中的地位真的很重要,在很多大公司的筆試面試中,演算法掌握程度的考察都占據了很大一部分。不管是為了面試還是自身編程能力的提升,花時間去研究常見的演算法還是很有必要的。下麵是自己對於演算法這部分的學習總結。 演算法簡介 算 ...
  • 為了便於描述,文中涉及到的代碼部分都是用Java語言編寫的,其實Java本身對常見的幾種數據結構,線性表、棧、隊列等都提供了較好的實現,就是我們經常用到的Java集合框架,有需要的可以閱讀這篇文章。Java - 集合框架完全解析 一、線性表 線性表是最常用且最簡單的一種數據結構,它是n個數據元素的有 ...
  • Linux-CentOS5/6啟動流程 ...
  • centos6.8 鏈接:https://pan.baidu.com/s/1TjCYXzijMzfpiZ9Z-D1Qhg 密碼:7mvn 2.1 新建虛擬機 1 1 2.2 選中稍後安裝操作系統(先把虛擬機建好先) 2 2 2.3 設置此虛擬機安裝哪種操作系統 3 3 2.4 設置虛擬機的名稱和位置 ...
  • 本文為mariadb官方手冊:CREATE TRIGGER的譯文。 原文:https://mariadb.com/kb/en/create-trigger/我提交到MariaDB官方手冊的譯文:https://mariadb.com/kb/zh-cn/create-trigger/ 回到Linux系 ...
  • Neo4j資料庫有兩個版本:社區版和商業版,社區版是開源並且免費的,社區版與商業版功能上沒有什麼區別,不同的是,社區版只能單機使用,商業版可以做分散式集群。單機版最大可以存儲10億個位元組。 Neo4j針對不同的操作系統,提供不同的安裝包,下載官網:https://neo4j.com/download ...
  • 空值操作: null表示空的意思。 一、情況: 1:表中的任何欄位預設情況下都可以為null值。 2:not null表示非空,是一種約束 設置為非空約束的欄位,必須有有效值,不能為空。 3:插入數據時 reg:insert into emp(ename,empno) values(2001,'張三 ...
  • 一次資料庫作業 題目如下: Consider the following SQL table definitions: 1. Define sensible key constraints for these tables in SQL. Note: An olympic event (such a ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...