原文地址:https://chanjarster.github.io...html
本文對應代碼:githubmysql
用Docker部署基於GTID的MySQL Master-Slave Replication例子。git
寫一個文件mysql-master.cnf
:github
[mysqld] server_id=1 binlog_format=ROW gtid_mode=ON enforce-gtid-consistency=true
這個配置文件把Master的server_id
設置爲1,要注意在同一個Master-Slave集羣裏,server_id
不能重複。sql
啓動Master:docker
docker run -d --name mysql-master \ -e MYSQL_USER=my_user \ -e MYSQL_DATABASE=my_database \ -e MYSQL_PASSWORD=my_database_password \ -e MYSQL_ROOT_PASSWORD=my_root_password \ -p 3307:3306 \ -v $(pwd)/mysql-master.cnf:/etc/mysql/conf.d/mysql-master.cnf \ mysql:8.0 \ --log-bin=my
寫一個文件mysql-slave-1.cnf
:bash
[mysqld] server_id=2 binlog_format=ROW gtid_mode=ON enforce-gtid-consistency=true read_only=ON
這個文件把Slave的server_id
設置爲2,若是你有多個Slave,那麼得分別設置不一樣的server_id
。此外,將Slave設置爲read_only
模式(這樣就不能在slave上執行寫操做了)。ide
啓動Slave:post
docker run -d --name mysql-slave-1 \ -e MYSQL_ROOT_PASSWORD=my_root_password \ -p 3308:3306 \ -v $(pwd)/mysql-slave-1.cnf:/etc/mysql/conf.d/mysql-slave-1.cnf \ mysql:8.0 \ --skip-log-bin \ --skip-log-slave-updates \ --skip-slave-start
到Master上建立Replication用戶:code
$ docker exec -it mysql-master mysql -u root -p Enter password: my_root_password mysql> CREATE USER 'repl'@'%' IDENTIFIED BY 'password'; mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
到Slave上把本身和Master關聯起來:
$ docker exec -it mysql-slave-1 mysql -u root -p Enter password: my_root_password mysql> CHANGE MASTER TO MASTER_HOST='192.168.101.21', MASTER_PORT=3307, MASTER_USER='repl', MASTER_PASSWORD='password', GET_MASTER_PUBLIC_KEY=1, MASTER_AUTO_POSITION=1;
注意MASTER_HOST
寫的是Master所在的Host的IP,MASTER_PORT
寫的是Master暴露在Host上的端口,MASTER_USER
和MASTER_PASSWORD
則是Replication用戶的信息。
最後正式啓動Slave:
mysql> START SLAVE;
到Slave上看看my_database是否存在:
$ docker exec -it mysql-slave-1 mysql -u root -p Enter password: my_root_password mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | my_database | | mysql | | performance_schema | | sys | +--------------------+ 5 rows in set (0.01 sec)
若是有就說明my_database從Master複製到了Slave上。
在github上也提供了docker-compose.yaml,操做過程和上述一致,只不過容器名字會有變化。
# 拉起Master和Slave $ docker-compose -p mysql-repl up # 鏈接Master $ docker exec -it mysql-repl_mysql-master_1 mysql -u root -p # 鏈接Slave $ docker exec -it mysql-repl_mysql-slave_1 mysql -u root -p
而且CHANGE MASTER TO
語句有所不一樣,使用的是Master的Service Name以及容器內端口3306
:
CHANGE MASTER TO MASTER_HOST='mysql-master', MASTER_PORT=3306, MASTER_USER='repl', MASTER_PASSWORD='password', GET_MASTER_PUBLIC_KEY=1, MASTER_AUTO_POSITION=1;
這個是由於Slave容器沒法訪問到Master的host。解決辦法我也不知道。
GET_MASTER_PUBLIC_KEY
在作本例子時出現過Slave沒法鏈接到Master的狀況:
2019-06-19T01:34:24.361566Z 8 [System] [MY-010597] [Repl] 'CHANGE MASTER TO FOR CHANNEL '' executed'. Previous state master_host='', master_port= 3306, master_log_file='', master_log_pos= 4, master_bind=''. New state master_host='mysql-master', master_port= 3306, master_log_file='', master_log_pos= 4, master_bind=''. 2019-06-19T01:34:28.274728Z 9 [Warning] [MY-010897] [Repl] Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. 2019-06-19T01:34:28.330825Z 9 [ERROR] [MY-010584] [Repl] Slave I/O for channel '': error connecting to master 'repl@mysql-master:3306' - retry-time: 60 retries: 1, Error_code: MY-002061 2019-06-19T01:35:28.333735Z 9 [ERROR] [MY-010584] [Repl] Slave I/O for channel '': error connecting to master 'repl@mysql-master:3306' - retry-time: 60 retries: 2, Error_code: MY-002061 2019-06-19T01:36:28.335525Z 9 [ERROR] [MY-010584] [Repl] Slave I/O for channel '': error connecting to master 'repl@mysql-master:3306' - retry-time: 60 retries: 3, Error_code: MY-002061 ...
詳細細節可見這個issue,這是由於MySQL 8默認啓用了caching_sha2_password authentication plugin,issue中提到了一個辦法:在啓動Slave的時候添加--default-auth=mysql_native_password
參數。不過我感受這個不太好,查閱相關文檔後發現能夠在CHANGE MASTER TO
添加GET_MASTER_PUBLIC_KEY=1
參數來解決這個問題。
更多詳情參考caching_sha2_password and Replication和CHANGE MASTER TO Syntax。