前提
由于沒有多台伺服器, 是以這裡改用docker啟動多個mysql服務, docker安裝指引可見: debian安裝docker
我的linux伺服器是debian的, 是以這裡以debian為例
另外, 需要在主控端連接配接docker的mysql服務, 需要在主控端安裝mysql服務, mysql安裝指引可見: linux安裝mysql
這裡我的虛拟機的ip為: 192.168.226.137
前期準備
- 通路mysql的docker鏡像源, 并找到所需mysql版本
- 拉取mysql鏡像,
docker pull mysql:8.0.18
- 在/var/mysql下建立對應檔案夾, 用于docker目錄映射到實體機的目錄
-
在mysqlConf1和mysqlConf2下分别建立對應的mysql配置檔案
mysql1配置:
sudo vi mysqlConf1/101.cnf
mysql2配置:[mysqld] log-bin=mysql-bin server-id=101
sudo vi mysqlConf2/102.cnf
[mysqld] log-bin=mysql-bin server-id=102
- 啟動兩個mysql服務
docker run -itd --name mysql1 -v /var/mysql/mysqlConf1:/etc/mysql/conf.d -v /var/mysql/mysql1:/var/lib/mysql -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.18
docker run -itd --name mysql2 -v /var/mysql/mysqlConf2:/etc/mysql/conf.d -v /var/mysql/mysql2:/var/lib/mysql -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.18
- 檢視docker服務狀态
docker ps
- 嘗試連接配接mysql服務
同理可連接配接mysql2的3308端口mysql -h 127.0.0.1 -P 3307 -u root -p
- 建立有遠端同步權限賬戶
create user 'replicate'@'%' identified with caching_sha2_password by '123456';
低版本的mysql用
create user 'replicate'@'%' identified by '123456';
grant replication slave on *.* to 'replicate'@'%';
- 登入主服mysql,查詢master狀态
mysql -h 127.0.0.1 -P 3307 -u root -p
show master status;
- 登入從服mysql,設定與主伺服器相關的配置參數
change master to master_host='192.168.226.137',master_port=3307,master_user='replicate',master_password='123456',master_log_file='mysql-bin.000003',master_log_pos=340;
master_host: docker的位址, 不能寫127.0.0.1
master_user: 在主庫建立的使用者, 步驟8中建立的使用者
master_port: 主庫的端口, 預設3306
master_log_pos: 主庫show master status;查詢出的Position
- 在從服mysql, 啟動slave,
start slave;
- 檢視從服狀态
show slave status \G;
驗收
- 在主服建立資料庫,
create database test
- 連接配接從服, 檢視資料庫清單,
show databases;
- 此時從服已經有test資料庫, 表示主從備份成功
其他問題
出現同步錯誤後, 後續同步不執行
若在主從同步的過程中,出現其中一條語句同步失敗報錯了,則後面的語句也肯定不能同步成功了。例如,主庫有一個資料庫,而從庫并沒有,然而,在主庫執行了删除這個資料庫的操作,那麼從庫沒有這麼資料庫就肯定删除不了,進而報錯了。在此時的從資料庫的資料同步就失敗了,是以後面的同步語句就無法繼續執行。
這裡提供的解決方法有兩種:
-
在從資料庫中,使用SET全局sql_slave_skip_counter來跳過事件,跳過這一個錯誤,然後執行從下一個事件組開始。
#在從資料庫上操作
mysql > stop slave; mysql > set global sql_slave_skip_counter=1; mysql > start slave;
- 想辦法(例如, 資料庫遷移等)令從庫與主庫的資料結構和資料都一緻了之後,再來恢複主從同步的操作。
start slave;
重新建立容器後, 建立的容器一直在重新開機
修改docker鏡像版本時, 把容器remove了重建建立, 但是建立的容器卻在啟動後馬上退出了
檢視容器日志
發現報錯:
InnoDB: Table flags are 0 in the data dictionary but the flags in file ./ibdatal are 0x4800!
原來是我remove的容器在主控端有生成對應的db檔案, 這裡不需要保留, 直接删除即可, 删除完在
docker start 容器名
即可
secure_file_priv
啟動容器後, 報以下錯誤:
failed to access directory for --secure-file-priv. please make sure that directory exists and is accessible by MYSQL Server. Supplied value: /var/lib/mysql-files
這裡主要是mysql8.0+的檔案路徑從原來的
/var/lib/mysql
調整為了
/var/lib/mysql-files
解決上述報錯的方法有:
- 不調整docker-compose内容, 在代碼庫設定裡, 加上
secure_file_priv=/var/lib/mysql
[mysqld] log-bin=mysql-bin server-id=101 secure_file_priv=/var/lib/mysql
- 修改docker啟動指令, 調整檔案路徑映射
docker run -itd --name mysql1 -v /var/mysql/mysqlConf1:/etc/mysql/conf.d -v /var/mysql/mysql1:/var/lib/mysql-files -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.18
Error Code: 1872. Slave failed to initialize relay log info structure from the repository
進行主從複制執行start slave時, 報錯:
Error Code: 1872. Slave failed to initialize relay log info structure from the repository
原因: 之前配置主從時, 已經執行過一次
change master to
的指令,這次再次執行
change master to
,2次的pos值不一樣。
解決方法:可以在從服通過
reset slave
重置slave
# 重置slave
reset slave;
# 執行同步
CHANGE MASTER TO MASTER_HOST='IP位址', MASTER_PORT='端口号', MASTER_USER='使用者名', MASTER_PASSWORD='密碼', MASTER_LOG_FILE='binlog',MASTER_LOG_POS=位置;
# 啟動slave
start slave;
# 檢視slave狀态
show slave status\G;