MySQL 主從架構配置詳解

成長之路 - 薛亮發表於2016-08-11

無論是哪一種資料庫,資料的安全都是至關重要的,因此熟練掌握資料庫的安全備份功能,是作為開發人員,特別是後端開發人員的一項必備技能。MySQL 資料庫內建的複製功能,可以幫助我們對資料進行異地備份,讀寫分離,在較大程度上避免資料丟失、資料庫伺服器壓力過大甚至當機帶來的損失。

使用MySQL 主從架構一年多了,想起當年學習這些東西的時候,苦於完整的中文資料比較少,當時英文又不太好,遇到不少問題。剛好最近也有一段時間沒更新部落格了,心血來潮,決定翻譯一下 MySQL 官網的英文文件,官網文件講解的非常詳細,可以幫助更多新手理解並快速入門。

第一次翻譯這麼大篇幅的英文技術文件,儘量採取逐句翻譯,這樣可以儘可能保持文件原意。有很多需要修改的地方,懇請各位指正。

廢話說多了,下面開始~~~

概述

MySQL的複製功能,使得資料可以從一臺MySQL 資料庫伺服器(我們稱之為主庫,即 master),複製到另外一臺或者多臺MySQL 資料庫伺服器(我們稱之為從庫,即 slave)。在預設情況下,複製的過程是非同步的,因此,從資料庫伺服器不需要一直連線到主資料庫伺服器接收更新。 這也意味著,更新可以在長距離連線,甚至在諸如撥號服務臨時或者間歇性的情況下繼續。MySQL的複製功能,可以複製所有資料庫,或者需要複製的幾個資料庫,甚至資料庫中需要複製的資料庫表,這都依賴於你是如何配置的。

配置

配置主庫

需要複製的主庫必須開啟二進位制日誌功能,並且建立一個唯一的伺服器編號(server-id),之後,必須重啟資料庫。

由於二進位制日誌檔案是主從複製的基礎,所以,主庫 必須 開啟二進位制日誌功能。如果二進位制日誌功能沒用使用 log-bin選項開啟,主從複製就無法進行。

可以將所有的從庫作為一個組,組裡的每一個從庫都需要建立一個唯一的伺服器編號(server-id),以便用這個編號在組裡識別指定的從庫,資料庫伺服器編號(server-id)必須是 1 至 232 − 1 之間的整數。具體使用哪些整數,完全由你自己決定,沒有其他特殊規定。

要給資料庫配置伺服器編號(server-id)選項,需要停止MySQL 資料庫,然後編輯 my.cnf 或者 my.ini 檔案。在配置檔案的 [mysqld] 這一節下,新增 log-bin 和 server-id 兩個選項。如果它們已經存在,但是被註釋掉了,就解註釋,然後根據自己的需要進行修改。例如使用字首為mysql-bin日誌檔名,啟用二進位制日誌功能,配置伺服器編號為1,可以參考下面的示例:

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

儲存好上面的修改之後,重啟資料庫。

注意:

  • 如果沒有配置 server-id 選項(或者將其設定為預設值0),主庫將拒絕來自任何從庫的連線請求。
  • 為了能在 InnoDB 儲存引擎中使用事務時,達到最大可能的耐用性和一致性,需要在 my.cnf 檔案中配置innodb_flush_log_at_trx_commit=1 和 sync_binlog=1 兩個選項。
  • 不要在主庫上配置 skip-networking 選項。如果主庫的網路都被禁用了,從庫就不能連線到主庫,最終導致複製失敗。

配置從庫

前面在配置主庫時,已經說過,必須給每個從庫建立一個伺服器編號,建立好之後,必須 重啟資料庫。

如果從庫的伺服器編號沒有設定,或者設定的編號和主庫衝突,就需要先停掉從庫,然後編輯從庫的配置檔案的[mysqld] 這一節,指定一個唯一的伺服器編號,像下面這樣:

[mysqld]
server-id=2

儲存好修改之後,重啟從庫。

如果配置了多個從庫,那麼每一個從庫都必須有一個唯一的 server-id 選項值(即每個從庫的 server-id 值必須與主庫以及除它本身以外的其他從庫的 server-id 值不同)。

注意:
如果沒有配置從庫的 server-id 選項(或者配置它的值為預設值0),那麼從庫將拒絕連線到主庫。

不需要為了主從複製而給從庫開啟二進位制日誌功能。如果給從庫開啟了二進位制日誌功能,由此產生的二進位制日誌檔案可以作為備份資料,或者在資料庫崩潰的時候,使用二進位制日誌檔案恢復資料,也可以使用此開啟了二進位制日誌功能的從庫作為更復雜的主從架構的一部分。比如,可以將此從庫作為其他從庫的主庫。

為從庫建立使用者

每個從庫都使用資料庫使用者名稱和密碼連線並登入到主庫,所以在主庫中必須有一個能讓從庫連線到此主庫的 MySQL 賬戶。任何被賦予 REPLICATION SLAVE 許可權的 MySQ L賬戶,都可以用作此連線操作。可以為每一個從庫分配一個賬戶,也可以讓所有的從庫使用同一個賬戶,用來連線到主庫。

雖然不需要為從庫分配一個單獨的賬戶去執行復制,但你應該知道的是,用來複制操作的使用者名稱和密碼都是明文儲存在主庫檔案或表中的(相關連結:Section 17.2.2.2, “Slave Status Logs”)。因此,你可能想要建立一個隔離的、只能進行復制操作的賬戶,將對其他賬戶的損害減到最小。

使用 CREATE USER 語句建立新的 MySQL 賬戶。使用 GRANT 語句給這個賬戶賦予複製操作所必要的許可權。若建立賬戶僅是為了達到複製的目的的話,那麼這個賬戶只需要 REPLICATION SLAVE 。舉個例子,建立一個新的賬戶 repl ,使其可以從 mydomain.com 域名下的任何主機連線到主庫並執行復制,在主庫上執行下面的語句:

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

更多關於使用者賬戶的操作語句,請檢視 Section 13.7.1, “Account Management Statements”

獲取主庫的二進位制日誌座標

為了在接下來配置完從庫,使其能從正確的位置開始執行復制操作,你需要知道主庫當前的二進位制日誌座標。

如果在主庫上已經儲存了一些資料,而且又需要在開始之前同步到從庫上,那麼就必須在主庫上停止執行語句,接著,獲取主庫當前的日誌座標,並轉存其資料。如果不使主庫停止執行語句,將會導致轉存的資料和資料庫的狀態資訊不相符,最終導致從庫資料不一致或者引起從庫發生錯誤。

依照下面這幾步來獲取主庫的二進位制日誌座標:

  1. 使用命令列連線到主庫以開始一個會話,清空所有表的快取,並且通過執行 FLUSH TABLES WITH READ LOCK 阻止對資料庫的寫操作,即鎖定對所有表的只讀操作:
    FLUSH TABLES WITH READ LOCK

    對於 InnoDB 儲存引擎來說, FLUSH TABLES WITH READ LOCK 語句也會阻止 COMMIT 操作。

    提醒:
    不要退出剛才執行了 FLUSH TABLES 語句的會話。如果退出了這個會話,上面的鎖表操作將被釋放。

  2. 再開啟一個新的會話,連線到主庫,使用 SHOW MASTER STATUS 語句來確認當前二進位制日誌檔案的名稱和位置:
    SHOW MASTER STATUS;

    結果:

    File Position Binlog_Do_DB Binlog_Ignore_DB
    mysql-bin.000003 73 test manual,mysql

    File 列顯示了當前二進位制日誌檔案的名字, Position 列顯示了檔案的位置。在上面這個例子中,二進位制日誌檔案的名字是 mysql-bin.000003 ,位置是 73 。這些資料代表了從庫將要(開始)處理來自主庫的更新的座標。記錄下這些資料,稍後在配置從庫時,將會使用到它們。

    如果主庫在事先沒有開啟二進位制日誌功能時已經在執行狀態了,那麼,通過執行 SHOW MASTER STATUS 語句,或者通過執行 mysqldump –master-data 命令,得到的結果中,二進位制日誌檔名和位置都將是空。若是那樣的話,在從庫上配置二進位制日誌名和位置時,就分別用空字串('')和 數值 4 來代替。

到目前為止,我們已經獲得了足夠的資訊,我們需要使用這些資訊,配置從庫,使從庫開始從正確的位置讀取來自主庫的二進位制日誌,開始進行復制。

如果你有一些資料,需要在從庫開始複製之前同步到從庫,那麼,保持之前開啟的會話不要關閉,這樣才能保持之前開啟的資料庫鎖不被釋放。接著,檢視 Section 17.1.1.5, “Creating a Data Snapshot Using mysqldump” 或者 Section 17.1.1.6, “Creating a Data Snapshot Using Raw Data Files” 。它們將會告訴你如何防止任何進一步的更改,以便於將已經存在於主庫的資料同步到從庫。

如果你正在建立一個全新的主從複製組,你可以退出第一個會話,以便釋放對資料庫的讀鎖定。

使用新的主、從庫配置複製

使用新的主、從庫配置資料庫複製是最簡單、最直接的方式。

如果你正在設定新的伺服器,但是有一些從其他的務器轉存的資料庫,並且你想載入到你的複製配置新中,同樣可以使用本節介紹的方法。通過將資料載入到新的主庫中,資料將會被自動複製到從庫中。

依照下面這幾步,來在新的主、從庫之間配置複製功能:

  1. 通過一些必要的配置屬性檔案,配置主庫。參考:配置主庫
  2. 啟動主庫。
  3. 設定一個使用者。參考:為從庫建立使用者。
  4. 獲取主庫的狀態資訊。參考:獲取主庫的二進位制日誌座標。
  5. 在主庫上釋放讀鎖:
    UNLOCK TABLES;
  6. 在從庫上編輯 MySQL 配置檔案。 參考:配置從庫。
  7. 啟動從庫。
  8. 執行 CHANGE MASTER TO 語句來設定主庫的資訊。參考:為從庫配置主庫的資訊。

在每一臺從庫上,都完成上面這幾步操作。

因為使用的是新的資料庫,沒有資料或者配置資訊需要替換,因此你不需要複製或者匯入任何其他資訊。

如果你需要使用來自於其他資料庫伺服器上資料配置新的複製環境,你可能需要在新的主庫上匯入這些轉存的資料。由此對主庫產生的更新將會被自動同步到從庫:

mysql -h master < fulldb.dump

使用已有的資料配置複製環境

當使用已有的資料配置複製環境時,你可能需要做出一個決定,如何在啟動複製服務之前,讓從庫以最優方式獲取到主庫的資料。
下面這幾步基本操作將會引導你,使用已有的資料配置複製環境:

  1. 在 MySQL 主庫執行的情況下,建立一個使用者,以便從庫在複製的時候可以連線到主庫。參考:為從庫建立使用者。
  2. 如果你還沒有在主庫上配置 server-id 選項,或者還沒有開啟二進位制日誌功能,你需要停止主庫,然後配置它們。參考:配置主庫。
    在配置主庫的過程中,如果需要停止(重啟)主庫服務,你可以利用主庫服務停止的這段時間,建立一個主庫的快照。但別忘了,你需要在停止主庫服務、更新配置資訊,建立快照之前,獲得主庫的狀態資訊(參考:獲取主庫的二進位制日誌座標)。關於如何使用原始資料建立資料庫快照,你可以參考這裡:Section 17.1.1.6, “Creating a Data Snapshot Using Raw Data Files”
  3. 如果主庫資訊已經正確配置好了,那麼就可以獲取它的狀態資訊(參考:獲取主庫的二進位制日誌座標),接著,使用 MySQL 自帶的 mysqldump 工具建立一個資料庫快照(參考:Section 17.1.1.5, “Creating a Data Snapshot Using mysqldump”),也可以參考 Section 17.1.1.6, “Creating a Data Snapshot Using Raw Data Files” 直接建立主庫的原始資料檔案的快照。
  4. 更新從庫的配置資訊。參考:配置從庫。
  5. 這一步的操作,取決於你在主庫上是如何建立的資料的快照的。
    若你是使用的 mysqldump 建立的快照:
    • 使用 --skip-slave-start 選項啟動從庫,以便不讓主從複製開始。
    • 像下面這樣,匯入轉存的資料檔案:
      mysql < fulldb.dump

    若你是使用第二種方案,即直接建立原始資料檔案的快照的方式:

    • 將資料檔案解壓到從庫的資料(data)目錄下:
      tar xvf dbdump.tar

      你可能需要設定這些檔案的許可權和所有者,以便在從庫可以獲取到這些資料檔案,並且可以對其進行更新。

    • 使用 --skip-slave-start 選項啟動從庫,以便不讓主從複製開始。
  6. 將主庫的二進位制日誌座標資訊配置到從庫。這一步用來指定從庫需要從主庫的哪一個二進位制日誌檔案,以及從這個檔案的什麼位置開始複製。當然,也需要在從庫上配置連線主庫時使用的憑證和主庫的 IP 或者 域名。更多關於CHANGE MASTER TO 語句的所需的必須引數等資訊,請參考:為從庫配置主庫的資訊。
  7. 啟動從庫:
    START SLAVE;

執行完上面這幾步,從庫就會連線到主庫,主庫的任何更新操作,都將被髮送到從庫,從庫會在已有的快照資料的基礎上,同步執行這些更新。

如果你忘記了設定主庫的 server-id 選項資訊,從庫將無法連線到主庫。

如果你忘記了設定從庫的 server-id 選項資訊,在從庫的錯誤日誌中,將出現以下錯誤資訊:

Warning: You should set server-id to a non-0 value if master_host
is set; we will force server id to 2, but this MySQL server will
not act as a slave.

同樣,如果從庫由於其他任何原因導致不能執行復制,你可以在錯誤日誌檔案中得到相關的錯誤資訊。

從庫通過使用儲存在主庫資訊倉庫中的資訊,保持跟蹤它已經執行了多少主庫產生的二進位制日誌。通過 --master-info-repository 選項,可以將倉庫資訊設定在檔案的表單裡,或者在一個表中。當配置資訊為 --master-info-repository=FILE 時,你可以在從庫的資料(data)目錄下發現兩個檔案,名字分別是 master.info 和 relay-log.info 。配置資訊為 --master-info-repository=TABLE 時,資訊將會被儲存在 mysql 資料庫的 master_slave_info表中。無論如何,不要刪除或者編輯上面提到的檔案和表裡的資料,除非你清楚的知道你在幹什麼,並且充分理解這麼做代表的含義。即便如此,也應該優先使用 CHANGE MASTER TO 語句去修改複製引數。從庫可以使用語句中指定的值去自動更新狀態資訊檔案。更多相關資訊請參考:Section 17.2.2, “Replication Relay and Status Logs”

注意:
主庫資訊倉庫的內容會覆蓋一些在命令列或者 my.cnf 檔案中設定的選項。詳細資訊請參考:Section 17.1.4, “Replication and Binary Logging Options and Variables”

一份主庫的快照,可以被多個從庫來使用。如果需要額外再配置一些從庫,可以使用相同的主庫快照,像之前介紹如何配置已有從庫時描述的那樣,配置這些額外增加的從庫。

為從庫配置主庫的資訊

你必須告訴告訴從庫一些必要資訊,以便從庫能夠連線到主庫進行復制。為了做到這一點,在從庫上執行下面的語句,根據你的系統上實際的值,替換語句中相應的選項值:

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;

注意:
複製不能使用 Unix 套接字檔案(socket file)。你必須確保能夠使用 TCP/IP 協議連線到主庫。

CHANGE MASTER TO 語句也有一些其他引數可供配置。例如,可以通過使用此語句的其他選項,決定是否使用 SSL 協議,以便達到安全的複製。

關於此語句的完整的選項,以及選項值允許的最大長度等資訊,請參考:Section 13.4.2.1, “CHANGE MASTER TO Syntax”

相關文章