当前情况
我目前手里只有一台服务器,上面部署了一个mysql服务,把这个服务作为主节点,用来写数据,另外的两个mysql节点通过docker来分别部署,这两个节点作为从节点。
各位可以相对的做参考就好,如果多台mysql来做主从,其实就是mysql里配置一下的事。如果是像我这种,可能就是多几步docker的执行操作,也没太大的区别
原料准备
bsah
docker pull mysql:8.0
开始搭建
一、配置本地主节点
1、修改主节点 MySQL 配置,编辑本地 MySQL 的配置文件(通常是 my.cnf 或 my.ini)
yaml
[mysqld]
# 必须唯一
server-id = 1
# 开启 binlog
log-bin = mysql-bin
# 可选:指定需要复制的数据库(不指定则复制所有)
# binlog-do-db = your_database
# 可选:忽略不需要复制的数据库
# binlog-ignore-db = mysql,information_schema,performance_schema
# 使用 ROW 格式,兼容性更好
binlog_format = ROW
# 保证事务安全
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1
2. 重启本地 MySQL 服务
bash
sudo systemctl restart mysql
3. 创建复制用户并授权
bash
-- 创建专用复制用户
CREATE USER '自己写个用户名替换'@'%' IDENTIFIED BY '替换你自己的密码,要记好,后面用';
-- 授予复制权限
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
-- 刷新权限
FLUSH PRIVILEGES;
4. 锁定数据库并获取 binlog 位置
sql
-- 锁定所有表,防止数据写入
FLUSH TABLES WITH READ LOCK;
-- 查看当前 binlog 文件名和位置(记录下来!)
SHOW MASTER STATUS;
输出内容大致如下:

记录 File 和 Position,后面配置从节点时需要用到。
5. 导出主节点数据(如果已有数据)
另开一个终端窗口导出数据(不要关闭上面的 MySQL 会话,保持锁):
bash
mysqldump -u root -p --all-databases --single-transaction --master-data=2 > master_data.sql
导出完成后,回到 MySQL 会话解锁:
sql
UNLOCK TABLES;
二、部署 Docker 从节点(Slave)
1、准备从节点配置文件
创建两个配置文件目录,具体目录位置可以自行更改,记好位置即可:
bash
mkdir -p ~/mysql-slave1/conf ~/mysql-slave1/data
mkdir -p ~/mysql-slave2/conf ~/mysql-slave2/data
在~/mysql-slave1/conf/和 ~/mysql-slave2/conf下分别创建对应的my.cnf文件
内容如下,注意:server-id必须不能一样!!!主节点是 1,两个从节点分别是 2 和 3:
yaml
[mysqld]
server-id = 2
relay-log = mysql-relay-bin
log-bin = mysql-bin
read_only = 1
2. 启动 Docker 容器
bash
# 启动从节点1
docker run -d \
--name mysql-slave1 \
--add-host=host.docker.internal:host-gateway \
-p 3307:3306 \
-e MYSQL_ROOT_PASSWORD=从节点1的mysql的密码 \
-e MYSQL_DATABASE=要复制的数据库 \
-v 宿主机my.cnf的位置:/etc/mysql/conf.d/my.cnf \
-v 宿主机data文件夹的位置:/var/lib/mysql \
mysql:8.0
# 启动从节点2
docker run -d \
--name mysql-slave2 \
--add-host=host.docker.internal:host-gateway \
-p 3308:3306 \
-e MYSQL_ROOT_PASSWORD=从节点2的mysql的密码 \
-e MYSQL_DATABASE=要复制的数据库 \
-v 宿主机my.cnf的位置:/etc/mysql/conf.d/my.cnf \
-v 宿主机data文件夹的位置:/var/lib/mysql \
mysql:8.0
# 示例,仅供参考
docker run -d \
--name mysql-slave1 \
--add-host=host.docker.internal:host-gateway \
-p 3307:3306 \
-e MYSQL_ROOT_PASSWORD=fgsdhfgdsjfgshj \
-e MYSQL_DATABASE=invoice_res_db \
-v /test/mysql-slave/node-1/conf/my.cnf:/etc/mysql/conf.d/my.cnf \
-v /test/mysql-slave/node-1/data:/var/lib/mysql \
mysql:8.0
注意:docker的host.docker.internal,macOS/Windows默认支持,通过host.docker.internal 访问宿主机,Linux需要额外配置,在启动容器时添加 --add-host=host.docker.internal:host-gateway,上述容器启动命令中已配置上,不需要的话可以移除
3. 导入主节点数据(如果有数据需要同步)
等待容器启动完成后,导入之前导出的数据:
bash
# 导入到 slave1
docker exec -i mysql-slave1 mysql -uroot -p从节点1的mysql的密码 < master_data.sql
# 导入到 slave2
docker exec -i mysql-slave2 mysql -uroot -p从节点2的mysql的密码 < master_data.sql
三、配置主从复制
以slave1 容器为例,slave2 容器也是一样的步骤
1、进入 slave1 容器:
slave2更换容器名称
bash
docker exec -it mysql-slave1 mysql -uroot -p
2、执行sql
sql
-- 停止复制(如果之前配置过)
STOP SLAVE;
-- 配置主节点信息
CHANGE MASTER TO
MASTER_HOST='host.docker.internal', -- Docker 访问宿主机的特殊域名,如果是直接通过其他服务器来部署的从节点,则输入对应的ip
MASTER_PORT=主节点端口,
MASTER_USER='主节点有复制权限的用户名',
MASTER_PASSWORD='主节点有复制权限用户的密码',
MASTER_LOG_FILE='mysql-bin.000001', -- 之前记录的 File
MASTER_LOG_POS=154, -- 之前记录的 Position
GET_MASTER_PUBLIC_KEY=1;
-- 启动复制
START SLAVE;
-- 查看状态
SHOW SLAVE STATUS\G
四、测试读写
完成上述配置后,在主节点进行数据写入,写入完成后进从节点查看是否成功同步数据,如果已同步则表示成功。