摘要:也就是說線程能夠獨立于線程之前工作。復制使用了三個線程。的日志線程,將事件寫入,的線程獲取,并將其寫入,線程重放日志。
1. 復制概述
MySQL 內置的復制功能是構建基于 MySQL 的大規模、高性能應用的基礎,復制解決的基本問題是讓一臺服務器的數據與其他服務器保持同步。接下來,我們將從復制概述及原理、復制的配置、常見的問題及解決方法來學習 MySQL 的復制功能。
1.1 復制解決的問題下面是復制常見的用途:
數據分布。Mysql 復制通常不會對帶寬造成很大壓力,但在 5.1 版本中引入的基于行的復制會比傳統的基于語句的復制模式產生更大的帶寬壓力。你可以隨意地停止或開始復制,并在不同的地理位置來分布數據備份,例如不同的數據中心。另外,即使在不穩定的網絡環境下,遠程復制也可以工作。但如果未來保存很低的復制延遲,最好有一個穩定、低延遲的連接。
負載均衡。通過 Mysql 復制,可以將讀操作分布到多個服務器上,實現對讀密集型應用的優化,并且很容易實現,通過簡單的代碼修改就能實現基本的負載均衡。對應小規模的應用,可以簡單的使用 DNS 輪詢(將一個機器名指向多個 IP 地址)。
備份。對于備份來說,負載是一項很有意義的技術補充。
高可用性和故障切換。負載能夠幫助應用避免 Mysql 單點失敗,一個使用復制的設計良好的系統能夠顯著的縮短宕機時間。
Mysql 升級測試。這是比較常見的做法,在更新 Mysql 版本前,先使用將要更新的版本作為備庫,保證更新版本不會對系統造成影響。
1.2 復制是如何工作的?在詳細介紹如何設置復制之前,讓我們先看看 Mysql 實際上是如何進行數據復制的。
總的來說,復制有三個步驟:
在主庫上把數據更改寫入到二進制日志(Binary Log)中(這些記錄被稱為二進制日志事件)。
備庫將主庫上的日志復制到自己的中繼日志(Relay Log)中。
備庫讀取中繼日志中的事件,將其更改同步到備庫。
以上是復制的簡單概述,下圖描述了復制的細節:
整體復制過程:
在主庫上記錄二進制日志。在每次準備提交事務完成 數據更新前,主庫將數據更新的事件記錄到二進制日志中。Mysql 會按事務提交的順序而非每條語句的執行順序來記錄二進制日志。在記錄二進制日志后,主庫會告訴存儲引擎可以提交事務了。
備庫將主庫的二進制日志復制到其本地的中繼日志中。首先,備庫會啟動一個工作線程,稱為 I/O 線程,I/O 線程跟主庫建立一個普通的客戶端連接,然后在主庫上啟動一個特殊的二進制轉儲(binlog dump)線程,這個二進制轉儲線程會讀取主庫二進制日志中的事件。它不會對時間進行輪詢。如果該線程“追趕”上了主庫,它將進入睡眠狀態,直到主庫發送信號量通知它有新的事件產生才會被換新,備庫 I/O 線程會將接收到的事件記錄到中繼日志中。
備庫啟動 SQL 線程,執行最后一步。該線程從中繼日志中讀取事件并在備庫執行,從而實現備庫數據的更新。當 SQL 線程追趕上 I/O 線程時,中繼日志通常已經在系統緩存中,所以中繼日志的開銷很低。SQL 線程執行的事件也可以通過配置項來決定是否寫入自身的二進制日志中,這對于備庫再配置備庫的常見非常有用。
這種復制架構實現了獲取事件和重放事件的解耦,允許這兩個過程異步進行。也就是說 I/O 線程能夠獨立于 SQL 線程之前工作。但是,這種架構也限制了復制的過程,其中最重要的一點是,在主庫上并發運行的查詢在備庫上只能串行化執行,因為只有一個 SQL 線程來重放中繼日志中的事件。
不過值得高興的是,5.7 版本已經支持從庫的并行復制了。基于二進制日志的并行復制,是在日志內容中新增了 last_committed 和 sequence_number,分別 表示事務提交的時間和上次事務提交的編號。如果事務具有相同的時間,表示這些事務是在一組內,可以進行并行回放。
2. 復制的原理我們已經了解了復制的一些基本概念,接下來我們要更深入的了解復制,看看復制究竟是如何工作的,有哪些優缺點。
2.1 基于語句的復制在 Mysql 5.0 及之前的版本中只支持基于語句的復制(也稱為邏輯復制)。基于語句的復制模式,主庫會記錄那些造成數據更改的 SQL 語句,當備庫讀取并重放這些事件時,實際上只是把主庫執行過的 SQL 再執行一遍。這種方式既有優點,也有缺點。
優點是:
實現簡單。理論上來說,只要簡單地記錄和執行 SQL 語句,就能夠讓主備保持同步。
二進制日志不會對帶寬產生較大影響。二進制日志里的事件更加緊湊,占用帶寬較小。
但事實上,基于語句的方式可能并不如其看起來那么便利,其缺點是:
主庫上的數據除了執行的語句外,可能還依賴其他因素。當主庫使用 CURRENT_USER() 函數的語句,存儲過程和觸發器在使用基于語句的復制模式時就可能會出現問題。
2.2 基于行的復制Mysql 5.1 開始支持基于行的復制。這種方式會將實際數據記錄在二進制日志中。同樣的,它也有其自身的優缺點。
它的優點是可以更加準確的復制數據,而缺點,則是可能造成較大的開銷。比如一個工資表中有一萬個用戶,我們把每個用戶的工資+1000,那么基于行的復制則要復制一萬行的內容,由此造成的開銷比較大,而基于語句的復制僅僅一條語句就可以了。
由于沒有哪種模式是對所有情況都是完美的,Mysql 就使復制模式可以動態切換。默認情況下使用的是基于語句的復制方式,但如果發現語句無法被正確地復制,就切換到基于行的復制模式。還可以根據需要來設置會話級別的變量 binlog_format,控制二進制日志格式。
2.3 復制文件解讀復制過程中會使用到一些文件。前面已經介紹了二進制日志文件和中繼日志文件,除此之外,還有其他的文件會被用到。
mysql-bin.index:當在服務器上開啟二進制日志時,同時會生成一個和二進制日志同名,但以 .index 作為后綴的文件,該文件用于記錄磁盤上的二進制日志文件。這里的 index 并不是表的索引,而是說這個文件的每一行包含了二進制文件的文件名。Mysql 依賴這個文件識別二進制日志文件。
mysql-relay-bin-index:中繼日志的索引文件,和 mysql-bin.index 的作用類似。
master.info:保存備庫連接主庫所需要的信息文件。格式為純文本(每行一個值),不同的 Mysql 版本,記錄的信息也可能不太。此文件不能刪除,否則備庫再重啟后不能連接主庫。這個文件以文本的方式記錄了復制用戶的密碼,所以要注意此文件的權限控制。
relay-log.info:記錄當前備庫復制的二進制日志和中繼日志位置文件。
使用這些文件來記錄 Mysql 復制和日志狀態是一種非常粗糙的方式。更不幸的是,它們不是同步寫的。如果服務器斷電并且文件數據沒有被刷新到磁盤,在重啟服務器后,文件中記錄的數據可能是錯誤。不過好在這些問題以及在 5.5 版本里做了改進。
2.4 發送復制事件到其它備庫log_slave_update 選項可以讓備庫編程其它服務器的主庫。在設置該選項后,Mysql 會將其執行過的事件記錄到它自己的二進制日志中。這樣它的備庫就可以從其日志中檢索并執行事件。下圖闡述了這一過程:
在這種場景下,主庫將數據更新事件寫入二進制日志,第一個備庫提取并執行這個事件。這個時候一個事件的生命周期應該已經結束了。但由于設置了 log_slave_updates,備庫會將這個事件寫到它自己的二進制日志中。這樣第二個備庫就可以從第一個備庫中,將事件提取到它的中繼日志中并執行。
這意味著作為源服務器的主庫可以將其數據變化傳遞給沒有與其直接相連的備庫上。默認情況下,這個選項是被打開的,這樣在連接到備庫時就不需要重啟服務器。
當第一個備庫把自主庫獲得的事件寫入到其它二進制日志中時,這個事件在備庫二進制日志中的位置與其主庫二進制日志中的位置幾乎肯定是不相同的,可能在不同的日志文件或文件內不同的位置。這意味著你不能假定所有擁有同一邏輯復制點的服務器擁有相同的日志坐標。
小結復制功能是 MySQL 高擴展性的基礎,常見的讀寫分離就使用了復制。
復制使用了三個線程。master 的日志線程,將事件寫入 binlog,slave 的 IO 線程獲取 binlog,并將其寫入 relaylog,SQL 線程重放 relaylog 日志。
復制有基于語句復制和基于行的復制。
參考:
高性能 MySQL - 第 3 版;
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/31138.html
摘要:也就是說線程能夠獨立于線程之前工作。復制使用了三個線程。的日志線程,將事件寫入,的線程獲取,并將其寫入,線程重放日志。 1. 復制概述 MySQL 內置的復制功能是構建基于 MySQL 的大規模、高性能應用的基礎,復制解決的基本問題是讓一臺服務器的數據與其他服務器保持同步。接下來,我們將從復制概述及原理、復制的配置、常見的問題及解決方法來學習 MySQL 的復制功能。 1.1 復制解決...
摘要:配置主庫和備庫。主庫當前的二進制日志文件,和獲得數據快照時在該二進制日志文件中的偏移量。它能夠在備份時不阻塞服務器的操作,因此可以在不影響主庫的情況下設置備庫。 showImg(https://segmentfault.com/img/bVbqOEk?w=720&h=480); 正所謂理論造航母,現實小帆船。單有理論,不動手實踐,學到的知識猶如空中樓閣。接下來,我們一起來看下如何一步步...
摘要:配置主庫和備庫。主庫當前的二進制日志文件,和獲得數據快照時在該二進制日志文件中的偏移量。它能夠在備份時不阻塞服務器的操作,因此可以在不影響主庫的情況下設置備庫。 showImg(https://segmentfault.com/img/bVbqOEk?w=720&h=480); 正所謂理論造航母,現實小帆船。單有理論,不動手實踐,學到的知識猶如空中樓閣。接下來,我們一起來看下如何一步步...
閱讀 3071·2021-10-11 10:58
閱讀 1989·2021-09-24 09:47
閱讀 502·2019-08-30 14:19
閱讀 1684·2019-08-30 13:58
閱讀 1444·2019-08-29 15:26
閱讀 640·2019-08-26 13:45
閱讀 2139·2019-08-26 11:53
閱讀 1772·2019-08-26 11:30