PmaControl logo PmaControl
  • 首页
  • PmaControl
    • AI智能代理 13个本地代理
    • 定价方案 Community、Cloud、On-Premise、Premium
    • 文档 指南、API、架构
    • 插件市场 社区插件
    • 客户 28+企业
    • 常见问题 25个问题 / 7个类别
    数据库
    • MariaDB 32 篇文章
    • MySQL 13 篇文章
    • Galera Cluster 6 篇文章
    • MaxScale 4 篇文章
    • ProxySQL 2 篇文章
    • Amazon Aurora MySQL 0 篇文章
    • Azure Database 0 篇文章
    • ClickHouse 0 篇文章
    • GCP CloudSQL 0 篇文章
    • Percona Server 0 篇文章
    • SingleStore 0 篇文章
    • TiDB 0 篇文章
    • Vitess 0 篇文章
    解决方案
    • 全天候支持 MariaDB & MySQL紧急支持
    • Observabilité SQL 监控、告警、拓扑
    • Haute disponibilité 复制、故障转移、Galera
    • Disaster Recovery 备份、恢复、RPO/RTO
    • Sécurité & conformité 审计、GDPR、SOC2
    • Migration & upgrade 零停机、pt-osc、gh-ost
  • 定价方案
  • 资源
    • 文档 技术指南与API
    • MySQL 优化中心 Markdown 索引、指标、参数、故障
    • 常见问题 25个常见问题
    • 客户评价 客户反馈与案例
    • 博客 文章与洞察
    • 路线图 即将推出的功能
    专业领域
    • Observabilité SQL 监控、告警、Dot3拓扑
    • Haute disponibilité 复制、故障转移、Galera
    • Sécurité & conformité 审计、GDPR、SOC2、ISO 27001
    • Disaster Recovery 备份、恢复、RPO/RTO
    • Performance & optimisation Digests、EXPLAIN、调优
    • Migration & upgrade 零停机、pt-osc
    快速链接
    • GitHub Wiki 26页 — 安装、引擎、插件
    • 源代码 GitHub官方仓库
    • 全天候支持 MariaDB & MySQL紧急支持
    • 预约演示 30分钟 — 真实架构
  • 全天候支持
  • 预约演示
预约演示
🇫🇷 FR Français 🇬🇧 EN English 🇵🇱 PL Polski 🇷🇺 RU Русский 🇨🇳 ZH 中文 🇸🇦 AR العربية
← 返回博客

MaxScale 与 MySQL 8.4:构建兼容 Source/Replica 的 GTID 故障转移

发布于 2026年7月27日 作者 Aurélien LEQUOY
maxscale mysql mysql-8.4 replication gtid failover high-availability proxy
分享 X LinkedIn Facebook Email PDF
MaxScale 与 MySQL 8.4:构建兼容 Source/Replica 的 GTID 故障转移

项目状态——2026 年 7 月 27 日。 上游 PR #421 向 MaxScale 提交了本文介绍的 mysqlrepmon 模块。该 PR 有意保持 draft 状态:代码已经在 MySQL 8.4.10 实验环境中完成编译和测试,但尚未进入任何 MaxScale 官方版本。请勿将其描述为厂商已支持的生产功能。

用一句话说明问题

MaxScale 历来使用 mariadbmon 监控 MariaDB / MySQL 复制拓扑。但 MySQL 8.4 已删除旧的 SLAVE / MASTER 命令,采用基于 UUID 的 GTID,并要求使用另一套语法来重新配置复制。

结果很容易造成误判:代理仍能接受 SQL 连接,但监控模块已经无法正确读取拓扑、提升 replica,或将原 primary 重新加入集群。

必须区分三个功能:

  1. 观察拓扑和复制线程状态;
  2. 在 switchover、failover 或 rejoin 时修改拓扑;
  3. 将应用会话路由到当前 primary 和可用 replicas。

MySQL 8.4 的兼容性必须在这三个层面都正确。仅把 SHOW SLAVE STATUS 替换为 SHOW REPLICA STATUS 并不够。

为什么 MySQL 8.4 打破了历史假设

MySQL 8.0.22 引入了 Source/Replica 术语,同时保留了一些历史别名。MySQL 8.4 完成了这次迁移:已弃用的命令被彻底删除。

操作 MariaDB / 旧语法 MySQL 8.4
读取 replica 状态 SHOW SLAVE STATUS SHOW REPLICA STATUS
配置 source CHANGE MASTER TO CHANGE REPLICATION SOURCE TO
启动复制 START SLAVE START REPLICA
停止复制 STOP SLAVE STOP REPLICA
清除配置 RESET SLAVE RESET REPLICA
读取二进制日志状态 SHOW MASTER STATUS SHOW BINARY LOG STATUS
重置 GTID RESET MASTER RESET BINARY LOGS AND GTIDS

返回的列名也发生了变化:

旧名称 MySQL 8.4 名称
Master_Host Source_Host
Master_Port Source_Port
Master_Server_Id Source_Server_Id
Slave_IO_Running Replica_IO_Running
Slave_SQL_Running Replica_SQL_Running
Seconds_Behind_Master Seconds_Behind_Source
Master_Log_File Source_Log_File
Read_Master_Log_Pos Read_Source_Log_Pos
Exec_Master_Log_Pos Exec_Source_Log_Pos
Channel_Name Channel_Name

仍然发送 SHOW SLAVE STATUS 的监控模块会立即遇到语法错误。即使发送了正确查询,如果仍然查找 Slave_IO_Running,也会错误地判定复制没有运行。

真正的差异:GTID 模型

最根本的区别并不是 SQL 词汇,而是事务的表示方式。

MariaDB GTID

MariaDB 使用以下形式表示 GTID:

domain_id-server_id-sequence

示例:

0-101-7842

domain 是模型的一部分。MariaDB 监控模块能够比较这些位置,并使用 MASTER_USE_GTID 等机制。

MySQL GTID

MySQL 通过服务器 UUID 和区间表示 GTID 集合:

155fa720-7623-11f1-9a78-bc241174cab8:1-76

一个历史记录可以包含多个 UUID 和不连续区间:

155fa720-7623-11f1-9a78-bc241174cab8:1-10:20-30,
7fd8c42a-7630-11f1-99af-bc241174cab8:1-8

MySQL 提供的关键信息包括:

  • @@global.server_uuid:标识事务来源;
  • @@global.gtid_executed:已经应用的事务;
  • @@global.gtid_purged:对应 binlog 已被清除的 GTID;
  • SHOW REPLICA STATUS 中的 Retrieved_Gtid_Set:已经接收的事务。

更换 source 时使用自动定位:

CHANGE REPLICATION SOURCE TO
    SOURCE_HOST = '10.0.0.12',
    SOURCE_PORT = 3306,
    SOURCE_USER = 'repl',
    SOURCE_PASSWORD = 'secret',
    SOURCE_AUTO_POSITION = 1,
    GET_SOURCE_PUBLIC_KEY = 1
FOR CHANNEL '';

服务器随后根据 GTID 集合自行选择正确的恢复点,不再需要提供 binlog 文件名和位置。

为什么需要 mysqlrepmon 模块

该提案在 mariadbmon 之外增加了一个 MySQL 专用监控模块。它复用经过验证的集群决策和操作引擎,同时替换所有与服务器方言相关的部分:

  • 读取 SHOW REPLICA STATUS 以及 Source_* / Replica_* 列;
  • 读取 server_uuid、gtid_executed 和 gtid_purged;
  • 使用 CHANGE REPLICATION SOURCE TO ... SOURCE_AUTO_POSITION=1;
  • 使用 START、STOP 和 RESET REPLICA ... FOR CHANNEL;
  • 降级服务器时启用 super_read_only=1;
  • 手动 reset 命令使用 RESET BINARY LOGS AND GTIDS;
  • 检查 enforce_gtid_consistency 和 log_replica_updates。

该模块保留 mariadbmon 中熟悉的运维参数:auto_failover、auto_rejoin、enforce_read_only_slaves,以及 switchover、failover 和 rejoin 命令。

参考架构

测试架构由三台 MySQL 8.4 服务器和一个 MaxScale 节点组成:

                              +----------------------+
SQL 应用 -------------------> | MaxScale             |
端口 4408 (RW)                | readwritesplit       |
端口 4409 (RO)                | mysqlrepmon          |
                              +----------+-----------+
                                         |
                              拓扑、健康、GTID、路由
                                         |
               +-------------------------+-------------------------+
               |                         |                         |
       +-------v--------+        +-------v--------+        +-------v--------+
       | mysql84-a      |        | mysql84-b      |        | mysql84-c      |
       | Primary        |------->| Replica        |        | Replica        |
       | 10.0.0.11      |------->| 10.0.0.12      |        | 10.0.0.13      |
       +----------------+        +----------------+        +----------------+

应用永远不需要知道 primary 的地址,只连接 MaxScale listener。监控模块决定哪个服务器拥有 MaxScale 内部的 Master 角色;readwritesplit 将写操作发往该服务器并分发读操作。

MaxScale 本身也必须具备冗余。即使数据库故障转移完美,如果唯一的 SQL 代理是单点,整个服务仍会中断。生产环境至少应部署两个 active/passive MaxScale 节点,配置 VIP 或 load balancer,并使用适当的协作锁机制。

1. 准备每台 MySQL 8.4 服务器

任何可能被提升的服务器都必须能够生成自己的 binlog,并将收到的事务重新写入 binlog。

基础配置:

[mysqld]
server_id=101
log_bin=mysql-bin
binlog_format=ROW

gtid_mode=ON
enforce_gtid_consistency=ON
log_replica_updates=ON

relay_log_recovery=ON

每个节点使用不同的 server_id,例如 101、102、103。

server_uuid 也必须唯一。它保存在 datadir 的 auto.cnf 文件中。克隆虚拟机或 datadir 后,绝不能同时运行多个具有相同 server_uuid 的服务器。

在 replicas 上:

read_only=ON
super_read_only=ON

在 primary 上:

read_only=OFF
super_read_only=OFF

重启后检查关键不变量:

SELECT
    @@hostname,
    @@server_id,
    @@server_uuid,
    @@gtid_mode,
    @@enforce_gtid_consistency,
    @@log_bin,
    @@log_replica_updates,
    @@read_only,
    @@super_read_only\G

SELECT @@global.gtid_executed\G
SHOW BINARY LOG STATUS\G
SHOW REPLICA STATUS\G

可被提升的 replica 必须满足 log_bin=1、log_replica_updates=1,两个复制线程均在运行,并且延迟受控。

2. 创建独立账户

至少应分离:

  • 监控和修改拓扑的账户;
  • replicas 用于读取 binlog 的账户;
  • 通过代理连接的应用账户。

监控账户

仅用于观察:

CREATE USER 'maxscale_mon'@'10.0.0.10'
    IDENTIFIED BY 'a-long-random-password';

GRANT REPLICATION CLIENT
    ON *.* TO 'maxscale_mon'@'10.0.0.10';

要执行 failover、switchover 和 rejoin,监控模块还必须能够停止和重新配置复制、修改只读变量以及控制连接:

GRANT REPLICATION SLAVE,
      REPLICATION CLIENT,
      PROCESS,
      SUPER,
      SYSTEM_VARIABLES_ADMIN,
      REPLICATION_SLAVE_ADMIN,
      CONNECTION_ADMIN
    ON *.* TO 'maxscale_mon'@'10.0.0.10';

某些兼容路径仍然要求历史的 SUPER 权限。在模块最终完成后,应重新审核准确权限列表并删除不再需要的权限。

复制账户

CREATE USER 'repl'@'10.0.0.%'
    IDENTIFIED BY 'another-long-random-password'
    REQUIRE SSL;

GRANT REPLICATION SLAVE
    ON *.* TO 'repl'@'10.0.0.%';

优先使用 TLS。如果通过未加密连接使用 MySQL 8.4 默认的 caching_sha2_password,更换 source 的命令必须提供 GET_SOURCE_PUBLIC_KEY=1 或 RSA 公钥路径。未启用 TLS 时,模块会添加该选项。

用于客户端认证的服务账户

MaxScale service 的 user 并不是所有应用查询实际执行时使用的账户。它让 MaxScale 的 User Account Manager 能够从 backend 加载账户和权限:

CREATE USER 'maxscale_route'@'10.0.0.10'
    IDENTIFIED BY 'route-password';

GRANT SELECT ON mysql.user
    TO 'maxscale_route'@'10.0.0.10';
GRANT SELECT ON mysql.db
    TO 'maxscale_route'@'10.0.0.10';
GRANT SELECT ON mysql.tables_priv
    TO 'maxscale_route'@'10.0.0.10';
GRANT SELECT ON mysql.columns_priv
    TO 'maxscale_route'@'10.0.0.10';
GRANT SELECT ON mysql.procs_priv
    TO 'maxscale_route'@'10.0.0.10';
GRANT SELECT ON mysql.proxies_priv
    TO 'maxscale_route'@'10.0.0.10';
GRANT SHOW DATABASES ON *.*
    TO 'maxscale_route'@'10.0.0.10';

应用账户仍必须存在于所有 MySQL 服务器上,使用相同密码并拥有一致的 grants。backend 看到连接来自 MaxScale,因此账户的 @host 必须允许代理地址。

3. 从可复现的 SHA 构建提案

由于 PR 仍是 draft,标准 MaxScale 软件包并不包含 mysqlrepmon。仅在实验环境中构建以下准确的公开 SHA:

git clone https://github.com/mariadb-corporation/MaxScale.git
cd MaxScale

git fetch https://github.com/Esysteme/MaxScale.git \
  aurelien/mysql-8.4-replication-support
git checkout --detach f61776a5b19cf295636c94a8a3dea6d81fcd61fb

cmake -S . -B build \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_INSTALL_PREFIX=/usr/local/maxscale-mysql84

cmake --build build --target mariadbmon mysqlrepmon test_cycle_find -j2
ctest --test-dir build --output-on-failure \
  -R '^test_mariadbmon_cycle_find$'

cmake --build build -j2
sudo cmake --install build

定向构建应生成 libmysqlrepmon.so。该提案的 CMake 修复显式复用 MaxScale 检测到的 LIBSSH_LIBRARY 和 LIBSSH_INCLUDE_DIR,而不是假定存在内部 libssh target。

启动隔离构建

/usr/local/maxscale-mysql84 前缀可避免覆盖已安装的软件包。相应地,软件包提供的 maxscale.service 仍会启动 /usr/bin/maxscale,不会加载新模块。在实验环境中创建 /etc/systemd/system/maxscale-mysql84.service:

[Unit]
Description=MaxScale MySQL 8.4 compiled build
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=maxscale
Group=maxscale
RuntimeDirectory=maxscale
RuntimeDirectoryMode=0755
ExecStart=/usr/local/maxscale-mysql84/bin/maxscale --nodaemon --config=/etc/maxscale.cnf --logdir=/var/log/maxscale --datadir=/var/lib/maxscale --cachedir=/var/cache/maxscale --libdir=/usr/local/maxscale-mysql84/lib/maxscale --piddir=/run/maxscale
Restart=on-failure
RestartSec=5s
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target

系统账户 maxscale 和数据目录必须存在;通常由为运行环境安装的 MaxScale 软件包创建。然后让 systemd 重新加载配置:

sudo install -d -o maxscale -g maxscale -m 0755 \
  /var/lib/maxscale /var/cache/maxscale /var/log/maxscale
sudo systemctl daemon-reload

4. 配置 MaxScale

完整的最小示例:

[maxscale]
threads=auto
admin_host=127.0.0.1
admin_port=8989

[mysql84-a]
type=server
address=10.0.0.11
port=3306
protocol=MariaDBBackend

[mysql84-b]
type=server
address=10.0.0.12
port=3306
protocol=MariaDBBackend

[mysql84-c]
type=server
address=10.0.0.13
port=3306
protocol=MariaDBBackend

[MySQL84-Monitor]
type=monitor
module=mysqlrepmon
servers=mysql84-a,mysql84-b,mysql84-c
user=maxscale_mon
password=a-long-random-password
monitor_interval=2000ms

assume_unique_hostnames=true
auto_failover=safe
auto_rejoin=true
enforce_read_only_slaves=true

replication_user=repl
replication_password=another-long-random-password
replication_master_ssl=true

[MySQL84-RW-Service]
type=service
router=readwritesplit
servers=mysql84-a,mysql84-b,mysql84-c
user=maxscale_route
password=route-password

master_reconnection=true
master_failure_mode=fail_on_write

[MySQL84-RW-Listener]
type=listener
service=MySQL84-RW-Service
protocol=MariaDBClient
port=4408

[MySQL84-RO-Service]
type=service
router=readconnroute
servers=mysql84-a,mysql84-b,mysql84-c
user=maxscale_route
password=route-password
router_options=slave

[MySQL84-RO-Listener]
type=listener
service=MySQL84-RO-Service
protocol=MariaDBClient
port=4409

这里保留明文密码仅为了示例可读性。在实际运维中,请使用 MaxScale 提供的 secret 加密、严格限制配置文件权限,并建立有记录的轮换流程。

启用 auto_failover 和 auto_rejoin 必须设置 assume_unique_hostnames=true。因此,每个 backend 都必须暴露唯一且稳定的地址或 hostname,并与 replicas 记录的 source 一致;如果复制网络使用不同地址,请配置 private_address。

为什么从 auto_failover=safe 开始?如果监控模块发现提升明显会丢失事务,该模式会拒绝执行。它不会把异步复制变成同步复制,但在评估阶段提供了一道有用的保护。

为什么使用 master_reconnection=true 和 master_failure_mode=fail_on_write?只要无 primary 窗口期间没有写请求且没有打开的事务,readwritesplit 会话就可以保留上下文并连接到新 primary。没有这些参数时,数据库 failover 可以成功,但所有应用会话仍然会被断开。

5. 第一次测试前的验证

验证配置并启动 MaxScale:

sudo /usr/local/maxscale-mysql84/bin/maxscale \
  --config=/etc/maxscale.cnf \
  --libdir=/usr/local/maxscale-mysql84/lib/maxscale \
  --config-check

sudo systemctl disable --now maxscale.service 2>/dev/null || true
sudo systemctl enable --now maxscale-mysql84.service
systemctl --no-pager --full status maxscale-mysql84.service

检查模块和拓扑是否可见:

maxctrl list modules | grep -E 'mariadbmon|mysqlrepmon'
maxctrl list servers
maxctrl list monitors
maxctrl show monitor MySQL84-Monitor

预期状态:

  • 一台 Master, Running 服务器;
  • 两台 Slave, Running 服务器;
  • 没有 Down 服务器;
  • monitor 处于活动状态;
  • listeners 4408 和 4409 已打开。

还应直接检查 MySQL:

mysql -h 10.0.0.12 -e "SHOW REPLICA STATUS\\G"
mysql -h 10.0.0.13 -e "SHOW REPLICA STATUS\\G"

关键字段:

Replica_IO_Running: Yes
Replica_SQL_Running: Yes
Seconds_Behind_Source: 0
Auto_Position: 1

6. 理解 failover 流程

当 primary 消失时,监控模块不只是修改标签:

  1. 等待 failcount 定义的监控周期,并尽可能确认故障确实存在;
  2. 比较 replicas 状态并选择可提升候选者;
  3. 停止候选者上的复制;
  4. 在新 primary 上关闭 read_only;
  5. 使用 CHANGE REPLICATION SOURCE TO ... SOURCE_AUTO_POSITION=1 重定向其他 replicas;
  6. 重新启动其复制线程;
  7. readwritesplit 检测新角色,并将后续写操作路由到新 primary。

降级 primary 时,mysqlrepmon 使用:

SET GLOBAL super_read_only = 1;

这比 read_only=1 更严格:即使拥有管理权限的账户,也不应继续意外写入原 primary。

7. 测试受控 switchover

在模拟硬故障之前,先验证 switchover:

maxctrl call command mysqlrepmon switchover \
  MySQL84-Monitor mysql84-b mysql84-a

然后检查:

maxctrl list servers

mysql -h 10.0.0.11 -e \
  "SELECT @@hostname, @@read_only, @@super_read_only, @@global.gtid_executed\\G"
mysql -h 10.0.0.12 -e \
  "SELECT @@hostname, @@read_only, @@super_read_only, @@global.gtid_executed\\G"
mysql -h 10.0.0.13 -e \
  "SELECT @@hostname, @@read_only, @@super_read_only, @@global.gtid_executed\\G"

新 primary 必须可写。其他两个节点必须为 super_read_only=1,并从它进行复制。

8. 不作弊地测试真实故障

首先通过 MaxScale 创建数据:

CREATE DATABASE maxscale_ha_test;
CREATE TABLE maxscale_ha_test.events (
    id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    source_hostname VARCHAR(255) NOT NULL,
    created_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
    PRIMARY KEY (id)
) ENGINE=InnoDB;

INSERT INTO maxscale_ha_test.events(source_hostname)
VALUES (@@hostname);

确认数据出现在 replicas 上,然后在服务或机器层面停止 primary。不要只在 MaxScale 中把服务器设置为 maintenance:那测试的是管理决策,而不是故障检测。

测试期间:

watch -n 1 'maxctrl list servers'

另一个终端中:

journalctl -u maxscale -f

成功标准:

  • 只选出一个新 primary;
  • 其他 replicas 指向它;
  • 提升后通过 listener 4408 的写操作成功;
  • 通过 4409 的读取保持一致;
  • 原 primary 恢复后以 replica 身份重新加入;
  • gtid_executed 集合最终收敛。

MySQL 8.4.10 实验室验证了什么

以下场景在三个 MySQL 8.4.10 节点上完成:

  • 初始检测一台 primary 和两台 replicas;
  • 停止 primary;
  • 提升一台 replica;
  • 将剩余 replica 重定向到新 source;
  • 原 primary 恢复,并自动以 replica 身份 rejoin;
  • 反方向执行第二次 failover;
  • 三台服务器最终收敛到同一 gtid_executed 集合;
  • 通过 MaxScale 的读写路由正确;
  • read-only listener 拒绝写操作。

该测试验证了连续 GTID 历史的功能路径,但尚未证明上游集成所需的所有边界情况。

认证:不要混淆两类故障

实验室中部署的 MaxScale build 拒绝使用 MySQL 8.4 caching_sha2_password 哈希的应用账户:

Stored password hash length is 70 when 40 was expected

这条消息来自该 build 使用的 MaxScale 协议 authenticator,而不是复制监控模块。复制和路由可以完全正常,而客户端认证仍然失败。

实验环境使用一个明确专用的 mysql_native_password probe 账户来隔离问题。这不是通用建议:MySQL 8.4 默认禁用该历史 plugin。生产环境应使用兼容 caching_sha2_password 的 MaxScale build 和 authenticator,或官方支持的认证方法,而不是全局削弱 MySQL 配置。

同样的原则适用于 REST 端口上的:

401 Unauthorized

它表示 maxctrl 没有正确的管理凭据,并不能证明 monitor 或 SQL 路由发生故障。

诊断表

症状 可能原因 检查方式
SHOW SLAVE STATUS 语法错误 使用了旧模块,或把 MariaDB 方言用于 MySQL 8.4 MaxScale 日志、实际发送的查询
服务器没有 replica 角色 未映射 Replica_* 列 直接执行 SHOW REPLICA STATUS\G
Replica 无法提升 log_bin、log_replica_updates 或 GTID 未启用 全局变量和 monitor 日志
Rejoin 被拒绝 errant 事务或历史不兼容 比较 gtid_executed / gtid_purged
Stored password hash length is 70... authenticator 不兼容 caching_sha2_password MaxScale 日志、账户 plugin
maxctrl 返回 401 Unauthorized REST 凭据错误 MaxScale 管理配置
提升成功但会话仍断开 router 无法重连、存在打开事务或会话命令历史已耗尽 master_reconnection、master_failure_mode、router 日志
两个 primary 都可写 fencing/read-only 不足或多个 monitor 竞争 super_read_only、协作锁、网络状态

已知限制:GTID 集合中的区间缺口

为了复用 mariadbmon 的内部引擎,该提案将每个 MySQL UUID 映射到一个合成 domain,并把其区间转换为现有内部表示。

当前实现仅保留每个 UUID 的最高事务编号。因此:

uuid:1-10:20-30

会被概括为位置已经到达 30。事务 11 到 19 不存在这一信息无法被准确表达。

实验室中的历史是连续的。在存在注入、过滤、清理或 errant GTID 的基础设施中,这种近似可能导致候选者比较错误。

这是 PR 仍为 draft 的主要原因。在将模块视为 production-ready 之前,需要:

  • 正确表示或比较不连续区间;
  • 添加包含多个 UUID 和区间缺口的单元测试;
  • 覆盖 errant GTID 和已清理历史;
  • 执行完整上游 CI;
  • 获得 MaxScale 维护者评审。

Failover 不能保证什么

监控模块不会消除异步复制的固有属性。

  • 不能保证 RPO 为零:原 primary 已确认的事务可能尚未到达 replica。
  • 打开的事务:处于事务中的会话不一定能无错误迁移。
  • Split-brain:如果部分应用仍能访问原 primary,必须实施真正的网络或系统 fencing。
  • 复杂拓扑:multi-source、环形复制和 relay 需要专门策略。
  • 数据分歧:auto_rejoin 不应静默覆盖 errant 事务。
  • 单一代理:MaxScale 的冗余必须单独解决。

因此,一个合格的高可用测试需要分别衡量四件事:故障检测、提升、数据收敛和应用连续性。

上生产前 Checklist

  • [ ] 已测试可恢复的备份;
  • [ ] 三个唯一的 server_id 和 server_uuid;
  • [ ] 所有节点启用 GTID 和 log_replica_updates;
  • [ ] MaxScale 与 backend 之间启用 TLS;
  • [ ] monitor、复制和应用账户彼此分离;
  • [ ] 每台 replica 均验证 super_read_only=1;
  • [ ] 在硬 failover 前先验证受控 switchover;
  • [ ] 提升后通过 MaxScale 完成写测试;
  • [ ] 完成原 primary 的 rejoin 测试;
  • [ ] 最终比较 gtid_executed 集合;
  • [ ] 记录应用事务的行为;
  • [ ] 测试 fencing 和 MaxScale 冗余;
  • [ ] 每次提升和 GTID 分歧都触发告警;
  • [ ] 上生产前确保上游模块已完成、评审并获得支持。

为什么公开这项贡献

MySQL 8.4 是 LTS 版本。历史命令不会回来。监控工具无限期保留别名,并不能解决 GTID 模型差异和重新配置语法问题。

专用模块让边界变得明确:

  • mariadbmon 保持对 MariaDB 方言和 GTID 的原生支持;
  • mysqlrepmon 承载 MySQL 8.x 专用规则;
  • 公共 failover 引擎继续共享;
  • 测试可以分别验证每个数据库家族,而无需堆积散落的条件判断。

MaxScale PR #421 包含代码、文档、验证命令、实验结果和已知 GTID 限制。保持 draft 的目的正是先对这种表示方式进行评审,再声称所有 MySQL 历史都能安全处理。

延伸阅读

  • MySQL 8.4——新功能和已删除的复制命令
  • MySQL 8.4——复制配置
  • MySQL 8.4——更换 source 和 GET_SOURCE_PUBLIC_KEY
  • MaxScale——MariaDB Monitor 参数
  • MaxScale——readwritesplit router
  • 在 Debian 13 上安装 MySQL 8.4
  • 理解从 Master/Slave 到 Source/Replica 的迁移

希望在 MaxScale 中看到这项支持吗?

如果 MySQL 8.4 兼容性对你有帮助,请阅读提案、测试该分支,并直接在 PR 中给予支持。真实环境反馈、复杂 GTID 案例和技术评审将帮助把这个 draft 变成真正能够被合并的贡献:

支持 MaxScale PR #421

分享 X LinkedIn Facebook Email PDF
← 返回博客

评论 (0)

暂无评论。

发表评论

PmaControl
+33 6 63 28 27 47 contact@pmacontrol.com
法律声明 GitHub 联系我们
不要等到故障发生才了解您的架构。 © 2014-2026 PmaControl — 68Koncept