答案是proxysql,因其唯一支持运行时动态权重调整:需修改mysql_servers.weight表并执行load mysql servers to runtime,确保变更即时生效且持久化;直接更新runtime_mysql_servers虽即时但重启失效,易引发流量错乱。

ProxySQL 是目前唯一能在运行时真正支持动态权重调整的 MySQL 代理层方案。MaxScale 的 weight 参数仅在 reload 配置后生效,不满足“动态”要求;MySQL Router 更无权重概念。所以,答案很明确:用 ProxySQL,改 mysql_servers.weight 表,并加载到 runtime。
为什么必须用 mysql_servers.weight 而不是配置文件?
ProxySQL 的配置分两层:磁盘持久化(mysql_servers 表)和内存运行时(runtime_mysql_servers)。只有修改前者再执行 LOAD MYSQL SERVERS TO RUNTIME,才能让权重变更即时生效且不丢失。直接 UPDATE runtime_mysql_servers 会立即生效,但服务重启后失效——这在故障切换或滚动调整中极易引发流量错乱。
常见错误现象:
• 权重改了但流量没变 → 忘了 LOAD 或 SAVE
• 重启后回到旧权重 → 只改了 runtime 表
• 多个从库权重归零却仍有请求 → 健康检查未触发剔除,需确认 mysql_replication_hostgroups 和监控模块已启用
UPDATE mysql_servers SET weight 的实操要点
权重不是绝对值,而是相对比例。假设你有两个从库:
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
-
replica1当前weight = 100,replica2当前weight = 50→ 实际分配比为 2:1 - 若想临时将
replica1承担全部读流量,设weight = 1000、replica2设weight = 1即可,无需清零(清零反而可能因健康状态未同步导致路由异常) - 权重为 0 仅表示“不参与负载”,但节点仍保留在 hostgroup 中,可用于快速恢复
- 避免权重过大(如 >10000),可能导致浮点精度计算偏差,官方建议控制在 1–1000 区间
权重变化如何影响真实流量?
实际分配概率由公式 P_i = w_i * S_i / Σ(w_k * S_k) 决定,其中 S_i 是健康状态(0 或 1)。这意味着:
- 即使你把
replica1的weight设为 1000,只要它健康状态S_i = 0(比如复制延迟超阈值),它就完全收不到读请求 - 权重调整不能绕过健康检查 —— 必须确保
MariaDB-Monitor或mysql-monitor模块已启用,且replication_lag_threshold设置合理(通常 500–2000ms) - 如果某个从库
S_i = 0,它的w_i无论多少都不计入分母求和,此时其他节点的占比会自动升高
怎么验证权重生效了?
别只看配置表,要查实时统计:
- 执行
SELECT hostgroup, hostname, weight, status FROM mysql_servers WHERE hostgroup = 20(假设读组是 20)确认权重已写入 - 执行
SELECT hostgroup, SUM(count_star) AS cnt FROM stats_mysql_query_digest GROUP BY hostgroup观察最近 1 分钟各组请求数占比 - 更细粒度:查
stats_mysql_connection_pool中Connections_used字段,看各后端连接数是否随权重比例变化
真实场景里最容易被忽略的,是权重调整和健康状态之间的耦合关系——你调了权重,但没确认监控模块是否真把节点标记为可用,结果流量根本没过去。动态权重不是“设完就跑”,而是“设 + 查 + 验”三步闭环。










