ProxySQL需显式配置双集群hostgroup、依赖@@read_only健康检查、用注释规则路由写请求至新集群,并确保新集群GTID与缓冲池预热到位,否则将引发连接错误或数据不一致。

MySQL升级期间要实现读写流量无缝切换,ProxySQL不是“开箱即用”的切换开关,而是需要提前配置好双集群拓扑、健康检查策略和路由规则的流量调度中间件;没做前置验证就切流,大概率会触发 mysql_connection_error 或写请求路由到只读实例。
如何让ProxySQL识别新旧MySQL集群并维持连接池
ProxySQL不自动发现后端,必须显式添加 mysql_servers 并设置 hostgroup_id 区分角色。旧集群(v5.7)和新集群(v8.0)需分配不同 hostgroup_id,比如 10 为旧写组、20 为新写组、30 为只读组(可跨版本复用)。关键点是:所有后端必须开启 read_only=ON(从库)或 OFF(主库),ProxySQL依赖 SELECT @@read_only 的结果做健康判断,否则 mysql_server_read_only 状态会误判。
实操建议:
- 先在
mysql_servers表中插入新集群地址,status='ONLINE'但weight=0,避免自动承接流量 - 执行
LOAD MYSQL SERVERS TO RUNTIME后,用SELECT * FROM monitor.mysql_server_ping_log确认新节点心跳正常 - 不要跳过连接池预热:用
mysql -h127.0.0.1 -P6033 -uadmin -padmin -e "SELECT 1"触发 ProxySQL 主动建连,避免切流瞬间大量Too many connections
怎么配置读写分离规则,确保升级时写请求不误发到旧集群
靠 mysql_query_rules 控制语句路由,但默认规则无法区分“升级中”状态。必须引入自定义变量或注释标记来触发切换,比如应用在事务开头加 /*+ USE_NEW_CLUSTER */,再配一条匹配该注释的规则,将匹配语句强制路由到新写组(destination_hostgroup=20)。
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
实操建议:
- 旧规则(匹配
^SELECT)保持指向只读组(30),但需设apply=1且sticky_conn=1防止主从延迟导致的脏读 - 新增规则优先级高于旧规则,
match_digest设为"USE_NEW_CLUSTER",destination_hostgroup指向新写组,并开启cache_ttl=0避免规则缓存延迟 - 禁止使用
match_pattern做正则匹配写请求——MySQL 8.0 的INSERT ... ON DUPLICATE KEY UPDATE语法可能被旧版规则错误拦截
为什么切流后出现 “Lock wait timeout exceeded” 或主从延迟飙升
这不是ProxySQL的问题,而是新集群未完成预热或GTID模式不一致导致的。ProxySQL转发请求后,如果新主库的 innodb_buffer_pool_size 还是默认值、或 gtid_mode=OFF 而旧集群是 ON,复制线程会卡在 event 解析阶段,ProxySQL却仍认为该节点 ONLINE。
实操建议:
- 升级前在新集群执行
SELECT COUNT(*) FROM information_schema.INNODB_BUFFER_POOL_PAGES,确认 buffer pool 已加载热点数据 - 用
SHOW SLAVE STATUS\G检查Seconds_Behind_Master和Retrieved_Gtid_Set是否连续,不连续说明 GTID 跳变,需人工补全gtid_purged - 切流后盯住
stats_mysql_connection_pool表里的ConnUsed和Queries,若某 hostgroup 的ConnUsed长时间为 0,说明路由规则未生效
真正难的不是配置几条 SQL,而是让 ProxySQL 的健康检查、应用层注释、MySQL 复制状态三者对齐;任何一个环节的时间差超过 3 秒,就可能造成写请求丢失或读取到过期数据。

















