proxysql 启动后连不上 mysql 是因未手动配置 mysql_servers 和 mysql_users 表;读写分离需配置 mysql_query_rules 规则并设 apply=1;select 匹配失败常因正则未覆盖归一化 sql;负载均衡依赖 weight>0、status='online' 及监控启用。

ProxySQL 启动后连不上 MySQL?检查 mysql_servers 表和 mysql_users 表是否已插入数据
ProxySQL 不会自动发现后端 MySQL 实例,所有节点必须手动注册。常见错误是启动 ProxySQL 后执行 mysql -h127.0.0.1 -P6033 -uadmin -padmin 能登录管理接口,但切到业务端口 6033 却报 Access denied for user 或直接连接超时。
- 先确认后端节点已写入
mysql_servers:运行INSERT INTO mysql_servers(hostgroup_id, hostname, port) VALUES (1, '192.168.1.10', 3306),再LOAD MYSQL SERVERS TO RUNTIME,最后SAVE MYSQL SERVERS TO DISK - 用户必须在
mysql_users表里显式添加,且default_hostgroup要匹配你写入mysql_servers时用的hostgroup_id - 密码字段填的是明文(不是 hash),ProxySQL 内部会自动加密存储;如果用
mysql_native_password插件认证失败,试试在 MySQL 端执行ALTER USER 'user'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd'
读写分离没生效?重点看 mysql_query_rules 的 match_digest 和 destination_hostgroup
默认情况下 ProxySQL 不做任何路由,所有语句都发往 default_hostgroup。要让 SELECT 走从库、INSERT/UPDATE/DELETE 走主库,必须配规则。
- 最简可行规则:插入两条
mysql_query_rules记录,一条match_digest = '^SELECT '指向destination_hostgroup = 2(从库组),另一条match_digest = '^INSERT |^UPDATE |^DELETE '指向destination_hostgroup = 1(主库组) -
apply = 1必须设为 1,否则规则不启用;sticky_conn = 1可选,避免事务中跨节点导致ERROR 1390 (HY000): Prepared statement not found - 规则顺序很重要:ProxySQL 从上到下匹配,所以更具体的规则(比如带注释的
/*+ read_from_slave */)要放在通用SELECT规则前面
为什么 SELECT COUNT(*) 还是打到主库?检查 match_digest 正则是否被空格或换行截断
ProxySQL 的 match_digest 匹配的是归一化后的 SQL(去掉多余空格、注释、统一大小写),但开头空格、换行符、或语句末尾分号会影响匹配结果。很多 ORM 或客户端发来的 SELECT 实际是
SELECT COUNT(*) FROM t 或 select count(*) from t;,而你写的规则是 '^SELECT ' —— 少了结尾空格或没覆盖小写形式。
- 用
SELECT * FROM stats_mysql_query_digest查看真实归一化语句长什么样,再反推正则 - 稳妥写法是
'^select [[:space:]]+count[[:space:]]*\([^)]*\)'(注意转义括号),或者直接用'^select '并确保case_sensitive = 0 - 别依赖
mysql-client命令行测试,它会自动加换行和空格;用应用程序直连或mysql --skip-auto-rehash -h127.0.0.1 -P6033 -uuser -ppass -e "SELECT COUNT(*) FROM t"更贴近真实场景
负载均衡不起作用?确认 weight 和 status 字段已正确设置,且监控线程没被禁用
ProxySQL 默认轮询,但前提是同一 hostgroup_id 下多个节点的 weight > 0 且 status = 'ONLINE'。常见问题是只加了一个从库,或误把从库状态设成 SHUNNED。
- 查状态:
SELECT hostgroup_id, hostname, port, status, weight FROM mysql_servers,确保从库组(如hostgroup_id = 2)里至少两个节点status = 'ONLINE'且weight非零 - 监控必须开启:在
proxysql.cnf里确认mysql-monitor_username和mysql-monitor_password已配置,并执行UPDATE global_variables SET variable_value='true' WHERE variable_name='mysql-monitor_enabled',否则节点状态不会自动刷新 - 权重不是百分比,而是相对值;比如两个从库
weight=10和weight=20,后者接收约 2/3 的读请求
真正麻烦的是事务上下文里的隐式读——比如先 UPDATE 再 SELECT,即使规则写了 SELECT 走从库,ProxySQL 默认也会把这条 SELECT 发回主库,避免主从延迟导致数据不一致。这个行为没法关,只能靠应用层控制或加注释强制路由。











