14.5.5 规则调试与验证方法

规则调试与验证的目标是确认 SQL 是否按预期命中规则并路由到正确的 hostgroup,同时避免误杀或遗漏。核心思路是“配置—加载—观察—验证—回滚”闭环。

原理草图:规则命中与路由闭环

文章图片

1. 调试前准备(命名与最小变更)
- 目标明确:读写分离、强制主库、特定业务 SQL 路由。
- 规则命名规范:rule_id 连续编号;comment 标记业务、负责人、变更单号。
- 最小变更原则:一次只改少量规则,易于回滚与对比。

2. 管理接口连接与规则安装/加载

ProxySQL 已部署后无需额外安装,仅需具备管理端口访问与 mysql 客户端。

# 连接 ProxySQL 管理端(默认 6032)
mysql -uadmin -padmin -h127.0.0.1 -P6032
-- 1) 新增或修改规则(示例:读写分离)
INSERT INTO mysql_query_rules
(rule_id, active, match_pattern, destination_hostgroup, apply, comment)
VALUES
(1001, 1, '^SELECT', 20, 1, 'rw_split:read_only');

INSERT INTO mysql_query_rules
(rule_id, active, match_pattern, destination_hostgroup, apply, comment)
VALUES
(1002, 1, '^(INSERT|UPDATE|DELETE)', 10, 1, 'rw_split:write_primary');

-- 2) 加载到运行层并持久化
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;

命令解释
- mysql_query_rules:配置层规则表,修改后必须加载到 runtime 才生效。
- LOAD ... TO RUNTIME:将配置层同步到运行层。
- SAVE ... TO DISK:持久化到磁盘,防止重启丢失。

3. 运行层验证与命中统计

-- 查看配置层与运行层规则一致性
SELECT rule_id, active, apply, match_pattern, destination_hostgroup, comment
FROM mysql_query_rules ORDER BY rule_id;

SELECT rule_id, active, apply, match_pattern, destination_hostgroup, comment
FROM runtime_mysql_query_rules ORDER BY rule_id;
-- 命中统计:看规则是否被触发
SELECT rule_id, hits, last_hit, active, comment
FROM stats_mysql_query_rules ORDER BY rule_id;

4. 路由结果验证(连接池与后端主从)

-- 观察后端连接池变化,确认请求落到正确 hostgroup
SELECT hostgroup, srv_host, status, ConnUsed, ConnFree
FROM stats_mysql_connection_pool
ORDER BY hostgroup, srv_host;

解释
- ConnUsed 在测试 SQL 后应在对应 hostgroup 有增长。
- 如果 hits 有增长但连接池无变化,可能被上游连接复用或命中缓存规则。

5. 调试技巧(不影响业务)
- 临时只观察不生效:将 apply=0,确认匹配范围后再启用。

UPDATE mysql_query_rules SET apply=0 WHERE rule_id=1001;
LOAD MYSQL QUERY RULES TO RUNTIME;
  • 限定范围:优先使用精确匹配,避免广泛正则误命中。
UPDATE mysql_query_rules
SET match_pattern='^SELECT .* FROM order_'
WHERE rule_id=1001;

6. 典型验证用例(可直接执行)

-- 只读 SQL:应路由到 hostgroup 20
SELECT * FROM order_2024 LIMIT 1;

-- 写 SQL:应路由到 hostgroup 10
UPDATE order_2024 SET status=2 WHERE id=100;
-- 事务一致性验证:事务内 SELECT 应走主库
BEGIN;
SELECT * FROM order_2024 WHERE id=100 FOR UPDATE;
COMMIT;

7. 排错方法与回滚(含明确命令)
- 规则未生效:
- 检查 active=1apply=1,规则是否加载到 runtime。
- 检查 rule_id 优先级,是否被更高优先级覆盖。

SELECT rule_id, active, apply, match_pattern, destination_hostgroup
FROM runtime_mysql_query_rules ORDER BY rule_id;
  • 误路由(正则过宽):
-- 收紧正则并重载
UPDATE mysql_query_rules
SET match_pattern='^SELECT .* FROM report_'
WHERE rule_id=1001;
LOAD MYSQL QUERY RULES TO RUNTIME;
  • 回滚到上一个版本(示例:禁用并重载)
UPDATE mysql_query_rules SET active=0 WHERE rule_id IN (1001,1002);
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;

8. 实战练习
1) 新建两条规则:读 SELECT 到 hostgroup=20,写 INSERT/UPDATE/DELETE 到 hostgroup=10。
2) 执行三条 SQL:一条 SELECT、一条 UPDATE、一条 SELECT ... FOR UPDATE。
3) 在 stats_mysql_query_rules 里确认 hits 变化,在 stats_mysql_connection_pool 里确认对应 hostgroup ConnUsed 增长。
4) 将 apply=0 验证匹配但不生效,观察 hits 变化是否仍然增长。