原文地址:https://chanjarster.github.io...

本文对应代码:github

用Docker部署基于GTID的MySQL Master-Slave Replication例子。

启动Master

写一个文件mysql-master.cnf

[mysqld]server_id=1binlog_format=ROWgtid_mode=ONenforce-gtid-consistency=true

这个配置文件把Master的server_id设置为1,要注意在同一个Master-Slave集群里,server_id不能重复。

启动Master:

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

启动Slave

写一个文件mysql-slave-1.cnf

[mysqld]server_id=2binlog_format=ROWgtid_mode=ONenforce-gtid-consistency=trueread_only=ON

这个文件把Slave的server_id设置为2,如果你有多个Slave,那么得分别设置不同的server_id。此外,将Slave设置为read_only模式(这样就不能在slave上执行写操作了)。

启动Slave:

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

创建Replication用户

到Master上创建Replication用户:

$ docker exec -it mysql-master mysql -u root -pEnter password: my_root_passwordmysql> CREATE USER 'repl'@'%' IDENTIFIED BY 'password';mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';

将Slave和Master关联

到Slave上把自己和Master关联起来:

$ docker exec -it mysql-slave-1 mysql -u root -pEnter password: my_root_passwordmysql> CHANGE MASTER TO   MASTER_HOST='192.168.101.21',  MASTER_PORT=3307,  MASTER_USER='repl',  MASTER_PASSWORD='password',  MASTER_AUTO_POSITION=1;

注意MASTER_HOST写的是Master所在的Host的IP,MASTER_PORT写的是Master暴露在Host上的端口,MASTER_USERMASTER_PASSWORD则是Replication用户的信息。

最后正式启动Slave:

mysql> START SLAVE;

验证

到Slave上看看my_database是否存在:

$ docker exec -it mysql-slave-1 mysql -u root -pEnter password: my_root_passwordmysql> show databases;+--------------------+| Database           |+--------------------+| information_schema || my_database        || mysql              || performance_schema || sys                |+--------------------+5 rows in set (0.01 sec)

如果有就说明my_database从Master复制到了Slave上。

已知问题

Slave无法使用hostname来链接Master

本例子中使用的MySQL Docker镜像自带了一个配置文件位置在/etc/mysql/conf.d/docker.cnf,它里面配置了:

[mysqld]skip-host-cacheskip-name-resolve

注意skip-name-resolve,因为这个配置,在MASTER_HOST里只能写IP,不能写hostname,否则就解析不到。这个可以观察Slave的日志看到:docker logs -f mysql-slave-1

本例在Mac上无法工作

这个是因为Slave容器无法访问到Master的host。解决办法我也不知道。

参考资料

  • Setting Up Replication Using GTIDs
  • Binary Logging Options and Variables
  • Replication Slave Options and Variables
  • DNS Lookup Optimization and the Host Cache
  • CHANGE MASTER TO Syntax