为什么基于Docker搭建?
- 资源有限
- 虚拟机搭建对机器配置有要求,并且安装mysql步骤繁琐
- 一台机器上可以运行多个
Docker容器 Docker容器之间相互独立,有独立ip,互不冲突Docker使用步骤简便,启动容器在秒级别
利用Docker搭建主从服务器
首先拉取docker镜像,我们这里使用5.7版本的mysql。然后使用此镜像启动容器,这里需要分别启动主从两个容器。
docker pull mysql:5.7
maseter-msql主容器对外映射的端口是3339,slave-mysql从容器对外映射的端口是3340。
因为docker容器是相互独立的,每个容器有其独立的ip,所以不同容器使用相同的端口并不会冲突。所以两个容器内的mysql使用默认的3306端口,否则可能会出现无法通过ip连接docker容器内mysql的问题。
Master(主):docker run -p 3339:3306 --name master-mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
Slave(从):docker run -p 3340:3306 --name slave-mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7使用
docker ps命令查看正在运行的容器:greamrod@greamrod-cp:/mnt/c/Users/11475$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 695a89694c2a mysql:5.7 "docker-entrypoint.s…" 11 seconds ago Up 11 seconds 33060/tcp, 0.0.0.0:3340->3306/tcp, :::3340->3306/tcp slave-mysql d591c009f048 mysql:5.7 "docker-entrypoint.s…" 17 seconds ago Up 16 seconds 33060/tcp, 0.0.0.0:3339->3306/tcp, :::3339->3306/tcp master-mysql greamrod@greamrod-cp:/mnt/c/Users/1147使用如下指令,进入容器内部:
# 进入 master-mysql 容器内部 docker exec -it master-mysql /bin/bash # 进入 slave-mysql 容器内部 docker exec -it slave-mysql /bin/bash配置Master(主)
进入
master-mysql容器: ```bash使用
master-mysql容器名称 进入具体某个容器docker exec -it master-mysql /bin/bash
或者(二选一)
d591c009f048 是master-mysql容器的ID
docker exec -it d591c009f048 /bin/bash
`docker`容器没有自带的`vim`,我们需要自行安装:
```bash
# 更新 apt-get
apt-get update
# 安装 vim 软件
apt-get install vim
进入master-mysql主容器,修改mysql(主数据库)的my.cnf配置文件,对设置server-id、log-bin、log-bin-index进行设置,配置如下。
# 进入到`my.cnf`编辑界面
vim /etc/mysql/my.cnf
===================================== 分割线 =======================================
# 对`my.cnf`新增如下修改
[mysqld]
server-id=1
log-bin=master-bin
log-bin-index=master-bin.index

从新启动master-mysql主容器中的msyql服务。
service mysql restart
进入master-mysql主容器,并查看容器的独立ip
greamrod@greamrod-cp:/mnt/c/Users/11475$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
695a89694c2a mysql:5.7 "docker-entrypoint.s…" 15 hours ago Up 15 hours 33060/tcp, 0.0.0.0:3340->3306/tcp, :::3340->3306/tcp slave-mysql
d591c009f048 mysql:5.7 "docker-entrypoint.s…" 15 hours ago Up 15 hours 33060/tcp, 0.0.0.0:3339->3306/tcp, :::3339->3306/tcp master-mysql
greamrod@greamrod-cp:/mnt/c/Users/11475$
greamrod@greamrod-cp:/mnt/c/Users/11475$
greamrod@greamrod-cp:/mnt/c/Users/11475$ docker inspect --format='{{.NetworkSettings.IPAddress}}' master-mysql
172.17.0.2
greamrod@greamrod-cp:/mnt/c/Users/11475$

进入master-mysql的主容器的mysql(主数据库)中,使用show master status;查看mysql(主数据)的详细信息:
# master-mysql(主数据库容器)
greamrod@greamrod-cp:/mnt/c/Users/11475$ docker exec -it master-mysql /bin/bash
root@d591c009f048:/#
root@d591c009f048:/#
root@d591c009f048:/# mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.34-log MySQL Community Server (GPL)
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000002 | 617 | | | |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

在mysql(主数据库)中创建数据同步用户。
mysql> CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
Query OK, 0 rows affected (0.01 sec)
配置Slave(从)
进入slave-mysql从容器,修改mysql(从数据库)的my.cnf配置文件,对设置server-id、relay-log-index、relay-log进行设置,配置如下。
# 进入到`my.cnf`编辑界面
vim /etc/mysql/my.cnf
===================================== 分割线 =======================================
# 对`my.cnf`新增如下修改
server-id=2
relay-log=slave-relay-bin
relay-log-index=slave-relay-bin.index

从新启动slave-mysql从容器中的msyql服务。
service mysql restart
进入slave-mysql的从容器的mysql(从数据库)中,执行如下指令:
- master_host :主容器的独立
ip,可以通过docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器名称|容器id查看。 - master_port:主容器中的
mysql(主数据库)端口号。 - master_user:在主容器中的
mysql(主数据库),创建数据同步用户名。 - master_password:在主容器中的
mysql(主数据库),创建数据同步密码。 - master_log_file:指定
mysql(从数据库)从哪个日志文件开始复制数据,对应mysql(主数据库)中提到的File字段的值 - master_log_pos:对应
mysql(主数据库)中提到的Position字段的值。 master_connect_retry:如果连接失败,重试的时间间隔,单位是秒,默认是
60秒。mysql> change master to master_host='172.17.0.2', master_user='slave', master_password='123456', master_port=3306, master_log_file='master-bin.000002', master_log_pos=617, master_connect_retry=30; Query OK, 0 rows affected, 2 warnings (0.02 sec)正常情况下,
SlaveIORunning和SlaveSQLRunning都是No,因为我们还没有开启主从复制过程。开启主从复制过程。
mysql> start slave; Query OK, 0 rows affected (0.01 sec)查询主从同步状态。
SlaveIORunning和SlaveSQLRunning都是Yes,说明主从复制已经开启。此时可以测试数据同步是否成功。
mysql> show slave status \G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.17.0.2
Master_User: slave
Master_Port: 3306
Connect_Retry: 30
Master_Log_File: master-bin.000002
Read_Master_Log_Pos: 617
Relay_Log_File: slave-relay-bin.000002
Relay_Log_Pos: 321
Relay_Master_Log_File: master-bin.000002
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 617
Relay_Log_Space: 528
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: bc3b0f85-bf99-11eb-abc9-0242ac110002
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)

主从复制排错
使用start slave开启主从复制过程后,如果SlaveIORunning一直是Connecting,则说明主从复制一直处于连接状态,这种情况一般是下面几种原因造成的,我们可以根据Last_IO_Error提示予以排除:
- 网络不通:检查
ip端口 - 密码不对:检查是否创建用于同步的用户和用户密码是否正确
master_log_pos不对:检查主容器中msyql主数据库的Position。
基于MySQL 8.0 镜像搭建时,遇到的错误

进入主容器的msyql主数据库中,将同步用户的 plugin=caching_sha2_password 修改为 plugin=mysql_native_password
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
mysql> SELECT plugin FROM mysql.`user` where user = 'slave';
+-----------------------+
| plugin |
+-----------------------+
| caching_sha2_password |
+-----------------------+
1 row in set (0.00 sec)
mysql> ALTER USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
Query OK, 0 rows affected (0.01 sec)
mysql> SELECT plugin FROM mysql.`user` where user = 'slave';
+-----------------------+
| plugin |
+-----------------------+
| mysql_native_password |
+-----------------------+
1 row in set (0.00 sec)
使用Navicat连接
使用navicat分别链接 主、从数据库 进行测试链接。往主数据库中导入一个sql文件,从数据库中会自动同步。
