請不要用SECONDS_BEHIND_MASTER來衡量MYSQL主備的延遲時間【轉】

来源:https://www.cnblogs.com/sz-wenbin/archive/2019/11/01/11775297.html
-Advertisement-
Play Games

MySQL 本身通過 show slave status 提供了 Seconds_Behind_Master ,用於衡量主備之間的複製延遲,但是 今天碰到了一個場景,發現 Seconds_Behind_Master 為 0 , 備庫的 show slave status 顯示IO/SQL 線程都是正 ...


MySQL 本身通過 show slave status 提供了 Seconds_Behind_Master ,用於衡量主備之間的複製延遲,但是 今天碰到了一個場景,發現 Seconds_Behind_Master 為 0 , 備庫的 show slave status 顯示IO/SQL 線程都是正常的 , MySQL 的主庫上的變更卻長時間無法同步到備庫上。如果沒有人為干預,直到一個小時以後, MySQL 才會自動重連主庫,繼續複製主庫的變更。

影響範圍: MySQL , Percona , MariaDB 的所有版本。

雖然這種場景非常特殊,遇到的概率並不高,但是個人覺得有必要提醒一下使用 MySQL 的 DBA 們。通過對這個場景的分析,也有助於我們更加深入的理解 MySQL replication 重試機制。

一、重現步驟

搭建主備的複製,臨時斷開主庫的網路,並 kill 掉主庫 MySQL 的 binlog dump 線程。

此時觀察備庫的複製情況, show slave status 中:

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

Seconds_Behind_Master: 0

但是此時你把網路恢復以後,在主庫做任何變更,備庫都無法獲得數據更新了。而且備庫上的show slave status 顯示: IO 線程 SQL 線程一切正常,複製延遲一直是 0 。

一切正常,普通的監控軟體都不會發現備庫有數據延遲。

二、原理分析

MySQL 的 Replication 是區別於其他資料庫很關鍵的地方。也是可擴展性和高可用的基礎。它本身已經非常智能化,只需要我們調用 Change Master 指定 Binlog 文件名和偏移位置就可以搭建從主庫到備庫的複製關係。

MySQL 複製 線程 會自動將目前複製位置記錄下來,在主備複製中斷的時候自動連上主庫,並從上次中斷的位置重新開始複製。這些操作都是全自動化的,不需要人為的干預。這給了 MySQL DBA 帶來了很多便利,同時卻也隱藏了很多細節。

要真正的理解前面問題的真相以及怎麼解決這個問題,我們還是需要真正的理解 MySQL  複製的原理。

2.1“推”還是“拉”

首先, MySQL 的複製是“推”的,而不是“拉”的。“拉”是指 MySQL 的備庫不斷的迴圈詢問主庫是否有數據更新,這種方式資源消耗多,並且效率低。“推”是指 MySQL 的主庫在自己有數據更新的時候推送這個變更給備庫,這種方式只有在數據有變更的時候才會發生交互,資源消耗少。如果你是程式員出身,你一定會選擇“推”的方式。

那麼 MySQL 具體是怎麼“推”的列,實際上備庫在向主庫申請數據變更記錄的時候,需要指定從主庫Binlog 的哪個文件 ( MASTER_LOG_FILE ) 的具體多少個位元組偏移位置 ( MASTER_LOG_POS ) 。對應的,主庫會啟動一個 Binlog dump 的線程,將變更的記錄從這個位置開始一條一條的發給備庫。備庫一直監聽主庫過來的變更,接收到一條,才會在本地應用這個數據變更。

2.2 原因解析

從上面的分析,我們可以大致猜到為什麼 show slave status 顯示一切正常,但是實際上主庫的變更都無法同步到備庫上來:

出現問題的時候, Binlog dump 程式被我們 kill 掉了。作為監聽的一方,備庫一直沒有收到任何變更,它會認為主庫上長時間沒有任何變更,導致沒有變更數據推送過來。備庫是無法判斷主庫上對應的Binlog dump 線程 到底是意外終止了,還是長時間沒有任何數據變更的。所以,對這兩種情況來說,備庫都顯示為正常。

當然, MySQL 會儘量避免這種情況。比如:

l  在 Binlog dump 被 kill 掉時通知備庫 線程 被 kill 掉了。所以我們重現時需要保證這個通知發送不到備庫,也就是說該問題重現的關鍵在於 Binlog dump 被 kill 的消息由於網路堵塞或者其他原因無法發送到備庫。

l  備庫如果長時間沒有收到從主庫過來的變更,它會每隔一段時間重連主庫。

2.3 問題避免

基於上面的分析,我們知道 MySQL 在這種情況下確實無法避免,那麼我們可以有哪些辦法可以避開列:

1.  被動處理:修改延遲的監控方法,發現問題及時處理。

2.  主動預防:正確設置 --master-retry-count ,  --master-connect-retry ,  --slave-net-timeout 複製重試參數。

l  被動處理

MySQL 的延遲監控大部分直接採集 show slave status 中的  Seconds_Behind_Master 。這種情況下,Seconds_Behind_Master 就無法用來真實的衡量主備之間的複製延遲了。我們建議通過在主庫輪詢插入時間信息,並通過複製到備庫的時間差來獲得主備延遲的方案。 Percona 提供了一種類似的方案 pt-heartbeat(在master上部署,實施監控從的延遲) 。

發現這個問題以後,我們只需要 stop slave; start slave; 重啟複製就能解決這個問題。 

l  主動預防

MySQL 可以指定三個參數,用於複製線程重連主庫: --master-retry-count ,  --master-connect-retry ,  --slave-net-timeout 。

其中 master-connect-retry 和 master-retry-count 需要在 Change Master 搭建主備複製時指定,而slave-net-timeout 是一個全局變數,可以在 MySQL 運行時線上設置。

具體的重試策略為:備庫過了 slave-net-timeout 秒還沒有收到主庫來的數據,它就會開始第一次重試。然後每過 master-connect-retry 秒,備庫會再次嘗試重連主庫。直到重試了 master-retry-count 次,它才會放棄重試。如果重試的過程中,連上了主庫,那麼它認為當前主庫是好的,又會開始 slave-net-timeout 秒的等待。

slave-net-timeout 的預設值是 3600 秒(mysql版本<= 5.7.6), master-connect-retry 預設為 60 秒, master-retry-count預設為 86400 次。也就是說,如果主庫一個小時都沒有任何數據變更發送過來,備庫才會嘗試重連主庫。這就是為什麼在我們模擬的場景下,一個小時後,備庫才會重連主庫,繼續同步數據變更的原因。

這樣的話,如果你的主庫上變更比較頻繁,可以考慮將 slave-net-timeout 設置的小一點,避免主庫Binlog dump 線程 終止了,無法將最新的更新推送過來。

當然 slave-net-timeout 設置的過小也有問題,這樣會導致如果主庫的變更確實比較少的時候,備庫頻繁的重新連接主庫,造成資源浪費。

查看設置情況:show variables like 'slave_net_timeout';

官網的預設配置:

PropertyValue
Command-Line Format --slave-net-timeout=#
System Variable slave_net_timeout
Scope Global
Dynamic Yes
Type Integer
Default Value (>= 5.7.7) 60
Default Value (<= 5.7.6) 3600
Minimum Value 1

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

-Advertisement-
Play Games
更多相關文章
  • [toc] 1. 資料庫是什麼 存數據的倉庫 2. 為什麼使用資料庫 1. 管理大量數據 2. 支持併發操作 3. 支持高級的操作,比如分組,鏈表等 3. 資料庫的分類 1. 關係型資料庫 表結構存儲,對每一列的數據的類型會有約束,數據存在硬碟中 Mysql(免費,企業用的多),maridb,Sql ...
  • 1.環境變數設置[oracle]$cat >> /home/oracle/.bash_profile > /home/oracle/.bashrc > $ORACLE_HOME/sqlplus/admin/glogin.sql " set time on set timing on set page... ...
  • redis沒有實現訪問控制這個功能,但是它提供了一個輕量級的認證方式,可以編輯redis.conf配置來啟用認證。 1、初始化Redis密碼: 在配置文件中有個參數: requirepass 這個就是配置redis訪問密碼的參數; 比如 requirepass 123456; (Ps:需重啟Redi ...
  • 概述 StreamingListener 是針對spark streaming的各個階段的事件監聽機制。 StreamingListener介面 自定義StreamingListener 功能:監控批次處理時間,若超過閾值則告警,每次告警間隔2分鐘 應用 訂閱關註微信公眾號《大數據技術進階》,及時獲 ...
  • 前言: Docker 是一個開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的鏡像中,然後發佈到任何流行的Linux或Windows機器上。近幾年來,Docker 在國內發展的如火如荼,特別是在互聯網公司, Docker 的使用是十分普遍的,極大提高了應用的維護效率,降低了雲計算 ...
  • 前言:本人遇到一個需求,需要在MySql的欄位中截取一段字元串中的特定字元,類似於正則表達式的截取,苦於沒有合適的方法,百度之後終於找到一個合適的方法:substring_index('www.sqlstudy.com.cn', '.', -2) 強烈推薦該方法獲取含有特定字元的數據。 substr ...
  • 參考官方文檔 Database Quick Installation Guide for Linux x86-64,https://docs.oracle.com/cd/E11882_01/install.112/e24326/toc.htmhttps://www.cnblogs.com/nucdy... ...
  • 昨天在學習oracle存儲過程的時候,寫了一個存儲過程的demo,語句是這樣的: 想法是通過表的varchar(20)類型欄位找到number類型欄位,然後更改number類型的欄位。表結構如下: 將存儲過程調用,出現結果如下: 出現錯誤 :該存儲過程無效。 what?明明剛剛建立的存儲過程啊。然後 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...