淺析MySQL複製

来源:http://www.cnblogs.com/ivictor/archive/2016/08/16/5764978.html
-Advertisement-
Play Games

MySQL的複製是基於binlog來實現的。 流程如下 涉及到三個線程,主庫的DUMP線程,從庫的IO線程和SQL線程。 1. 主庫將所有操作都記錄到binlog中。當複製開啟時,主庫的DUMP線程根據從庫IO線程的請求將binlog中的內容發送到從庫。 2. 從庫的IO線程接受到主庫DUMP線程發 ...


MySQL的複製是基於binlog來實現的。

 

流程如下

涉及到三個線程,主庫的DUMP線程,從庫的IO線程和SQL線程。

1. 主庫將所有操作都記錄到binlog中。當複製開啟時,主庫的DUMP線程根據從庫IO線程的請求將binlog中的內容發送到從庫。

2. 從庫的IO線程接受到主庫DUMP線程發送的binlog事件後,將其寫到本地的relay-log。

3. 從庫的SQL線程重放relay-log中的事件。

實際上,在MySQL 4.0之前,複製只有兩個線程,master和slave端各一個。在Slave端,該線程同時負責接收主庫發來的binlog事件,也負責事件的重放,所以沒有使用relay-log,這樣容易導致,當binlog事件的重放速度較慢時,會影響binlog事件的接受。

 

複製的搭建

基本步驟如下:

1. 配置主庫和從庫

2. 創建複製的賬號

3. 創建主庫一致性快照

4. 根據主庫的快照,建立從庫

5. 開啟複製

 

詳細步驟如下

1. 配置主庫和從庫

主庫

開啟binlog並設置server-id

[mysqld]
log-bin=mysql-bin
server-id=1

在一組複製結構中,每個伺服器必須配置一個唯一的server-id。該值的有效範圍為1~232-1。

如果server-id設置為0的話,則MySQL會自動將它更改為1。此時,對複製沒有影響。

如果server-id沒有顯式設置的話,則MySQL同樣會將它設置為1,但是從連接的時候,IO線程會報錯

Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Misconfigured master - server_id was not set'

 

從庫

設置server-id

[mysqld]
server-id=2

在從伺服器上,可以選擇不開啟binlog。當開啟了binlog後,如果想把重放的時間同樣也記錄到binlog中,可將log_slave_updates參數設置為1。

 

設置完畢後,重啟資料庫

 

2. 創建複製賬號

主庫上執行

mysql> CREATE USER 'repl'@'%.mydomain.com' IDENTIFIED BY 'slavepass';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%.mydomain.com';

 

3. 創建主庫一致性快照

在這裡,我用mysqldump來創建資料庫快照

# mysqldump --master-data=2  -R --single-transaction -A > 3306_20160815.sql

在生成的備份文件中,我們可以得到在對資料庫執行一致性快照時主的狀態,包括二進位文件的名稱及位置

# head -30 3306_20160815.sql

...
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000016', MASTER_LOG_POS=120;
...

 

4. 根據主庫的快照,建立從庫

# mysql < 3306_20160815.sql

 

5. 開啟複製

根據第3步獲取到的主庫狀態執行CHANGE MASTER TO命令

mysql> CHANGE MASTER TO
         MASTER_HOST='master_host_name',
         MASTER_USER='replication_user_name',
         MASTER_PASSWORD='replication_password',
         MASTER_LOG_FILE='recorded_log_file_name',
         MASTER_LOG_POS=recorded_log_position;

在執行CHANGE MASTER TO命令後,從庫並不會連接到主庫,而只是將這些信息寫入到從庫數據目錄下的master.info和relay-log.info中。如果沒有顯式指定MASTER_LOG_FILE,則預設為空,因為此時還沒有和主庫建立連接,並不知道主庫binlog的文件名稱,只有等到和主庫建立連接時才能知道。如果MASTER_LOG_POS沒有顯式指定,則預設為4,即忽略binlog的頭4個位元組,從第一個事件開始讀取。

 

開啟複製功能

mysql> start slave;

 

查看複製的狀態

mysql> show slave status\G

重點關註以下兩個變數,如果為YES,則代表複製搭建成功。

...
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...

 

註:以上搭建場景是基於主庫上已經有一定的數據。如果在全新的環境中搭建,實際上會更簡單。

只需獲取主庫的狀態信息即可

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000016 |      120 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec

 

MySQL複製的格式

MySQL的複製有三種格式:

Statement-based replication(SBR)

基於語句的複製,即master上執行的SQL語句原封不動的在slave上重放。該複製格式在MySQL 3.23即出現了。

優點:

1. 節省binlog的空間。

2. 可用於審核,畢竟所有的DML語句都是直接記錄在binlog中。

缺點:

1. 很多函數在主從上執行的結果並不一致

LOAD_FILE(),UUID(), UUID_SHORT(),USER(),FOUND_ROWS(),SYSDATE(),GET_LOCK(),IS_FREE_LOCK(),IS_USED_LOCK(),MASTER_POS_WAIT(),RAND(),RELEASE_LOCK(),SLEEP(),VERSION()

2. DELETE和UPDATE操作,帶了LIMIT子句,卻沒有帶ORDER BY,可能導致主從執行的結果並不一致。

3. 相對於基於行的複製,master上執行INSERT ... SELECT操作需要更多的行鎖。

4. 自定義函數(UDF)必須確保執行的結果是確定的。

 

Row-based replication(RBR)

基於行的複製,MySQL 5.1引入的,相對於SBR,它記錄的是DML操作涉及到的行。

優點:

1. 安全。master上所有的變更都能複製到slave上。

2. 在執行以下操作時,只需更少的行鎖。

    INSERT ... SELECT

    帶有AUTO_INCREMENT列的INSERT操作

    UPDATE和DELETE中,WHERE條件沒有用上索引。

缺點:

1. 會產生大量的日誌。

譬如一張表有1w條記錄,如果我不帶任何條件執行delete操作,則在基於statement的複製中,在binlog中只會記錄delete from table這一條記錄,但是在基於row的複製中,則會記錄1w筆記錄,每筆記錄類似於delete from table where ..。

這會帶來以下問題

 1> 如果利用binlog進行恢復,會需要更長的時間.

 2> 在寫數據到binlog中時,因為數據量大,會導致binlog的鎖定時間較長,影響資料庫的併發。

 3> 較大的日誌會對磁碟IO和網路IO產生較大的壓力。

 4> 增大slave的延遲。

2. 不會對二進位日誌進行校驗。

3. 不推薦基於庫級別的複製

    包括--replicate-do-db, --replicate-ignore-db, --replicate-rewrite-db

 

MIXED

MIXED是上述兩者的的結合,會根據執行的語句和涉及的存儲引擎自動在這兩種模式間切換。預設情況下,採用的是基於語句的複製模式,在遇到unsafe statements時,會切換為基於行的複製模式。

關於切換的條件,可參考官方文檔:http://dev.mysql.com/doc/refman/5.7/en/binary-log-mixed.html

 

在MySQL 5.7.7之前,預設的是基於語句的複製模式,從MySQL 5.7.7開始,預設基於行的複製模式。

 

複製中涉及的文件

relay-log

relay-log保存著從庫IO線程從主庫讀取到的binlog事件。和binlog格式一樣,可通過mysqlbinlog解析其中的內容。

可通過配置relay_log和relay_log_index參數設置relay-log和relay-log.index文件的名稱。

 

relay-log在如下情況下會發生切換:

1. slave IO線程啟動的時候。

2. 執行FLUSH LOGS操作的時候。

3. 達到參數max_relay_log_size設置的大小,預設為0,即以max_binlog_size的值作為max_relay_log_size的大小。

slave SQL線程在重放完一個relay-log文件中的所有事件後,會自動刪除relay-log文件(由relay_log_purge參數控制),所以沒有顯式刪除relay-log的命令。

 

master.info

該文件保存了主庫的主機名,埠,複製賬號的用戶名和密碼,以及從庫接受主庫binlog事件的位置信息,通過這些位置信息,從庫的IO線程知道下次從哪裡獲取主庫的binlog事件。

該位置信息對應於show slave status\G中的Master_Log_File和Read_Master_Log_Pos。

如下所示:

# cat master.info

23
mysql-bin.000014
120
192.168.244.10
repl
repl
3306
60
0





0
1800.000

0
cad449f2-5d4f-11e6-b353-000c29c64704
86400


0

 

relay-log.info

該文件記錄從庫的重放信息,這樣即便資料庫發生重啟,SQL線程也知道該從哪裡開始重放。

該位置信息對應於show slave status\G中的Relay_Master_Log_File和Exec_Master_Log_Pos。

# cat relay-log.info

7
./mysqld-relay-bin.000024
283
mysql-bin.000014
120
0
0
1
1

 

Crash-Safe Replication

slave每次接受binlog或者應用relay-log時,都要修改master.info或relay-log.info的信息並同步到磁碟中,這會導致大量的磁碟操作,所以,一般都是採用非同步方式來對這兩個文件進行更改。雖然每次都會修改這些文件,但是持久化到磁碟卻留給操作系統處理。在記憶體與磁碟中的信息不一致時,如果此時操作系統宕機,記憶體中的信息將無法及時同步到磁碟中。操作系統恢復後,master.info和relay-log.info的數據依然是舊的,所以會從已經執行的部分重新執行。

MySQL 5.6為了改善這個問題,提供了兩個參數,可將master.info和relay-log.info中的內容保存在表中而不是磁碟文件中。

master-info-repository

可設置為TABLE或FILE,如果使用FILE,則複製的位置信息依舊保存在master.info中,如果設置為TABLE,則信息報保存在mysql.slave_master_info中,預設為FILE。

relay-log-info-repository

可設置為TABLE或FILE,如果使用FILE,則應用relay-log的信息會保存在relay-log.info中,如果設置為TABLE,則保存在mysql.slave_relay_log_info中,預設為FILE。

 

通過將上述兩個變數設置為TABLE,可實現“Crash-Safe Replication”,上述的相關操作都會放到一個事務中進行。

 

總結

1. 啟用複製功能並不會增加伺服器太多的開銷,主要是開啟binlog帶來的開銷,包括binlog文件的追加寫操作開銷,以及系統調用fsync帶來的開銷。

2. MySQL的複製功能具有向後相容性,因為較新版本的MySQL的binlog中會進入新的事件類型。所以,可以將較新版本的MySQL作為從庫。

3. MySQL複製是非同步的。

4. MySQL 5.6開始新增延遲複製功能,由master_delay參數來控制。

 

參考

1. http://dev.mysql.com/doc/refman/5.7/en/replication-configuration.html

2. MariaDB原理與實現

 

 

 

 

 

 

 

 

 

    

    

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一.界面搭建 1.項目需求 主界面能左右滾動,還能上下滾動,點擊按鈕跳轉界面 2.分析界面 點擊按鈕跳轉界面可以自定義UITabBarCotroller來實現 左右滾動,可以利用scrollView來實現 或 UICollectionView 上下滾動,用tableView可以實現 3.選擇實現方案 ...
  • 參考文章:微信公眾號文章 一直對sql中的left和right有誤解,一直以為它是這樣的。 執行這樣一句: 出現的結果是這樣的: 而我心中這樣認為: 我認為只出現第二個。 運行了就知道了。 ...
  • 有時候我們的某個程式或者應用在執行SQL語句時報錯了, 我們需要拿到報錯的SQL語句檢查, 那麼你可以藉助:SQL Profiler工具來實現. 1.SQL Profiler是一個可以檢測SQL伺服器上SQL語句執行情況的工具,也稱SQL抓包工具. 2.打開 SQL Profiler: 開始=》所有 ...
  • 對於程式員來說,編程過程中或多或少會和資料庫打交道。如果採用Visual Studio進行程式開發,則微軟的Sql Server資料庫是最好的選擇。但是問題來了,Sql Server資料庫動輒幾個G,安裝後占用的空間也相當大,是不是每個開發人員在開發時都需要安裝Sql Server呢?其實,對於小型 ...
  • 環境要求JDK 1.6+java -versionPython 2.6.6+python -V ZooKeeper3.4.5+storm 0.9.4+ 單機模式上傳解壓 下麵分別啟動ZooKeeper、Nimbus、UI、supervisor、logviewer 需要多等一會兒,通過jps觀察 登錄 ...
  • Hive是為瞭解決hadoop中mapreduce編寫困難,提供給熟悉sql的人使用的。只要你對SQL有一定的瞭解,就能通過Hive寫出mapreduce的程式,而不需要去學習hadoop中的api。 在部署前需要確認安裝jdk以及Hadoop 如果需要安裝jdk以及hadoop可以參考我之前的博客 ...
  • 存儲過程 一 存儲過程的概念 存儲過程是在資料庫管理系統保存的,預先編譯的,能實現某種功能的SQL程式,它是資料庫應用中運用比較廣泛的一種數據對象。 為什麼需要存儲過程? 1.存儲過程只在創造時進行編譯,以後每次執行存儲過程都不需再重新編譯,而一般SQL語句每執行一次就編譯一次,所以使用存儲過程可提 ...
  • 今天在做統計數據的時候,傳入數組導致數據不顯示。解決方式和大家分享一下: --參數@CompanyName='北京,天津,上海' DECLARE @PointerPrev int DECLARE @PointerCurr int DECLARE @TName nvarchar(100) Set @P ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...