搭建 Mysql 主从复制

环境

  • 操作系统: debian 12
  • 数据库: mysql 8.4.7
名称 地址
主服务器 192.168.31.111
从服务器 192.168.31.114, 192.168.31.115

搭建步骤

  1. 修改主服务器配置

Mysql 配置文件是: /etc/mysql/my.cnf ,在 192.168.31.111 的 my.cnf 文件中加入如下配置

[mysqld]
server_id = 111 # 只能是 1 - (2^32 - 1) 之间的整数
log_bin=mysql-bin # 开启 binlog
# binlog_format=ROW # binglog 格式, ROW 最安全可靠,默认值为 ROW。变量已经被废弃,官方未来打算只支持 ROW 格式
binlog_row_image=FULL # 决定 ROW 模式下,binlog 记录“多少列”。FULL 表示所有列
gtid_mode=ON # 开启全局事务 ID,方便从库自动找到位置进行同步
enforce_gtid_consistency=ON # 强制只允许“GTID 安全”的事务,防止生成无法复制的 GTID
log_replica_updates=ON # 从库执行的复制事件,也写入自己的 binlog。这样从库可以再作为其他从库的主库
sync_binlog=1 # 每次事务提交,都 fsync binlog 到磁盘
innodb_flush_log_at_trx_commit=1 # 控制 InnoDB redo log 刷盘策略,每次提交事务,redo log 都要刷盘。
innodb_flush_method = O_DIRECT # 表示使用  Direct IO, 绕过操作系统的缓存,直接将数据写入磁盘
  1. 重启主服务器
systemctl restart mysql
  1. 在主库上创建用于数据同步的用户
CREATE USER 'root'@'192.168.31.%' IDENTIFIED BY '111000';
GRANT REPLICATION SLAVE ON *.* TO 'root'@'192.168.31.%';

-- 刷新权限
FLUSH PRIVILEGES;
  1. 导出主服务器 192.168.31.111 上的相关数据
mysqldump -u root -p \
  --databases better_rss \
  --single-transaction \
  --set-gtid-purged=OFF \
  --source-data=2 \
  > /root/better_rss_dump.sql

参数解释:

  • --single-transaction最关键的一步。它会开启一个事务来读数据,期间主库即使有新数据写入(增删改),备份出的数据也是备份开始那一刻的快照,且不会阻塞主库的读写。
  • --set-gtid-purged=OFF: 这个参数表示将主库所有数据库的 GTID 范围记录在导出的 SQL 文件头部,因此需要关闭。
  • --source-data=2:将主库当前的 Binlog 文件名和位置以注释形式记录在 SQL 文件中(作为双重保险)。
  1. 将 sql 文件拷贝到从服务器
scp /root/better_rss_dump.sql root@192.168.31.114:/root/
scp /root/better_rss_dump.sql root@192.168.31.115:/root/
  1. 修改从服务器配置

Mysql 配置文件是: /etc/mysql/my.cnf ,在 192.168.31.114 和 192.168.31.115 的 my.cnf 文件中加入如下配置

[mysqld]
server_id=114 # 只能是 1 - (2^32 - 1) 之间的整数
gtid_mode=ON # 开启全局事务 ID,方便从库自动找到位置进行同步
enforce_gtid_consistency=ON # 强制只允许“GTID 安全”的事务,防止生成无法复制的 GTID
log_bin=mysql-bin  # 开启 binlog
binlog_format= ROW # binglog 格式, ROW 最安全可靠
log_replica_updates=ON #  # 从库执行的复制事件,也写入自己的 binlog。这样从库可以再作为其他从库的主库
read_only=ON # 限制普通用户只能执行读操作,无法执行写操作。高权限用户不受限制
super_read_only=ON # 限制只能读,不能写。高级权限用户也不能够随便写

注意修改一下 server_id,保证不重复即可:

  • 192.168.31.114: server_id = 114
  • 192.168.31.115: server_id = 115

重启从数据库:

systemctl restart mysql
  1. 在从库中导入主库的数据

进入 192.168.31.114 的 Mysql:

mysql -u root -p

执行如下命令:

-- 关闭只读模式
SET GLOBAL super_read_only = 0;
SET GLOBAL read_only = 0;

-- 停止主从复制
STOP REPLICA;
-- 清理之前的错误状态和旧的 GTID 信息
RESET REPLICA ALL;

-- 重置 GTID 和 bin_log
RESET BINARY LOGS AND GTIDS;

-- 退出 mysql
exit;

导入主库数据:

mysql -u root -p < /root/better_rss_dump.sql

进入 Mysql

mysql -u root -p

执行如下的命令:

-- 开启只读模式
SET GLOBAL read_only = 1;
SET GLOBAL super_read_only = 1;

-- 设置同步主机
CHANGE REPLICATION SOURCE TO
  SOURCE_HOST='192.168.31.111',
  SOURCE_PORT=3306,
  SOURCE_USER='root', -- 第三步提前在主库中设置好的用户
  SOURCE_PASSWORD='111000', -- 第三步提前在主库中设置好的密码
  GET_SOURCE_PUBLIC_KEY = 1, -- 当从库使用 caching_sha2_password 认证、且连接没有启用 SSL 时,允许从主库“动态获取 RSA 公钥”,用来安全地传输密码。
  SOURCE_AUTO_POSITION=1; -- 表示自动与主库数据保持一致

-- 开启主从复制
START REPLICA;

-- 检查主从复制的状态
SHOW REPLICA STATUS\G

查看主从复制是否成功的关键参数:

  • Replica_IO_Running: Yes
  • Replica_SQL_Running: Yes
  • Auto_Position: 1

如果看到这三项,说明基于 GTID 的 MySQL 8.4 集群搭建成功

Q & A

ERROR 3546 (HY000) at line 24: @@GLOBAL.GTID_PURGED cannot be changed: the added gtid set must not overlap with @@GLOBAL.GTID_EXECUTED

解决步骤:

进入 mysql

mysql -u root -p

执行

RESET BINARY LOGS AND GTIDS;

Fatal error: The replica I/O thread stops because source and replica have equal MySQL server UUIDs; these UUIDs must be different for replication to work.

解决步骤:

systemctl stop mysql
rm -rf /var/lib/mysql/auto.cnf
systemctl start mysql
mysql -u root -p
show replica status\G

IP 被 Mysql 封锁了怎么办? 操作步骤如下:

进入 Mysql

mysql -u root -p

执行

TRUNCATE TABLE performance_schema.host_cache;
使用 Hugo 构建
主题 StackJimmy 设计