介绍
MySQL 8.4 的多源复制允许单个副本从多个源服务器并行接收事务。每个源通过一个独立的复制通道连接到副本。
这种机制主要用于:
- 将多个服务器整合到单个节点
- 聚合来自多个国家、站点或应用程序的流
- 集中读取数据
- 准备报表或对账节点
然而,这不是一个共享写入集群。MySQL 不会在多个源之间执行冲突解决。如果两个源写入相同的逻辑对象,一致性必须在应用层面处理,或者通过严格的数据分区来保证。
MySQL 8.4 实际支持什么
在 MySQL 8.4 中:
- 多源副本为每个源打开一个通道
- 每个通道必须指向不同的源
- 复制可以基于 GTID 或 binlog 位置
- 复制过滤器可以按通道应用
- 副本元数据仓库必须为
TABLE模式,这是 8.4 中的默认行为
关键点:
- 多源是用于整合的,不是用于带仲裁的多主
- 没有内置的冲突检测或解决机制
- 单个副本不能向同一个源打开多个通道
示例拓扑
三个源和一个聚合器的简单示例:
production_de ─┐
production_es ─┼──> production_all84
production_it ─┘
在这个示例中:
production_de包含一个PRODUCTION数据库production_es也包含一个PRODUCTION数据库production_it也包含一个PRODUCTION数据库production_all84接收所有三个流,但将它们重映射到不同的数据库:PRODUCTION_DEPRODUCTION_ESPRODUCTION_IT
这种重映射防止三个流在副本上写入同一个数据库。
前提条件
在每个源上:
- 唯一的
server-id - 启用二进制日志
- 对 MySQL 端口的 TCP/IP 访问
- 专用复制用户
在多源副本上:
- 唯一的
server-id - 配置
relay_log - MySQL 8.4
- 启动复制前的初始数据恢复
典型的源配置
源上的最小配置示例:
[mysqld]
bind-address = 0.0.0.0
server-id = 186
log_bin = mysql-bin
binlog_format = ROW
binlog_row_image = FULL
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1
其他源上使用相同的逻辑,每个服务器使用不同的 server-id。
典型的聚合器副本配置
示例:
[mysqld]
bind-address = 0.0.0.0
server-id = 189
log_bin = mysql-bin
relay_log = mysql-relay-bin
binlog_format = ROW
binlog_row_image = FULL
skip_replica_start = ON
read_only = ON
super_read_only = ON
skip_replica_start=ON 在设置或维护阶段很有用,因为它防止在验证之前自动重启通道。
创建复制账户
在每个源上:
CREATE USER 'repl'@'10.68.68.%' IDENTIFIED BY 'Repl84Geo2026x';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl'@'10.68.68.%';
REPLICATION SLAVE 权限仍然是 MySQL 在 8.4 中为此类设置记录的权限。
初始数据加载
在附加通道之前,你需要将初始数据加载到副本上。
从源上获取转储的示例:
mysqldump --single-transaction --set-gtid-purged=OFF PRODUCTION > PRODUCTION_de.sql
mysqldump --single-transaction --set-gtid-purged=OFF PRODUCTION > PRODUCTION_es.sql
mysqldump --single-transaction --set-gtid-purged=OFF PRODUCTION > PRODUCTION_it.sql
然后在副本上:
CREATE DATABASE PRODUCTION_DE;
CREATE DATABASE PRODUCTION_ES;
CREATE DATABASE PRODUCTION_IT;
并将三个转储导入到各自对应的目标数据库中。
获取 binlog 坐标
如果你不使用 GTID,你需要获取每个源的:
- binlog 文件名
- 起始位置
示例:
SHOW BINARY LOG STATUS;
然后副本将使用 SOURCE_LOG_FILE 和 SOURCE_LOG_POS 从这些坐标开始。
创建通道
在 MySQL 8.4 中,每个源通过 CHANGE REPLICATION SOURCE TO ... FOR CHANNEL 配置。
德国源的示例:
CHANGE REPLICATION SOURCE TO
SOURCE_HOST='10.68.68.186',
SOURCE_PORT=3306,
SOURCE_USER='repl',
SOURCE_PASSWORD='Repl84Geo2026x',
SOURCE_LOG_FILE='mysql-bin.000001',
SOURCE_LOG_POS=158,
SOURCE_AUTO_POSITION=0,
GET_SOURCE_PUBLIC_KEY=1
FOR CHANNEL 'production_de';
对以下通道使用相同的方法:
production_esproduction_it
按通道过滤
多源的强大之处在于按通道过滤。
如果所有三个源都有一个 PRODUCTION 数据库,你可以在副本端重写它们:
CHANGE REPLICATION FILTER
REPLICATE_REWRITE_DB=((PRODUCTION,PRODUCTION_DE))
FOR CHANNEL 'production_de';
CHANGE REPLICATION FILTER
REPLICATE_REWRITE_DB=((PRODUCTION,PRODUCTION_ES))
FOR CHANNEL 'production_es';
CHANGE REPLICATION FILTER
REPLICATE_REWRITE_DB=((PRODUCTION,PRODUCTION_IT))
FOR CHANNEL 'production_it';
重要说明:
- 在应用
CHANGE REPLICATION FILTER ... FOR CHANNEL之前,通道必须已经存在 - 如果通道尚不存在,MySQL 会返回错误
启动通道
START REPLICA FOR CHANNEL 'production_de';
START REPLICA FOR CHANNEL 'production_es';
START REPLICA FOR CHANNEL 'production_it';
然后,如果副本应保持被动状态:
SET GLOBAL read_only = ON;
SET GLOBAL super_read_only = ON;
验证
按通道检查:
SHOW REPLICA STATUS FOR CHANNEL 'production_de'\G
SHOW REPLICA STATUS FOR CHANNEL 'production_es'\G
SHOW REPLICA STATUS FOR CHANNEL 'production_it'\G
预期指标:
Replica_IO_Running: YesReplica_SQL_Running: YesSeconds_Behind_Source: 0或接近0Replicate_Rewrite_DB正确设置
功能检查:
SELECT * FROM PRODUCTION_DE.germany_feed;
SELECT * FROM PRODUCTION_ES.spain_feed;
SELECT * FROM PRODUCTION_IT.italy_feed;
常见操作
停止单个通道:
STOP REPLICA FOR CHANNEL 'production_es';
重启单个通道:
START REPLICA FOR CHANNEL 'production_es';
重置通道:
RESET REPLICA ALL FOR CHANNEL 'production_es';
移除通道上的重写过滤器:
CHANGE REPLICATION FILTER REPLICATE_REWRITE_DB=() FOR CHANNEL 'production_es';
应该避免的事项
- 在没有数据分区的情况下将多个源路由到同一个目标数据库
- 假设 MySQL 会解决键或排序冲突
- 在没有严格兼容性控制的情况下使用不同的 MySQL 版本
- 忘记
CHANGE REPLICATION SOURCE TO中的SOURCE_PASSWORD有长度限制 - 在创建通道之前应用过滤器
技术定位
MySQL 8.4 多源适用于:
- 多国整合
- 集中报表
- 对账
- 恢复多个独立流
它不适用于(单独使用时):
- 真正的并发多主写入
- 共识架构
- 自动冲突解决
结论
使用 MySQL 8.4,多源复制清晰、成熟,可用于生产环境中将多个源服务器聚合到单个副本。
推荐的模式很简单:
- 明确分离源和聚合器角色
- 在所有地方强制使用唯一的
server-id - 加载初始快照
- 为每个源创建一个通道
- 按通道应用重写过滤器
- 独立验证每个通道
如果源数据库共享相同的名称,按通道使用 REPLICATE_REWRITE_DB 是保持最终副本可读和可用的最实用机制。
评论 (0)
暂无评论。
发表评论