使用 percona 和 docker 的 MySQL 複製從站
我正在嘗試在 docker 容器中執行 MySQL 複製從屬。我們在生產環境中執行 MySQL 5.7.24-27-log,它來自 percona 儲存庫(Ubuntu 18.04)。
我曾經
xtrabackup
備份、準備和發送一個用於複製的起始數據集,然後我docker pull percona
像這樣啟動了 percona docker 映像():$ docker run --name mysql-replication -v /replication/data:/var/lib/mysql -v /replication/docker.cnf:/etc/mysql/docker.cnf:ro -e MYSQL_ROOT_PASSWORD=xxxx -P -d percona
我的 docker.cnf 只記錄了伺服器 ID(我從
percona
圖像中複製了它)。[mysqld] skip-host-cache skip-name-resolve bind-address = 0.0.0.0 server-id = 4
然後使用
CHANGE MASTER
等。我的複制執行得很好。我的意圖(根據卷掛載
-v /replication/data:/var/lib/mysql
)是將所有 MySQL 數據保留在主機上,並將複製 docker 容器視為臨時的,即容器中沒有狀態。server-id
如果我需要通過停止現有容器、將數據複製到別處、更改並執行新容器來啟動另一個複制容器,也應該很容易。為了測試這一點,在它設置並正常執行後(我看了
Seconds_Behind_Master
下拉菜單0
),我想我應該能夠刪除容器並重新創建它,並且複制仍然可以正常工作。因此我嘗試了這個:$ docker stop mysql-replication $ docker rm mysql-replication $ docker run ... // same command as before
當我這樣做並連接到在容器中執行的 MySQL 時,我發現它
Slave_IO_Running
是No
,並且在啟動它 (START SLAVE;
) 後,我得到以下資訊(如中所示SHOW SLAVE STATUS;
):Last_Error: Could not execute Update_rows event on table databasename.tablename; Can't find record in 'tablename', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin.000681, end_log_pos 9952
(
databasename
並且tablename
是真實的數據庫和表名)起初我以為我可能搞砸了,但我現在已經嘗試了很多次來嘗試解決問題。使用
docker diff mysql-replication
顯示對正在執行的容器沒有任何變化,這似乎很重要:$ docker diff mysql-replication C /run C /run/mysqld A /run/mysqld/mysqld.pid C /var C /var/log A /var/log/mysql
Google搜尋建議我需要使用
RESET SLAVE;
,START SLAVE;
但這似乎無法解決它 - 就像數據(容器外部)不再與主伺服器同步,因此複製無法繼續。任何人都可以在我正在做的事情中找出漏洞嗎?
非常感謝。
此問題的根本原因是文件中缺少該
relay-log
選項mysql.cnf
(或者在這種情況下,由於 docker 卷掛載,該docker.cnf
文件)。這會導致文件的創建和使用,例如89726507f176-relay-bin.000002
最初,89726507f176
機器的主機名在哪裡(在創建映像時由 docker 守護程序隨機分配)。當容器停止、刪除和重新創建時,會創建和使用一組新文件(例如be0c801d95bc-relay-bin.000407
),但這會導致同步問題。
relay-log
通過在文件中明確指定一個值,docker.cnf
可以毫無問題地刪除和重新創建容器。作為旁注,我還建議 /var/log/mysql 目錄沒有被掛載存在問題 - 事實並非如此。但是,如果您指定了一個值,
log_bin = /var/log/mysql/mysql-bin.log
例如,那麼這是一個要求。如果您不指定此路徑,則二進制日誌似乎儲存在本地 /var/lib/mysql 中,該 /var/lib/mysql 已安裝在容器外部。我的最終
docker.cnf
文件如下:[mysqld] skip-host-cache skip-name-resolve bind-address = 0.0.0.0 binlog-ignore-db = mysql replicate-ignore-db = mysql log_bin = /var/log/mysql/mysql-bin.log relay-log = replication-1 server_id = 1
注意:
server_id = 2
在複製從站上。另請注意,如果沒有該
relay-log
選項,該命令SHOW MASTER STATUS;
不會在主數據庫容器上返回任何結果。還有一個可能的未決問題,預設情況下,當您使用
docker stop
它時,它會要求容器終止(通過向 docker entrypoint 命令發送 SIGHUP),如果它沒有在 10 秒內終止,則會被強制停止。我需要確保有足夠的時間來關閉它,因為在負載下可能需要一段時間才能自行解決,結果可能導致數據失去。