1. 问题背景与现象描述
那天刚过完年开工,开发组的同事急匆匆找到我,说他们使用的PolarDB 8.02集群出现了异常情况。监控显示所有的SELECT查询都集中在主节点(写节点)上执行,而从节点(读节点)的负载几乎为零。这完全违背了我们使用PolarDB集群的初衷——通过读写分离来分担主节点压力。
从监控截图可以清晰看到:
- 从节点的CPU使用率长期低于5%,QPS接近于零
- 主节点的CPU使用率飙升至80%以上,明显过载
- 连接数分布也显示所有连接都集中在主节点
这种情况在PolarDB使用中其实并不罕见,通常有几种常见原因会导致读请求无法分发到从节点:
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 常见原因排查与分析
2.1 连接地址使用错误
第一种可能是应用程序错误地连接到了主节点地址而非集群地址。PolarDB提供了两种连接方式:
- 集群地址(推荐):自动实现读写分离,写请求发往主节点,读请求发往从节点
- 主地址:所有请求都直接发往主节点
重要提示:生产环境必须使用集群地址才能实现读写分离。很多开发人员因为测试时使用主地址连接,上线时忘记修改,导致读写分离失效。
2.2 显式事务的使用
第二种常见情况是应用程序使用了显式事务(BEGIN...COMMIT)。PolarDB的代理层(Proxy)为了保证事务一致性,会将整个事务路由到主节点执行。这包括以下场景:
- 明确使用BEGIN/START TRANSACTION语句
- 即使没有BEGIN语句,但设置了autocommit=0
- 事务中包含写操作(INSERT/UPDATE/DELETE)
2.3 混合读写事务
第三种情况是事务中同时包含读操作和写操作,且写操作在前。例如:
sql复制BEGIN;
UPDATE users SET status=1 WHERE id=100; -- 写操作
SELECT * FROM users WHERE id=100; -- 读操作
COMMIT;
这种情况下,PolarDB会将整个事务路由到主节点执行,以确保数据一致性。
3. 问题排查过程实录
3.1 初步排查与误判
基于上述经验,我首先询问开发团队:
- 确认使用的是集群地址而非主地址
- 确认没有使用显式事务(BEGIN
