當機導致slave異常分析
線上一臺備份伺服器由於誤操作導致異常掉電,設定了開機自動啟動複製,重新啟動之後,檢視複製,報錯:
主鍵衝突, Slave SQL: Error 'Duplicate entry '5218036-4f8c3555-1e5f-4c8e-bed7-9c78d6ab8725' for key 'PRIMARY'' on query. Default database: .....
為何會報主鍵衝突,主鍵衝突,那就是說之前已經有同樣一條資料寫入到了slave,然後複製程式又寫一遍導致的,那為何會重寫一遍呢,要麼master重新寫入了,這點可以否決,因為是主鍵,master重寫也會失敗,壓根就不會傳送到slave來,要麼就是relay-log又重放了一遍導致,看來只能是這點了,每個故障都是有原因的。要處理一個問題,就需要把這個問題在心裡重現一遍,然後看看是哪個環節可能導致的問題。
下面來看看複製的原理,簡單描述如下:
master插入一條記錄,寫入binlog,slave 上IO程式從主庫獲取這條記錄的資訊並寫入relay-log,接著slave的SQL程式解析到這條記錄,並寫入到slave,完成一條記錄的複製。複製過程中會涉及到檔案有:
relay-log存放從主庫獲取到的二進位制日誌,
relay-log.info 存放slave SQL執行緒執行到了master的哪個檔案和pos以及relay-log檔案和pos位置,這個檔案由SQL執行緒負責更新
master.info 存放slave 獲取到了master的二進位制日誌檔案和pos位置,複製有關的資訊,master-host,port,user,passwd等等,這個檔案由IO執行緒負責更新
上述三個檔案的資訊都是不斷更新的,注意這裡是不斷更新而不是實時更新,這個更新的頻率由下面幾個引數決定,摘自官方文件:
# sync_relay_log_info
If the value of this variable is greater than 0,
a replication slave synchronizes its relay-log.info file to disk (using fdatasync()) after every sync_relay_log_info transactions.
A value of 1 is the generally the best choice.
The default value of sync_relay_log_info is 0,
which does not force any synchronization to disk by the MySQL server—in this case,
the server relies on the operating system to flush the relay-log.info file's contents from time to time as for any other file.
# sync_master_info
If the value of this variable is greater than 0,
a replication slave synchronizes its master.info file to disk (using fdatasync()) after every sync_master_info events.
The default value of sync_relay_log_info is 0 (recommended in most situations),
which does not force any synchronization to disk by the MySQL server;
in this case, the server relies on the operating system to flush the master.info file's contents from time to time as for any other file.
# sync_relay_log
If the value of this variable is greater than 0,
the MySQL server synchronizes its relay log to disk (using fdatasync()) after every sync_relay_log writes to the relay log.
There is one write to the relay log per statement if autocommit is enabled, and one write per transaction otherwise.
The default value of sync_relay_log is 0, which does no synchronizing to disk—in this case,
the server relies on the operating system to flush the relay log's contents from time to time as for any other file.
A value of 1 is the safest choice because in the event of a crash you lose at most one statement or transaction from the relay log.
However, it is also the slowest choice (unless the disk has a battery-backed cache, which makes synchronization very fast).
這幾個引數控制著上面三個檔案的更新頻率,0由作業系統cache控制relay.info和master.info的重新整理,N則表示N個事務後重新整理到磁碟,(和sync-binlog一樣)
預設都是0,都是依賴作業系統的重新整理來更新。檢視了出故障這臺slave,這幾個引數都是預設的。既然依賴作業系統的重新整理來更新,這就意味著有可能丟失資料,在異常掉電的情況下,作業系統cache來不及重新整理到磁碟,就會大導致slave複製資訊沒有及時重新整理到relay-log.info和master.info而丟失,也就是此時的relay-log.info,master.info是落後於複製執行緒的,複製資訊和disk存放的資訊不一致。這也是5.5版本複製稱為not crash safe的原因,5.6版本可以選擇採用表來存放複製資訊,稱為 crash safe,可以找時間驗證一下。
這裡還需要理解一點的是,如果slave設定了例項開啟時啟動複製的話,則會根據relay.info和master.info這兩個檔案來啟動複製。
透過上述幾點理解,那就很容易理解為何例項啟動後會報主鍵衝突了,master.info和relay-log.info 在掉電後,複製資訊沒有及時重新整理到磁碟,落後於slave複製。例項啟動後,自動啟動複製,mysql根據這兩個落後的檔案來啟動的複製,實際上就是將一些relay-log重放了,從而導致了主鍵衝突。既然是重放,都是主鍵操作,選擇跳過異常。
而要避免這個問題的話,可以將上述幾個引數設定為1,每處理一個slave event後就重新整理relay.info和master.info。這樣最多丟失一個event影響的記錄。
但是這幾個引數設定為1的話,對磁碟的效能還是有一定的消耗,每一個event都重新整理磁碟,必定對磁碟的訪問增加。和開啟sync-binlog道理一樣,這就需要在效能和安全之間做一個權衡。只要從庫和master配置差不多的話,配置為1的問題,對效能影響不大,畢竟master還為了安全還設定了sync-binlog=1。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22418990/viewspace-1309000/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL Bug導致異常當機的分析流程MySql
- A站大流量導致服務崩潰異常分析
- MySQL Slave異常關機的處理 (pt-slave-restart)MySqlREST
- MySQL Slave異常關機的處理MySql
- ORACLE 11.2.0.4 rac for linux 鏈路宕導致的單節點異常當機OracleLinux
- 華為交換機LLDP震盪導致網路異常
- 核心引數導致的備庫當機分析
- crontab導致CPU異常的問題分析及處理
- 故障分析 | MySQL : slave_compressed_protocol 導致 crashMySqlProtocol
- ORA-04031錯誤導致當機案例分析
- 記 Laravel Observer 導致 Redis 佇列異常LaravelServerRedis佇列
- 異常程式導致大量資源佔用
- cv::Mat轉QImage導致影像色彩異常
- 序列異常導致災備端應用異常處理一則
- 從原始碼分析JSONObject因版本差異導致toString格式異常問題原始碼JSONObject
- Oracle RAC啟動因CTSS導致的異常Oracle
- SCN異常增長導致資料庫異常關閉風險的防範資料庫
- 時區不一致導致spring應用異常Spring
- 【譯】Gradle 的依賴關係處理不當,可能導致你編譯異常Gradle編譯
- 360衛士阻止程式建立,導致各種異常
- OGG 表結構變化導致同步異常
- MongoDB 異常當機與引數cacheSizeGBMongoDB
- Oracle 資料庫不一致導致異常的恢復Oracle資料庫
- 解決一次gitlab因異常關機導致啟動失敗Gitlab
- 伺服器架構導致的SEO收錄異常伺服器架構
- 異常連線導致的記憶體洩漏排查記憶體
- ChromeHSTS異常導致無法訪問HTTPS網頁ChromeHTTP網頁
- Linux,Network manager 導致節點異常重啟Linux
- HA異常導致oracle資料庫無法啟動Oracle資料庫
- GDI資源洩漏導致的程式異常的解析
- 一條sql語句導致的資料庫當機問題及分析SQL資料庫
- 一條sql語句“導致”的資料庫當機問題及分析SQL資料庫
- 硬體或軟體衝突導致當機
- 驅動導致的當機怎麼解決
- SQLServer mirror當機後error 9004異常處理SQLServerError
- replace into 導致MASTER/SLAVE的auto_increment值不同ASTREM
- MySQL 預插入的資料條數過多導致異常MySql
- crontab設定導致的伺服器程式異常問題伺服器