本篇爲自己筆記,還未深入瞭解,瀏覽者不用看
首先我們要知道 mysql 的預寫日誌 wtite ahead log (WAL)機制,在mysql中redo日誌相當於wal,即客戶端操作命令先寫入 redo 日誌,然後再寫入內存緩衝區,返回客戶端, 最後再由操作系統寫入硬盤。這樣的好處是能保證事物。
當寫入 redo 日誌時服務器宕機,重啓服務器時,則mysql會執行redo日誌,這樣就會保質和客戶端得到的返回結果一致。
當然還有undo日誌,事物回滾時使用。當重啓服務器時,發現
當然高可用是由 binlog 實現的,那麼binlog和事物日誌的順序是怎麼樣的呢
下面來看 mysql 各種日誌的順序
- undo日誌(記錄事物未執行之前數據庫值)
- 將多個事物操作語句按順序寫入redo
- biglog日誌 (整個一次寫入,所以當開啓binlog時會對性能有點影響)
- 事物commit
- 返回用戶
其中在mysql 5.5之前,寫入binlog之後是異步寫入 mysql 從機的,那麼這時候如果主庫宕機,binlog還未寫入從庫,就會造成主從數據不一致。這時候如果要將從庫升級爲主庫,則需要恢復主庫後,使用 pt-table-checksum 等一致性檢測工具檢測主從一致性,並使用 pt-table-sync 恢復一致性
爲了解決這個問題,mysql5.5後增加了半同步複製,binlog寫入後,會同步等待從庫返回,從庫返滬後才返回給用戶。
具體可百度 mysql半同步一致性。 裏面的問題 mysql半同步一致性回滾 ,mysql腦裂問題 ,解決了這兩個問題纔算是解決了mysql的高可用問題。 具體分析參見 mysql半同步一致性探討
但 mongodb 副本集 已經解決了 腦裂 問題(有待考證) 使用 bully共識算法
raft協議也解決了腦裂問題 raft算法
關於mongodb是如何解決一致性的可以參見這篇文章 mongodb丟數據問題
經驗 對於支付等系統,在使用mysql半同步複製時,超時請使用無限長,避免退化成異步複製,當所有從庫都沒有響應時,就會提交失敗,這樣就避免了數據不一致的現象。