当前位置: 首页 > news >正文

Centos7.9 Docker26容器化部署 MySql9.4 一主一从的同步复制部署

Centos7.9 Docker26容器化部署 MySql9.4 一主一从的同步复制部署。我使用了一个mysql9.4:teamdhl-mysql-master 作为主库,一个mysql9.4:teamdhl-mysql-slave 作为从库,主库负责写入,从库负责查询。组成一主一从的同步复制架构。

我的实践过程:


第一次连接,不使用SSL,但MySQL 8.0+ 默认使用 caching_sha2_password 认证插件,该插件要求加密连接(SSL),失败


第一次连接,尝试将 repl 用户的认证插件改为不强制 SSL 的 mysql_native_password失败,错误原因是 MySQL 9.4 版本默认未加载 mysql_native_password 插件,该插件在高版本 MySQL 中已被弱化(默认仅支持 caching_sha2_password


第三次连接,尝试使用SSL连接,自动生成SSL证书,失败,在 MySQL 9.4 容器中,mysql_ssl_rsa_setup 命令已被移除,生成 SSL 证书的方式有所变化


第四次连接,尝试手动生成SSL证书并连接,成功

最终解决方案:手动配置SSL证书

步骤 1:为主库和从库准备自定义配置文件

主库 容器的配置文件夹conf/my.cnf (conf文件夹是本地文件夹,挂载的是容器的/etc/mysql/conf.d)

[mysqld]
# 开启二进制日志(从库依赖它复制数据)
log-bin=mysql-bin
# 主库唯一标识(1-2^32,从库需不同)
server-id=1
# 要同步的数据库(可指定多个,*表示所有,这里同步 ry-vue 库)
binlog-do-db=ry-vue
# 不需要同步的数据库(可选,如系统库 mysql 可忽略)
binlog-ignore-db=mysql
# SSL 配置
ssl-ca=/var/lib/mysql/ssl/ca.pem
ssl-cert=/var/lib/mysql/ssl/server-cert.pem
ssl-key=/var/lib/mysql/ssl/server-key.pem

从库 容器的配置文件夹conf/my.cnf(conf文件夹是本地文件夹,挂载的是容器的/etc/mysql/conf.d)

[mysqld]
# 从库唯一标识(必须与主库不同)
server-id=2
# 开启中继日志(从库复制主库 binlog 时的临时日志)
relay-log=relay-log
# 从库只读(普通用户无法写)
read_only=1
# 禁止 root 用户在从库写
super_read_only=1

**注意:在主从数据库都要有相同的数据库(在准备的时候),主库配置文件 my.cnf 中 binlog-do-db=ry-vue 可知道,主从库中都要有名为 ry-vue 的数据库才可以同步复制,不然在从库内部会执行 SHOW REPLICA STATUS\G; 时会报错 Last_Errno: 1049(未知数据库)。**具体如何解决放在文章最后面。

预防措施

为避免此类问题,建议:

  1. 在主库创建数据库后,先手动在从库创建同名数据库,再执行表结构或数据操作。

  2. 若希望主库自动同步数据库创建操作,可在主库配置中

    删除 binlog-do-db 限制

    (即不指定同步特定库,默认同步所有库):

    ini

    # 编辑主库 my.cnf,注释或删除以下行
    # binlog-do-db=ry-vue
    

    重启主库后,主库的

    CREATE DATABASE
    

    相关操作会自动同步到从库。

步骤 2:在主库容器中手动生成 SSL 证书

bash

# 进入主库容器
docker exec -it teamdhl-mysql-master bash# 创建证书目录
mkdir -p /var/lib/mysql/ssl
cd /var/lib/mysql/ssl# 使用 openssl 生成 SSL 证书(依次执行以下命令)
openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes -days 3650 -key ca-key.pem -out ca.pem
openssl genrsa 2048 > server-key.pem
openssl req -new -key server-key.pem -out server-req.pem
openssl x509 -req -in server-req.pem -days 3650 -CA ca.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem
openssl genrsa 2048 > client-key.pem
openssl req -new -key client-key.pem -out client-req.pem
openssl x509 -req -in client-req.pem -days 3650 -CA ca.pem -CAkey ca-key.pem -set_serial 02 > client-cert.pem# 授权 MySQL 用户访问证书
chown -R mysql:mysql /var/lib/mysql/ssl

注意:

在执行 openssl req 命令时,需要填写证书的相关信息(如国家、组织等),这些信息是证书的元数据,可简单填写或直接留空(按回车跳过)。

针对你遇到的 “Country Name” 输入问题:

  1. 国家代码需要填写2 个字母(如中国填 CN,美国填 US),例如:

    plaintext

    Country Name (2 letter code) [XX]:CN
    
  2. 后续其他字段可直接按回车留空(或简单填写):

    plaintext

    State or Province Name (full name) []:
    Locality Name (eg, city) []:
    Organization Name (eg, company) []:
    Organizational Unit Name (eg, section) []:
    Common Name (eg, your name or your server's hostname) []:
    Email Address []:
    
步骤 3:在主库中配置 SSL 并授权用户

进入主库 MySQL 终端:

bash

mysql -uroot -p

执行执行授权 SQL(% 表示允许从任意 IP 连接,生产环境建议限制 IP):

sql

-- 启用 SSL
SET GLOBAL ssl=ON;-- 授权 repl 用户使用 SSL 连接
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' REQUIRE SSL;
FLUSH PRIVILEGES;

查看主库当前的 binlog 位置(记录 FilePosition,从库需要用):

sql

# 必须在主库中执行,从库不支持该命令
# SHOW MASTER STATUS; # mysql9.4不支持
SHOW BINARY LOG STATUS;

输出类似:

plaintext

+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      154 | ruoyi_wms    |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

记录 File(如 mysql-bin.000001)和 Position(如 154

注意:重启容器后 position 会发生变化

步骤 4:将主库 SSL 证书复制到从库

在宿主机执行(将主库生成的证书复制到从库容器):

bash

# 从主库容器复制证书到宿主机临时目录
docker cp teamdhl-mysql-master:/var/lib/mysql/ssl /tmp/# 将证书复制到从库容器
docker cp /tmp/ssl teamdhl-mysql-slave:/var/lib/mysql/# 为从库证书授权
docker exec -it teamdhl-mysql-slave chown -R mysql:mysql /var/lib/mysql/ssl
步骤 5:在从库中配置 SSL 同步

进入从库 MySQL 终端:

bash

docker exec -it teamdhl-mysql-slave mysql -uroot -p

验证从库证书是否存在

bash

# 查看从库容器内的证书文件
docker exec -it teamdhl-mysql-slave ls -l /var/lib/mysql/ssl

如果看到类似以下输出,说明证书已正确复制:

plaintext

-rw------- 1 mysql mysql 1675 Aug 22 10:00 ca-key.pem
-rw------- 1 mysql mysql 1359 Aug 22 10:00 ca.pem
-rw------- 1 mysql mysql 1679 Aug 22 10:01 client-key.pem
-rw------- 1 mysql mysql 1359 Aug 22 10:01 client-cert.pem
-rw------- 1 mysql mysql 1675 Aug 22 10:00 server-key.pem
-rw------- 1 mysql mysql 1359 Aug 22 10:00 server-cert.pem

配置同步:

sql

STOP REPLICA;CHANGE REPLICATION SOURCE TO
SOURCE_HOST='teamdhl-mysql-master',
SOURCE_USER='repl',
SOURCE_PASSWORD='HIH.20171009',
SOURCE_PORT=3306,
SOURCE_LOG_FILE='mysql-bin.000001',
SOURCE_LOG_POS=158,
SOURCE_SSL=1 # 仅启用SSL,不指定证书路径,防止路径报错问题START REPLICA;
步骤 6:验证同步状态

sql

SHOW REPLICA STATUS\G;

Replica_IO_RunningReplica_SQL_Running 均为 Yes,则主从同步通过 SSL 连接成功建立。

这种方式通过 openssl 手动生成证书,兼容 MySQL 9.4 版本,解决了 mysql_ssl_rsa_setup 命令不存在的问题。

步骤 7:验证同步功能(可选)
  1. 在主库创建测试数据:

    sql

    -- 进入主库
    docker exec -it teamdhl-mysql-master mysql -uroot -p-- 创建测试数据库(如果不存在)
    CREATE DATABASE IF NOT EXISTS test_sync;
    USE test_sync;-- 创建测试表并插入数据
    CREATE TABLE IF NOT EXISTS test_table (id INT, name VARCHAR(20));
    INSERT INTO test_table VALUES (1, 'sync_test');
    
  2. 在从库查看是否同步成功:

    sql

    -- 进入从库
    docker exec -it teamdhl-mysql-slave mysql -uroot -p-- 查看同步的数据
    USE test_sync;
    SELECT * FROM test_table;
    

如果能看到主库插入的数据,说明同步功能正常工作。

恭喜你完成了 MySQL 9.4 的主从同步配置!


从库 Last_Errno: 1049(未知数据库)解决方案

在从库中执行SHOW REPLICA STATUS\G;

从输出的状态信息来看,从库的 SQL 线程(Replica_SQL_Running: No)已中断,错误原因是 Last_Errno: 1049(未知数据库),具体是主库执行的事务涉及从库不存在的数据库,导致从库无法执行中继日志中的 SQL。

具体原因

主库中创建了某个数据库(如 test_syncnavicat_test 所在的库),但从库中不存在该数据库,当主库的 binlog 同步到从库时,从库执行 CREATE TABLEINSERT 操作时会因 “找不到数据库” 而报错,导致 SQL 线程停止。

解决方案:手动创建缺失的数据库并重启同步

步骤 1:确定主库中操作的数据库名称

查看主库中你测试时使用的数据库(例如 test_sync 所在的库)。

步骤 2:在从库中创建相同的数据库

在从库 MySQL 终端执行:

sql

-- 替换为实际缺失的数据库名(例如 test_sync)
CREATE DATABASE IF NOT EXISTS test_sync;
步骤 3:跳过错误并重启同步

sql

-- 跳过当前错误事务(仅用于解决此问题,不要频繁使用)
SET GLOBAL sql_slave_skip_counter = 1;-- 重启从库同步
STOP REPLICA;
START REPLICA;
步骤 4:验证同步状态

sql

SHOW REPLICA STATUS\G;

确认 Replica_SQL_Running 变为 Yes,且 Last_SQL_Error 为空。

步骤 5:重新测试同步
  1. 在主库创建测试数据:

    sql

    -- 进入主库
    docker exec -it teamdhl-mysql-master mysql -uroot -p-- 创建测试数据库(如果不存在)
    CREATE DATABASE IF NOT EXISTS test_sync;
    USE test_sync;-- 创建测试表并插入数据
    CREATE TABLE IF NOT EXISTS test_table (id INT, name VARCHAR(20));
    INSERT INTO test_table VALUES (1, 'sync_test');
    
  2. 在从库查看是否同步成功:

    sql

    -- 进入从库
    docker exec -it teamdhl-mysql-slave mysql -uroot -p-- 查看同步的数据
    USE test_sync;
    SELECT * FROM test_table;
    

如果能看到主库插入的数据,说明同步功能正常工作。

通过以上步骤,可解决 “未知数据库” 导致的同步中断问题,恢复主从数据同步。

http://www.dtcms.com/a/347593.html

相关文章:

  • 【51单片机非精准延时演示来回流水灯效果】2022-11-10
  • 【机器学习深度学习】自然语言与多模态大模型
  • 【KO】前端面试一
  • git的工作使用中实际经验
  • 关于Highcharts的数据参考与产品系列
  • Camera performance analysis
  • 智能系统与未来生态演进初步思考
  • 告别图片背景违和!autohue.js 让图片与背景自动 “无缝衔接”
  • 基于51单片机自动智能浇花系统设计
  • 【序列晋升】13 Spring Cloud Bus微服务架构中的消息总线
  • 研究生方向:在传统赛道与交叉领域间寻找破局之路
  • 第三阶段数据库-2:数据库中的sql语句
  • 重审文字的本体论地位:符号学转向、解构主义突围与视觉性革命
  • 1电吉他环境搭建:效果器再探
  • C++算法题—— 小C的细菌(二维偏序离线 + 树状数组 + 坐标压缩)
  • [激光原理与应用-328]:结构设计 - Solidworks - 什么是结构建模?
  • PCB电路设计学习3 电路原理图设计 元件PCB封装设计与添加
  • 学习嵌入式第三十六天
  • 神经网络|(十三)概率论基础知识-贝叶斯公式和全概率公式
  • More Effective C++ 条款04:非必要不提供默认构造函数
  • c++string
  • 【计算机网络 | 第8篇】编码与调制
  • 青少年机器人技术(二级)等级考试试卷-实操题(2024年9月)
  • 笔试——Day47
  • 张老师---个人师资介绍
  • python学习DAY49打卡
  • 智慧矿山误报率↓83%!陌讯多模态融合算法在矿用设备监控的落地优化
  • 鸿蒙中CPU活动分析:CPU分析
  • 周末总结(2024/08/23)
  • 数组拆分求最大不重复数和(动态规划解法)