關于SECONDS_BEHIND_MASTER:
這個參數(shù)在我們使用show slave status的時候會看到,這個參數(shù)可用于參考從庫同步主庫的一個進度,當為0時,可認為主從數(shù)據(jù)已完全同步,但需要注意的是,這個參數(shù)只適合作為一個參考,并不能完全依賴這個參數(shù)判斷從庫進度是否已追上了主庫,說白了,不要用SECONDS_BEHIND_MASTER來衡量MYSQL主備的延遲時間
曾有網(wǎng)友遇到過以下場景:
Seconds_Behind_Master 為 0 , 備庫的 show slave status 顯示 IO/SQL 線程都是正常的 , MySQL 的主庫上的變更卻長時間無法同步到備庫上。如果沒有人為干預,直到一個小時以后(可設置重連時間), MySQL 才會自動重連主庫,繼續(xù)復制主庫的變更。
而這個問題的影響范圍是:MySQL , Percona , MariaDB 的所有版本。
這個問題遇到的概率并不高,但還是有必要記錄一下。
一、問題重現(xiàn)步驟:
搭建主備的復制,臨時斷開主庫的網(wǎng)絡,并 kill 掉主庫 MySQL 的 binlog dump 線程。
此時觀察備庫的復制情況, show slave status 中:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Seconds_Behind_Master: 0
但是此時你把網(wǎng)絡恢復以后,在主庫做任何變更,備庫都無法獲得數(shù)據(jù)更新了。而且備庫上的show slave status 顯示: IO 線程 SQL 線程一切正常,復制延遲一直是 0 。
一切正常,普通的監(jiān)控軟件都不會發(fā)現(xiàn)備庫有數(shù)據(jù)延遲。
原理分析:
MySQL 的 Replication 是區(qū)別于其他數(shù)據(jù)庫很關鍵的地方。也是可擴展性和高可用的基礎。它本身已經(jīng)非常智能化,只需要我們調(diào)用 Change Master 指定 Binlog 文件名和偏移位置就可以搭建從主庫到備庫的復制關系。
MySQL 復制 線程 會自動將目前復制位置記錄下來,在主備復制中斷的時候自動連上主庫,并從上次中斷的位置重新開始復制。這些操作都是全自動化的。
關于MySQL主從是“推”還是“拉”
首先說明一下,MySQL主從是使用“推”的方式實現(xiàn)的:
關于推拉說明:
推:主庫上數(shù)據(jù)更新時,將消息推送給從庫,然后從庫再進行更新
拉:從庫會通過輪詢的方式不斷查詢主庫是否更新了數(shù)據(jù),資源消耗巨大
問題分析:
當我們kill掉主庫的進程的時候,主庫就不能向從庫推送數(shù)據(jù)消息,導致從庫一直收不到數(shù)據(jù)消息而不會更新數(shù)據(jù),從庫如果長時間沒有收到主庫發(fā)過來的變更,,從庫會每隔一段時間重連主庫
問題避免:
修改延遲的監(jiān)控方法:
正確設置:--master-connect-retry ,--slave-net-timeout ,--master_heartbeat_period重試參數(shù)
slave_net_timeout:
MySQL主從復制的時候, 當Master和Slave之間的網(wǎng)絡中斷,但是Master和Slave無法察覺的情況下(比如防火墻或者路由問題)。Slave會等待slave_net_timeout設置的秒數(shù)后,才能認為網(wǎng)絡出現(xiàn)故障,然后才會重連并且追趕這段時間主庫的數(shù)據(jù)。
備庫過了 slave-net-timeout 秒還沒有收到主庫來的數(shù)據(jù),它就會開始第一次重試。然后每過 master-connect-retry 秒,備庫會再次嘗試重連主庫,直到--master-retry-count次后才結束。
--master-retry-count(該參數(shù)在mysql5.6.1及其后續(xù)版本廢除)。MASTER_RETRY_COUNT = 0表示重連次數(shù)無限制。
master_heartbeat_period參數(shù):
設置復制心跳的周期,取值范圍為0 到 4294967秒。精確度可以達到毫秒,最小的非0值是0.001秒。心跳信息由master在主機binlog日志文件在設定的間隔時間內(nèi)沒有收到新的事件時發(fā)出,以便slave知道m(xù)aster是否正常。
slave連接到master后,該參數(shù)可通過mysql.slave_master_info表查看。
slave_net_timeout 的默認是 3600,也就是一小時。也就是說,在之前的情況下,Slave 要延誤 1 小時后才會嘗試重連。而在沒有設置 master_heartbeat_period 時,將 slave_net_timeout 設得很短會造成 Master 沒有數(shù)據(jù)更新時頻繁重連。
mysql> stop slave;
mysql> change master to master_heartbeat_period = 10;
mysql> set global slave_net_timeout = 25;
mysql> start slave;
Master 在沒有數(shù)據(jù)的時候,每 10 秒發(fā)送一個心跳包。這樣 Slave 就能知道 Master 是不是還正常
mysql> show status like 'slave%';
+----------------------------+---------------------+
| Variable_name | Value |
+----------------------------+---------------------+
| Slave_heartbeat_period | 10.000 |
| Slave_last_heartbeat | 2015-01-08 10:28:16 |
| Slave_open_temp_tables | 0 |
| Slave_received_heartbeats | 1645 |
| Slave_retried_transactions | 0 |
| Slave_running | ON |
+----------------------------+---------------------+
參考文章:
http://chenxy.blog.51cto.com/729966/1361558
http://blog.csdn.net/JesseYoung/article/details/42914577