本文分成以下几步来说明如何基于 Docker 来搭建 MySQL 的主从复制:
准备两台 MySQL 服务器
配置主服务器(Master)
配置从服务器(Slave)
完成Master和Slave链接
测试配置是否成功
1. 准备两台 MySQL 服务器(5.7)
使用 Docker 创建 MySQL 服务器很简单:
docker run --name mysql_master -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:latest
命令解释:
通过镜像 mysql:latest 启动一个名为 mysql_master 的 MySQL 服务器,端口号是3306,映射的宿主机端口号是3306,root 账号密码是123456
使用同样的方式创建 Slave 服务器:
docker run --name mysql_slave -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:latest
使用 docker ps
查看当前运行的容器,如下:
正在运行中的容器
我们还需要知道这两台服务器的 IP 地址,结果如下:
查看服务器IP地址
Master 服务器地址是 172.17.0.2 ,Slave 服务器地址是 172.17.0.3,MySQL 的端口号都为 3306。
好了,到现在为止,我们已经有了两台 MySQL 服务器。
2. 配置主服务器(Master)
首先,进入到 Master 服务器。
docker exec -it c66b935ea94d /bin/bash
c66b935ea94d 是 mysql_master 的容器id。
效果图如下:
进入 Master 服务器
service mysql status
这个命令是查看 mysql 服务的状态,可以看到当前服务器正在运行当中,版本是 5.7.18。搭建主从复制时,最好保持版本的一致。
修改配置文件--my.cnf:
[mysqld] ## 设置server_id,一般设置为IP,同一局域网内注意要唯一 server_id=100 ## 复制过滤:也就是指定哪个数据库不用同步(mysql库一般不同步) binlog-ignore-db=mysql ## 开启二进制日志功能,可以随便取,最好有含义(关键就是这里了) log-bin=edu-mysql-bin ## 为每个session 分配的内存,在事务过程中用来存储二进制日志的缓存 binlog_cache_size=1M ## 主从复制的格式(mixed,statement,row,默认格式是statement) binlog_format=mixed ## 二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。 expire_logs_days=7 ## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。 ## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致 slave_skip_errors=1062
在我的容器中,my.cnf 的路径是 /etc/mysql。
配置完成后重启 mysql ,使用如下命令:
service mysql restart
这个命令会使得容器停止,重新启动就可以了。
接下来创建数据同步用户:
CREATE USER 'slave'@'%' IDENTIFIED BY '123456'; GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
这里主要是要授予用户 slave REPLICATION SLAVE权限和REPLICATION CLIENT权限。
3. 配置从服务器(Slave)
修改配置文件--my.cnf
[mysqld] ## 设置server_id,一般设置为IP,注意要唯一 server_id=101 ## 复制过滤:也就是指定哪个数据库不用同步(mysql库一般不同步) binlog-ignore-db=mysql ## 开启二进制日志功能,以备Slave作为其它Slave的Master时使用 log-bin=edu-mysql-slave1-bin ## 为每个session 分配的内存,在事务过程中用来存储二进制日志的缓存 binlog_cache_size=1M ## 主从复制的格式(mixed,statement,row,默认格式是statement) binlog_format=mixed ## 二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。 expire_logs_days=7 ## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。 ## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致 slave_skip_errors=1062 ## relay_log配置中继日志 relay_log=edu-mysql-relay-bin ## log_slave_updates表示slave将复制事件写进自己的二进制日志 log_slave_updates=1 ## 防止改变数据(除了特殊的线程) read_only=1
配置完成后重启mysql,和配置 Master 一样,会使容器停止,需要启动容器。
4. 完成Master和Slave链接
注意,需要保证 Master 和 Slave 除了不同步的数据库,其他数据库的数据要一致。
在 Master 进入 MySQL, 然后执行命令:
show master status;
结果如下:
master status
记录下 File 和 Position 字段的值,后面会用到。
然后到 Slave 中进入 mysql,执行命令:
change master to master_host='172.17.0.2', master_user='slave', master_password='123456', master_port=3306, master_log_file='edu-mysql-bin.000001', master_log_pos=929, master_connect_retry=30;
命令解释:
master_host: Master 的IP地址 master_user: 在 Master 中授权的用于数据同步的用户 master_password: 同步数据的用户的密码 master_port: Master 的数据库的端口号 master_log_file: 指定 Slave 从哪个日志文件开始复制数据,即上文中提到的 File 字段的值 master_log_pos: 从哪个 Position 开始读,即上文中提到的 Position 字段的值 master_connect_retry: 当重新建立主从连接时,如果连接失败,重试的时间间隔,单位是秒,默认是60秒。
在 Slave 的 MySQL 终端执行查看主从同步状态
show slave status \G;
结果如下:
slave status
SlaveIORunning 和 SlaveSQLRunning 是No,表明 Slave 还没有开始复制过程。相反 SlaveIORunning 和 SlaveSQLRunning 是Yes表明已经开始工作了,因为我已经运行过了,所以我的显示的都是 Yes。
执行以下命令,开始开启主从同步:
start slave;
OK!
5. 测试配置是否成功
最后一步,测试是否可以同步。测试方法比较多,可以在 Master 中增加一个数据库,然后去 Slave 中查看是否同步过来了,如果没有成功,请仔细检查你的配置文件和配置过程。
以下示例:
主:
[mysqld]
server_id=100
binlog-ignore-db=mysql
log-bin=charge-mysql-bin
binlog_cache_size=10M
binlog_format=mixed
expire_logs_days=7
slave_skip_errors=1062
innodb_buffer_pool_size = 5G
innodb_log_file_size = 1G
max_connections=1000
log_bin_trust_function_creators=1
CREATE USER 'slave'@'%' IDENTIFIED BY 'Aa123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
show master status;
show binlog events\G
从:
[mysqld]
server_id=101
binlog-ignore-db=mysql
log-bin=charge-mysql-slave1-bin
binlog_cache_size=10M
binlog_format=mixed
expire_logs_days=7
slave_skip_errors=1062
relay_log=charge-mysql-relay-bin
log_slave_updates=1
read_only=1
super_read_only=1
innodb_buffer_pool_size = 5G
innodb_log_file_size = 1G
log_bin_trust_function_creators=1
max_connections=1000
change master to master_host='172.16.89.119', master_user='slave', master_password='Aa123456', master_port=3306, master_log_file='charge-mysql-bin.000001', master_log_pos=154, master_connect_retry=30;
master_host: Master 的IP地址
master_user: 在 Master 中授权的用于数据同步的用户
master_password: 同步数据的用户的密码
master_port: Master 的数据库的端口号
master_log_file: 指定 Slave 从哪个日志文件开始复制数据,即上文中提到的 File 字段的值 定死000001
master_log_pos: 从哪个 Position 开始读,即上文中提到的 Position 字段的值
master_connect_retry: 当重新建立主从连接时,如果连接失败,重试的时间间隔,单位是秒,默认是60秒。
show slave status \G
start slave;
主:
create user 'charge'@'%' identified by 'N#HvoBlIQLdy8NIR';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, PROCESS, REFERENCES, INDEX, ALTER, SHOW DATABASES, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON *.* TO 'charge'@'%';
#revoke all privileges on *.* from 'charge'@'%';
#show grants for charge;
8.0
主:
[mysqld]
log-bin=mysql-bin
log-bin-index=master-bin.index
server-id=1
binlog_cache_size=10M
binlog_format=mixed
expire_logs_days=7
slave_skip_errors=1062
innodb_buffer_pool_size = 5G
innodb_log_file_size = 1G
max_connections=1000
log_bin_trust_function_creators=1
mysql>
CREATE USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY 'Aa123456';
GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%';
flush privileges;
SHOW MASTER STATUS;
从:
server-id=2
relay-log=relay-log
relay-log-index=relay-log.index
read_only=1
super_read_only=1
slave_skip_errors=1062
log_slave_updates=1
binlog_cache_size=10M
binlog_format=mixed
expire_logs_days=7
slave_skip_errors=1062
innodb_buffer_pool_size = 5G
innodb_log_file_size = 1G
max_connections=1000
log_bin_trust_function_creators=1
mysql>
change master to master_host='192.168.59.148', master_user='slave', master_password='Aa123456', master_port=3306, master_log_file='mysql-bin.000001', master_log_pos=828, master_connect_retry=30;
start slave;
show slave status\G
慢查询日志配置:
long_query_time=2
slow_query_log=1
log_queries_not_using_indexes=1
#slow_query_log_file="mysql_slow_query.log"
注意:本文归作者所有,未经作者允许,不得转载