MySQL 主從復(fù)制的幾種方案及存在的問題

本文引用自《Mycat權(quán)威指南.pdf》

一、mysql主從復(fù)制的幾種方案

數(shù)據(jù)庫讀寫分離對于大型系統(tǒng)或者訪問量很高的互聯(lián)網(wǎng)應(yīng)用來說,是必不可少的一個重要功能。從數(shù)據(jù)庫的角度來說,對于大多數(shù)應(yīng)用來說,從集中到分布,最基本的一個需求不是數(shù)據(jù)存儲的瓶頸,而是在于計算的瓶頸,即 SQL 查詢的瓶頸,我們知道,正常情況下,Insert SQL 就是幾十個毫秒的時間內(nèi)寫入完成,而系統(tǒng)中的大多數(shù) Select SQL 則要幾秒到幾分鐘才能有結(jié)果,很多復(fù)雜的 SQL,其消耗服務(wù)器 CPU 的能力超強,不亞于死循環(huán)的威力。在沒有讀寫分離的系統(tǒng)上,很可能高峰時段的一些復(fù)雜 SQL 查詢就導(dǎo)致數(shù)據(jù)庫服務(wù)器 CPU爆表,系統(tǒng)陷入癱瘓,嚴(yán)重情況下可能導(dǎo)致數(shù)據(jù)庫崩潰。因此,從保護數(shù)據(jù)庫的角度來說,我們應(yīng)該盡量避免沒有主從復(fù)制機制的單節(jié)點數(shù)據(jù)庫。對于 MySQL 來說,標(biāo)準(zhǔn)的讀寫分離是主從模式,一個寫節(jié)點 Master 后面跟著多個讀節(jié)點,讀節(jié)點的數(shù)量取決于系統(tǒng)的壓力,通常是 1-3 個讀節(jié)點的配置,如下圖所示:

image.png

MySQL 支持更多的主從復(fù)制的拓?fù)潢P(guān)系,如下圖所示,但通常我們不會采用雙向主從同步以及環(huán)狀的拓?fù)洌?/p>

image.png

MySQL 主從復(fù)制的原理如下:

第一步是在主庫上記錄二進制日志(稍后介紹如何設(shè)置)。在每次準(zhǔn)備提交事務(wù)完成數(shù)據(jù)更新前,主庫將數(shù)
據(jù)更新的事件記錄到二進制日志中。MySQL 會按事務(wù)提交的順序 而非每條語句的執(zhí)行順序來記錄二進制日志。在記錄二進制日志后,主庫會告訴存儲引擎可以提交事務(wù)了。 下一步,備庫將主庫的二進制日志復(fù)制到其本地的中繼日志中。首先,備庫會啟動一個 工作線程,稱為 I/O 線程,I/O 線程跟主庫建立一個普通的客戶端連接,然后在主庫上啟動一個特殊的二進制轉(zhuǎn)儲(binhg dump、線程(該線程沒有對應(yīng)的 SQL 命令),這個二 進制轉(zhuǎn)儲線程會讀取主庫上二進制日志中的事件。它不會對事件進行輪詢。如果該線程追趕上了主庫,它將進入睡眠狀態(tài),直到主庫發(fā)送信號量通知其有新的事件產(chǎn)生時才會被喚醒,備庫 I/O 線程會將接收到的事件記錄到中繼日志中。備庫的 SQL 線程執(zhí)行最后一步,該線程從中繼日志中讀取事件并在備庫執(zhí)行,從而實現(xiàn)備庫數(shù)據(jù)的更新。當(dāng)SQL線程追趕上 I/O 線程時,中繼日志通常已經(jīng)在系統(tǒng)緩存中,所以中繼日志的開銷很低。SQL 線程執(zhí)行的事件也可以通過配置選項來決定是否寫入其自 己的二進制日志中,它對于我們稍后提到的場景非常有用。這種復(fù)制架構(gòu)實現(xiàn)了獲取事件和重放事件的解耦,允許這兩個過程異步進行。也就是說 I/o 線程能夠獨立于 SQL 線程之外工作。但這種架構(gòu)也限制了復(fù)制的過程,其中最重要 的一點是在主庫上并發(fā)運行的査詢在備庫只能串行化執(zhí)行,因為只有一個 SQL 線程來重放中繼日志中的事件。后面我們將會看到,這是很多工作負(fù)載的性能瓶頸所在。雖然有一些針對該問題的解決方案,但大多數(shù)用戶仍然受制于單線程。MySQL5.6 以后,提供了基于 GTID 多開啟多線程同步復(fù)制的方案,即每個庫有一個單獨的(sql thread)
進行同步復(fù)制,這將大大改善 MySQL 主從同步的數(shù)據(jù)延遲問題,配合 Mycat 分片,可以更好的將一個超級
大表的數(shù)據(jù)同步的時延降低到最低。此外,用 GTID 避免了在傳送 binlog 邏輯上依賴文件名和物理偏移量,能夠更好的支持自動容災(zāi)切換,對運維人員來說應(yīng)該是一件令人高興的事情,因為傳統(tǒng)的方式里,你需要找到 binlog和 POS 點,然后 change master to 指向,而不是很有經(jīng)驗的運維,往往會將其找錯,造成主從同步復(fù)制報錯,在 mysql5.6 里,無須再知道 binlog 和 POS 點,需要知道 master 的 IP、端口,賬號密碼即可,因為同步復(fù)制是自動的,mysql 通過內(nèi)部機制 GTID 自動找點同步。即使是并發(fā)復(fù)制機制、仍然無法避免主從數(shù)據(jù)庫的數(shù)據(jù)瞬間不同步的問題,因此又有了一種增強的方案,即galera for mysql、percona-cluster 或者 mariadb cluster 等集群機制,他們是一種多主同步復(fù)制的模式,可以在任意節(jié)點上進行讀寫、自動控制成員,自動刪除故障節(jié)點、自動加入節(jié)點、真正給予行級別的并發(fā)復(fù)制等強大能力!
下圖是其原理圖,通常是采用 3 個 MySQL 節(jié)點作為一個 Cluster,即提供了 3 倍的數(shù)據(jù)庫讀的并發(fā)能力.galera for mysql 集群這種方式,是犧牲了數(shù)據(jù)的寫入速度,以換取最大程度的數(shù)據(jù)并發(fā)訪問能力,類似Mycat 里的全局表,并且保證了數(shù)據(jù)同時存在幾個有效的副本,從而具有非常高的可靠性,因此在某種程度上,可以替代 Oracle 的一些關(guān)鍵場景,目前開源中間件中,只有 Mycat 很完美的支持了 galera for mysql 集群模式。

image.png

二、MySQL 主從復(fù)制的幾個問題

MySQL 主從復(fù)制并不完美,存在著幾個由來已久的問題,首先一個問題是復(fù)制方式:

  • 基于 SQL 語句的復(fù)制(statement-based replication, SBR);
  • 基于行的復(fù)制(row-based replication, RBR);
  • 混合模式復(fù)制(mixed-based replication, MBR);
  • 基于 SQL 語句的方式最古老的方式,也是目前默認(rèn)的復(fù)制方式,后來的兩種是 MySQL 5 以后才出現(xiàn)的復(fù)
    制方式。

RBR 的優(yōu)點:

  • 任何情況都可以被復(fù)制,這對復(fù)制來說是最安全可靠的;
  • 和其他大多數(shù)數(shù)據(jù)庫系統(tǒng)的復(fù)制技術(shù)一樣;
  • 多數(shù)情況下,從服務(wù)器上的表如果有主鍵的話,復(fù)制就會快了很多。

RBR 的缺點:
? binlog 大了很多;
? 復(fù)雜的回滾時 binlog 中會包含大量的數(shù)據(jù);
? 主服務(wù)器上執(zhí)行 UPDATE 語句時,所有發(fā)生變化的記錄都會寫到 binlog 中,而 SBR 只會寫一次,這會
導(dǎo)致頻繁發(fā)生 binlog 的并發(fā)寫問題;
? 無法從 binlog 中看到都復(fù)制了此什么語句。

SBR 的優(yōu)點:

  • 歷史悠久,技術(shù)成熟;
  • binlog 文件較小;
  • binlog 中包含了所有數(shù)據(jù)庫更改信息,可以據(jù)此來審核數(shù)據(jù)庫的安全等情況;
  • binlog 可以用于實時的還原,而不僅僅用于復(fù)制;
  • 主從版本可以不一樣,從服務(wù)器版本可以比主服務(wù)器版本高。

SBR 的缺點:

  • 不是所有的 UPDATE 語句都能被復(fù)制,尤其是包含不確定操作的時候;
  • 復(fù)制需要進行全表掃描(WHERE 語句中沒有使用到索引)的 UPDATE 時,需要比 RBR 請求更多的行級鎖;
  • 對于一些復(fù)雜的語句,在從服務(wù)器上的耗資源情況會更嚴(yán)重,而 RBR 模式下,只會對那個發(fā)生變化的記
    錄產(chǎn)生影響;
  • 數(shù)據(jù)表必須幾乎和主服務(wù)器保持一致才行,否則可能會導(dǎo)致復(fù)制出錯;
  • 執(zhí)行復(fù)雜語句如果出錯的話,會消耗更多資源。

選擇哪種方式復(fù)制,會影響到復(fù)制的效率以及服務(wù)器的損耗,甚以及數(shù)據(jù)一致性性問題,目前其實沒有很好
的客觀手手段去評估一個系統(tǒng)更適合哪種方式的復(fù)制,Mycat 未來希望能通過智能調(diào)優(yōu)模塊給出更科學(xué)的建議。第二個問題是關(guān)于主從同步的監(jiān)控問題,Mysql 有主從同步的狀態(tài)信息,可以通過命令 show slave status獲取,除了獲知當(dāng)前是否主從同步正常工作,另外一個重要指標(biāo)就是 Seconds_Behind_Master,從字面理解,它表示當(dāng)前 MySQL 主從數(shù)據(jù)的同步延遲,單位是秒,但這個指標(biāo)從 DBA 的角度并不能簡單的理解為延遲多少秒,感興趣的同學(xué)可以自己去研究,但對于應(yīng)用來說,簡單的認(rèn)為是主從同步的時間差就可以了,另外,當(dāng)主從同步停止以后,重新啟動同步,這個數(shù)值可能會是幾萬秒,取決于主從同步停止的時間長短,我們可以認(rèn)為數(shù)據(jù)此時有很多天沒有同步了,而這個數(shù)值越接近零,則說明主從同步延遲最小,我們可以采集這個指標(biāo)并匯聚曲線圖,來分析我們的數(shù)據(jù)庫的同步延遲曲線,然后根據(jù)此曲線,給出一個合理的閥值,主從同步的時延小于閥值時,我們認(rèn)為從庫是同步的,此時可以安全的從從庫讀取數(shù)據(jù)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容