通过docker实现mysql一主多从

当前情况

我目前手里只有一台服务器,上面部署了一个mysql服务,把这个服务作为主节点,用来写数据,另外的两个mysql节点通过docker来分别部署,这两个节点作为从节点。

各位可以相对的做参考就好,如果多台mysql来做主从,其实就是mysql里配置一下的事。如果是像我这种,可能就是多几步docker的执行操作,也没太大的区别

原料准备

  • Linux上安装部署mysql,这个可以参考我之前的文章点击查看
  • 如果需要像我一样安装docker,查看这里
  • 拉取mysql镜像,建议根据主节点版本来指定版本,我的本机主节点版本是8.0
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

四、测试读写

完成上述配置后,在主节点进行数据写入,写入完成后进从节点查看是否成功同步数据,如果已同步则表示成功。

相关推荐
todoitbo9 小时前
从 MySQL 到 KingbaseES:Database、Schema、User 一次讲透
数据库·mysql·国产数据库·kingbasees
梦想的颜色9 小时前
硬核|Docker从入门到精通:镜像构建、仓库推送、Compose编排、生产部署全攻略
运维·服务器·docker·容器·部署·环境·镜像
千云9 小时前
100w大表0停机回滚:我们为什么放弃Undo Log,选择表名切换?
数据库·后端·mysql
SXJR9 小时前
使用docker 部署向量数据库Milvus
数据库·docker·容器·milvus·向量数据库
AC赳赳老秦9 小时前
用 OpenClaw 制定技术学习计划:根据目标岗位自动生成学习路线、推荐学习资源
开发语言·c++·人工智能·python·mysql·php·openclaw
qq_452396239 小时前
第二篇:《K8s 集群搭建:Minikube、kubeadm、Kind 对比与实操》
容器·kubernetes·kind
前进的李工9 小时前
MySQL性能优化:索引与子查询实战技巧
数据库·sql·mysql·性能优化
段ヤシ.10 小时前
回顾Java知识点,面试题汇总Day13:数据库MySQL(持续更新)
java·数据库·mysql
jingqiulyue10 小时前
docker run出现exited或者不断restart怎么办
docker·容器
小哈里10 小时前
【K8S】OCI标准下的企业级镜像治理:Harbor+Skopeo+Trivy 最佳实践
云原生·容器·kubernetes·harbor·镜像·skopen