跳轉到內容

MySQL/複製

來自華夏公益教科書,開放的書籍,開放的世界

什麼是複製

[編輯 | 編輯原始碼]

複製意味著寫入主 MySQL 伺服器的資料將被髮送到單獨的伺服器並在那裡執行。

應用

  • 備份
  • 將讀取訪問分散到多個伺服器以實現可擴充套件性
  • 故障轉移/高可用性

複製型別

  • 非同步複製(基本主從)
  • 半非同步複製(非同步複製 + 強制在完成查詢之前進行 1 次從伺服器複製)

複製配置

  • 標準:主->從
  • 雙主:主<->主

在主主複製中,兩個主機同時是主伺服器和從伺服器。 伺服器 A 複製到伺服器 B,伺服器 B 複製到伺服器 A。 沒有一致性檢查,即使配置了 auto_increment_increment/auto_increment_offset,也不應將兩個伺服器用於併發寫入。

非同步複製

[編輯 | 編輯原始碼]

這是最簡單的複製。 主伺服器寫入二進位制日誌檔案,從伺服器可以讀取此日誌檔案(可能選擇性地讀取)以重放查詢語句。 它是非同步的,這意味著主伺服器和從伺服器在特定時間點可能具有不同的狀態; 此外,此設定可以承受網路斷開連線。

主伺服器上的配置

[編輯 | 編輯原始碼]

/etc/mysql/my.cnf 中,在 [mysqld] 部分

  • 定義伺服器識別符號(檢測迴圈?); 通常我們會使用 1 表示伺服器,但它可以是不同的
server-id = 1
log-bin
# or log-bin = /var/log/mysql/mysql-bin.log

為從伺服器建立一個新使用者以連線

 CREATE USER 'myreplication';
 SET PASSWORD FOR 'myreplication' = PASSWORD('mypass');
 GRANT REPLICATION SLAVE ON *.* to 'myreplication';

驗證您的伺服器識別符號

 SHOW VARIABLES LIKE 'server_id';

每個從伺服器上的配置

[編輯 | 編輯原始碼]

/etc/mysql/my.cnf 中,在 [mysqld] 部分

  • 定義伺服器識別符號,與主伺服器不同(以及與其他從伺服器不同)
server-id = 2
  • 使用以下命令驗證
 SHOW VARIABLES LIKE 'server_id';
  • 您還可以將從伺服器主機名宣告給主伺服器(參見下面的 SHOW SLAVE HOSTS
report-host=slave1

宣告主伺服器

 CHANGE MASTER TO MASTER_HOST='master_addr', MASTER_USER='myreplication', MASTER_PASSWORD='mypass';

如果從備份設定複製,請指定起點(新增到前面的命令中)

 MASTER_LOG_FILE='<binary_log_from_master>', MASTER_LOG_POS=<master_binary_log_position>;

啟動複製

 START SLAVE;

這將在您的資料目錄中建立一個名為 master.info 的檔案,通常為 /var/lib/mysql/master.info; 此檔案將包含從伺服器配置和狀態。

待辦事項

Oct 15 21:11:19 builder mysqld[4266]: 101015 21:11:19 [Warning] Neither --relay-log nor --relay-log-index were used; so
  replication may break when this MySQL server acts as a slave and has his hostname changed!! Please use
  '--relay-log=mysqld-relay-bin' to avoid this problem.

檢查複製

[編輯 | 編輯原始碼]

在從伺服器上

[編輯 | 編輯原始碼]

在從伺服器上,鍵入

 SHOW SLAVE STATUS;

或更多,以獲得更易讀(基於行的)輸出

 SHOW SLAVE STATUS\G

示例

*************************** 1. row ***************************
             Slave_IO_State: 
                Master_Host: master_addr
                Master_User: myreplication
                Master_Port: 3306
...

特別檢查

           Slave_IO_Running: Yes
          Slave_SQL_Running: Yes

您可以檢查複製的非同步性質

      Seconds_Behind_Master: 0

另請參閱

mysql> SHOW GLOBAL VARIABLES LIKE "%SLAVE%";

在主伺服器上

[編輯 | 編輯原始碼]

您可以在程序列表中看到來自從伺服器的連線。

mysql> SHOW PROCESSLIST\G
[...]
*************************** 6. row ***************************
     Id: 14485
   User: myreplication
   Host: 10.1.0.106:33744
     db: NULL
Command: Binlog Dump
   Time: 31272
  State: Has sent all binlog to slave; waiting for binlog to be updated
   Info: NULL

如果您啟用了 report-host,從伺服器也可見於

mysql> SHOW SLAVE HOSTS;
+-----------+---------+------+-------------------+-----------+
| Server_id | Host    | Port | Rpl_recovery_rank | Master_id |
+-----------+---------+------+-------------------+-----------+
|         2 | myslave | 3306 |                 0 |         1 | 
+-----------+---------+------+-------------------+-----------+
1 row in set (0.00 sec)

一致性

[編輯 | 編輯原始碼]

請注意,這種複製是一種簡單的重放,類似於將 mysqldump 輸出饋送到 mysql 客戶端。 因此,要保持一致性

  • 避免在從伺服器上寫入關鍵資料
  • 在主伺服器和從伺服器上都使用相同的資料啟動複製
  • 要測試:我們懷疑最好在主伺服器和從伺服器上使用相同版本的 MySQL

預設情況下,複製將在遇到錯誤時停止。 如果您的主伺服器和從伺服器在開始時不一致,或者由於網路錯誤導致查詢格式錯誤,則可能會發生這種情況。

在這種情況下,您將在系統日誌(通常為 /var/log/syslog)中獲得跟蹤

Oct 15 21:11:19 builder mysqld[4266]: 101015 21:11:19 [ERROR] Slave: Error 'Table 'mybase.form'
  doesn't exist' on query. Default database: 'mybase'.  Query:
  'INSERT INTO `form` (`form_id`,`timestamp`,`user_id`) VALUES ('abed',1287172429,0)',
  Error_code: 1146

最好的方法是完全重置複製。

您也可以手動修復錯誤,然後要求 MySQL 以這種方式跳過 1 條語句

STOP SLAVE;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
START SLAVE;

您可以將 SQL_SLAVE_SKIP_COUNTER 設定為任何數字,例如 100。 請注意,在這種情況下,它將跳過有效語句和無效語句,而不僅僅是錯誤。


另一種修復損壞複製的方法是使用 Maatkit 工具。

  • mk-slave-restart(如果存在更多錯誤,並且 SQL_SLAVE_SKIP_COUNTER 無濟於事,則重新啟動從伺服器上的複製)
  • mk-table-checksum(在主伺服器和從伺服器上執行表的校驗和)
  • mk-table-sync(根據 mk-table-checksum 生成的統計資訊,將從伺服器與主伺服器同步)

解除安裝

[編輯 | 編輯原始碼]

要擦除複製

  • 鍵入
mysql> RESET SLAVE;
  • 注意:此時,MySQL 暫停了從伺服器並使用預設值替換了配置。 master.info 檔案也被刪除。
  • 重新啟動 MySQL 以清除所有配置。

警告:STOP SLAVE 將停止複製。 它可以手動重新啟動,或者(預設情況下)如果您重新啟動 MySQL 伺服器,它將自動恢復。 為了在啟動過程中避免複製的自動啟動,請在您的配置檔案中新增

slave-skip-start 

如果您想永久停止複製(並將伺服器用於其他目的),則需要如上所述重置配置。

此時,您的從伺服器配置應該完全為空

mysql> SHOW SLAVE STATUS;
Empty set (0.00 sec)

SQL 提示

[編輯 | 編輯原始碼]

一些提示可以放在每個有關複製的請求之前的註釋中。 例如透過 PHP Mysqlnd 外掛(用於本機驅動程式)。[1]

  • MYSQLND_MS_MASTER_SWITCH:強制在主伺服器上執行請求。
  • MYSQLND_MS_SLAVE_SWITCH:強制在從伺服器上執行請求。
  • MYSQLND_MS_LAST_USED_SWITCH:強制在最後使用的伺服器上執行請求。

聯合表

[編輯 | 編輯原始碼]

作為複製和叢集的替代方案,MySQL Federated 儲存引擎允許您在伺服器上建立一個表,該表與另一個伺服器上的相同表同步。

參考文獻

[編輯 | 編輯原始碼]
華夏公益教科書