docker环境下,配置MySQL一主一从,master负责写,slave负责读,从而做到读写分离。非docker环境下配置基本一样,这里为了安装MySQL方便使用docker容器,只需在docker中开2个MySQL。
一、环境准备
- 创建2个文件夹用于本机文件关联容器文件,只需修改本机文件容器中的文件也相应修改
mkdir -p /home/docker/mysql/c_master1
mkdir -p /home/docker/mysql/c_slave1
- 环境master1端口3306;slave1端口3307
- docker创建master1(注意该语句没有换行,这里为了方便查看)
docker run -p 3306:3306 --name master1
-v /home/docker/mysql/c_master1/conf:/etc/mysql/conf.d
-v /home/docker/mysql/c_master1/logs:/logs
-v /home/docker/mysql/c_master1/data:/var/lib/mysql
-e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7.36
- docker创建slave1(注意该语句没有换行,这里为了方便查看)
docker run -p 3307:3306 --name slave1
-v /home/docker/mysql/c_slave1/conf:/etc/mysql/conf.d
-v /home/docker/mysql/c_slave1/logs:/logs
-v /home/docker/mysql/c_slave1/data:/var/lib/mysql
-e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7.36
- docker创建MySQL完成后
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
08ae03ae6be1 mysql:5.7.36 "docker-entrypoint.s…" 25 hours ago Up 16 minutes 33060/tcp, 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp slave1
0fe58676575a mysql:5.7.36 "docker-entrypoint.s…" 25 hours ago Up 17 minutes 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp master1
二、配置Master(主)
- 进入master1的conf文件夹创建
my.cnf
[root@localhost conf]# cd /home/docker/mysql/c_master1/conf
[root@localhost conf]# vi my.cnf
[mysqld]
## 同一局域网内注意要唯一
server-id=1
## 开启二进制日志功能,可以随便取(关键)
log-bin=mysql-bin
- docker进入master1容器重启MySQL,docker重启MySQL会关闭容器,我们需要重启容器。
[root@localhost ~]# docker exec -it 0fe58676575a /bin/bash
root@0fe58676575a:/# service mysql restart
[root@localhost ~]# docker start 0fe58676575a
- 确保在master1主服务器上 skip_networking 选项处于 OFF 关闭状态, 这是默认值。如果是启用的,则从站无法与主站通信,并且复制失败。
mysql> show variables like '%skip_networking%';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| skip_networking | OFF |
+-----------------+-------+
1 row in set (0.01 sec)
- 在master1上创建一个专门用来复制同步的用户slave,授予用户 slave REPLICATION SLAVE权限和REPLICATION CLIENT权限,用于在主从库之间同步数据。
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
三、配置Slave(从)
- 和配置Master一样,在slave1的conf文件夹下创建
my.cnf
[root@localhost conf]# cd /home/docker/mysql/c_slave1/conf
[root@localhost conf]# vi my.cnf
[mysqld]
## 同一局域网内注意要唯一
server-id=2
## 开启二进制日志功能,可以随便取(关键)
log-bin=mysql-bin
- 配置完成后也需要和配置master1一样重启slave1的服务与docker容器
[root@localhost ~]# docker exec -it 08ae03ae6be1 /bin/bash
root@08ae03ae6be1:/# service mysql restart
[root@localhost ~]# docker start 08ae03ae6be1
四、链接master1与slave1
- 进入master1的MySQL执行
show master status;
记录File
和Position
字段的值后面将会用到,在后面的操作完成之前,需要保证master1不能做任何操作,否则将会引起状态变化,File和Position字段的值变化。
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000010 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
- 进入slave1的MySQL终端中执行
change master to master_host='172.17.0.2', master_user='slave', master_password='123456', master_port=3306, master_log_file='mysql-bin.000010', master_log_pos= 154, master_connect_retry=30;
mysql> change master to master_host='172.17.0.2', master_user='slave', master_password='123456', master_port=3306, master_log_file='mysql-bin.000010', master_log_pos= 154, master_connect_retry=30;
**master_host:**master1的docker地址,docker容器的独立IP地址可以通过以下命令查看docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器ID|容器名称
查询容器的IP
[root@localhost ~]# docker inspect --format='{{.NetworkSettings.IPAddress}}' 0fe58676575a
**master_port:**master1的端口号,指的是docker容器的内部端口,非暴露给宿主机的端口
**master_user:**在master1创建的用于数据同步的用户,这里创建的用户名是slave
**master_password:**在master1创建的用于数据同步的密码,这里创建的用户名密码是123456
**master_log_file:**指定 slave1从哪个日志文件开始复制数据,即上文中提到的 File 字段的值
**master_log_pos:**从哪个 Position 开始读,即上文中提到的 Position 字段的值
**master_connect_retry:**如果连接失败,重试的时间间隔,单位是秒,默认是60秒
- 在slave1的MySQL终端中执行
show slave status \G;
正常情况下,SlaveIORunning 和 SlaveSQLRunning 都是No,因为我们还没有开启主从复制过程。使用start slave
开启主从复制过程,然后再次查询主从同步状态show slave status \G;
SlaveIORunning 和 SlaveSQLRunning 都是Yes,说明主从复制已经开启。此时可以测试数据同步是否成功。
五、主从复制排错
- 使用
start slave
开启主从复制过程后,如果SlaveIORunning一直是Connecting,则说明主从复制一直处于连接状态,这种情况一般是下面几种原因造成的,我们可以根据 Last_IO_Error提示予以排除。
- 网络不通:检查ip,端口
- 密码不对:检查是否创建用于同步的用户和用户密码是否正确
- pos不对:检查Master的 Position
六、测试主从复制
- 在master1中随便创建一个test数据库,后在slave1中查看是否存在,在master1的test数据库中创建一张表,在slave1中查看是否存在