當主庫存在歷史數據時如何完成全量Mysql主從復制
上一篇文章介紹了docker+mysql的主從復制的搭建,使用docker有許多優點:可以輕松實現跨平台的移植、docker容器之間不會互相影響、容器內部不會污染宿主機的環境等等。如果大家還沒有接觸docker,建議先去了解一下docker的使用教程,當然了,不會docker也不影響學習解決該問題的大體步驟。
前提:
當決定使用Mysql主從復制的數據庫架構時,可能你的工程已經運行了一段時間,這是很常見的場景,比如目前我負責的一個項目,我想改變生產環境的單節點數據庫的現狀,通過主從復制為讀寫分離作鋪墊。那么就需要兩台及以上的節點作為數據庫節點,這里所謂的節點不僅僅指服務器,也可能是同一台服務器,不同端口,使用docker進行隔離。
可是我在配置完主從復制后發現,主節點已經存在的數據並沒有同步到從節點,當主節點向數據庫寫數據時,從節點重復這些操作,可從節點本身根本沒有創建那些主節點的庫,導致運行出錯、IO線程壞死,最終從節點掛掉
教程開始
查看主庫的已有數據庫
show databases;
假設其中test數據庫是我們想要主從同步的數據庫,模擬生產環境,該數據庫中已經有了很多數據
use test;
select * from user;
鎖定主數據庫
鎖定主數據庫,只允許讀取不允許寫入,這樣做的目的是防止備份過程中或備份完成之后有新數據插入,導致備份數據和主數據數據不一致,同樣,這樣做也有弊端,可能在鎖庫期間會影響正常的業務流程,所以我們應使鎖庫的粒度盡可能小。
flush tables with read lock;
查詢主數據庫狀態,並記下FILE及Position的值
show master status;
開始備份主數據庫
退出mysql終端,執行docker mysql備份命令
docker exec [CONTAINER] /usr/bin/mysqldump -u username --password=xxx [DATABASE] > back.sql
[CONTAINER] 是你自己容器的名字, [DATABASE]是你自己數據庫的名字,back.sql是臨時產生的備份文件,里面是sql語句, username是你自己的用戶名,一般是root,xxx則是你自己的用戶密碼。該命令的意思是執行docker容器內mysql相關命令:mysqldump,將指定的數據庫導出到宿主機當中
我們這里只需要備份test數據庫,若要備份全部數據庫,[DATABASE]處使用--all-databases
在宿主機上執行下列語句
圖中的warnming是因為我們在命令行輸入了密碼,所以會有安全警告信息。可以看到,已經在宿主機上生成了back.sql,
開始導入從數據庫
在導入備份文件之前,需要在從庫中手動建立相應的同名庫CREATE DATABASE test;
,否則會出現如下報錯
找不到相關數據庫
在手動創建完數據庫后執行下列語句
cat back.sql | docker exec -i [CONTAINER] /usr/bin/mysql -u username --password=xxx [DATABASE]
備份成功
之后就可以開始進行主從模式的配置了,具體可以參考我這篇文章docker+mysql的主從復制的搭建
記住配置完要解鎖主庫
unlock tables;