mysql代理用户功能需显式开启check_proxy_users=on才生效,grant proxy语法严格且必须刷新权限,客户端须显式指定--proxy-user参数,proxysql不支持透传该机制。

check_proxy_users 必须显式开启,否则 GRANT PROXY 完全无效
MySQL 默认关闭代理用户功能,check_proxy_users 变量为 OFF 时,哪怕 GRANT PROXY 执行成功,代理关系也完全不生效。这不是配置遗漏,而是硬性开关。
临时启用:SET GLOBAL check_proxy_users = ON;
永久启用:在 my.cnf 的 [mysqld] 段添加 check_proxy_users=ON,然后重启 MySQL。
验证是否生效:SHOW VARIABLES LIKE 'check_proxy_users';,返回 ON 才算到位。
注意:若用 mysql_native_password(5.7+ 默认),还需同时开启 mysql_native_password_proxy_users=ON;8.0+ 若用 caching_sha2_password,Proxy User 不支持,必须先切回 mysql_native_password:
ALTER USER 'app_user'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd';
GRANT PROXY 语法严格,host 和引号一个都不能错
代理授权不是普通权限,语法固定且对引号、host、空格极其敏感。常见错误是漏掉 host 或写错格式,导致报错 ERROR 1410 (42000)。
-
'real_user'@'%'中的 host 必须和CREATE USER 'real_user'@'%'完全一致——不能是'real_user'@'localhost',也不能省略引号 - 不能写成
GRANT PROXY ON real_user TO app_user(漏引号、漏 host) - 正确写法只有一种:
GRANT PROXY ON 'real_user'@'%' TO 'app_user'@'%'; - 执行后必须
FLUSH PRIVILEGES;,否则mysql.proxies_priv表不会更新 - 验证是否写入:
SELECT * FROM mysql.proxies_priv WHERE User='app_user' AND Host='%';
客户端连接必须显式声明 --proxy-user 或等效参数
ProxySQL 不支持透传 Proxy User,这个机制只在直连 MySQL 时有效。应用必须主动告诉 MySQL “我要以谁的身份运行”,否则 CURRENT_USER() 始终是 app_user,权限不会切换。
不同客户端写法:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- 命令行:
mysql -uapp_user -p --proxy-user=alice - JDBC URL(驱动 ≥ 8.0.22):
?proxyUser=alice - Python
mysql-connector-python:proxy_user='alice'参数
验证是否生效:SELECT USER(), CURRENT_USER();,前者应为 app_user@client_ip,后者为 alice@%——只有 CURRENT_USER() 决定实际权限。
连接池里用 Proxy User 要绕过 ProxySQL,直连后端 MySQL
ProxySQL 本身不支持 Proxy User 透传,它只认自己 mysql_users 表里的账号,完全不查后端 mysql.user 或 mysql.proxies_priv。所以想让连接池统一用 app_user 连接,再按实际操作人走不同权限,必须跳过 ProxySQL,让应用直连后端 MySQL 实例。
如果仍需中间件做 SQL 过滤或路由,只能分层处理:
- ProxySQL 负责认证、路由、SQL 拦截(如拦截
DROP) - 真实权限控制交给后端 MySQL 的 Proxy User 机制
- 客户端连接字符串中必须带
proxyUser参数,且后端 MySQL 已开启check_proxy_users
容易被忽略的是:ProxySQL 配置的 mysql_users 表里,app_user 的 password 字段必须填对哈希值(比如 authentication_string),而它的 default_hostgroup 必须指向一个真实存在的 hostgroup_id,否则即使认证通过,也会在路由阶段静默失败。










