通过ProxySql调用MySQL存储过程失败,报Table 'mysql.proc'不存在错误
这个问题的核心原因是MySQL 8.0移除了mysql.proc系统表(替换为information_schema.routines),而你的ProxySQL版本可能对MySQL 8.0的兼容性不足,或者.NET驱动在调用存储过程时的元数据查询没有被ProxySQL正确处理。结合你的场景(SqlYog正常但.NET报错),可以按以下步骤解决:
1. 升级ProxySQL到兼容MySQL 8.0的版本
旧版本的ProxySQL(比如1.4.x之前的部分版本)没有适配MySQL 8.0的系统表变更,会在处理存储过程相关的元数据查询时尝试访问已被移除的mysql.proc。建议升级到ProxySQL 2.0及以上版本,这些版本完全支持MySQL 8.0的系统架构。
升级后,记得重启ProxySQL服务,并验证其与RDS主从节点的连接状态:
SELECT * FROM mysql_servers; -- 检查节点状态是否为ONLINE
2. 调整.NET连接字符串参数
你的MySql.Data驱动版本(8.0.13)在调用存储过程时,默认会尝试查询存储过程的元数据(比如参数、返回结构),这个查询可能被ProxySQL错误转发或者无法正确解析。可以在连接字符串中添加Use Procedure Bodies=False,让驱动跳过元数据查询,直接执行存储过程调用:
server=xxx.amazonaws.com;Port=6033;user=xxx;database=abc;password=xxxx;charset=utf8mb4;Use Procedure Bodies=False
这个参数会告诉驱动:不需要提前获取存储过程的定义信息,直接发送CALL命令到数据库,避免触发对mysql.proc的查询。
3. 检查ProxySQL的路由规则
确保存储过程的调用语句(以CALL开头)被正确路由到主节点(因为存储过程可能包含写操作)。可以在ProxySQL中添加专门匹配CALL语句的规则:
INSERT INTO mysql_query_rules (rule_id, active, match_pattern, destination_hostgroup, apply) VALUES (100, 1, '^CALL', 1, 1); -- 假设主节点的hostgroup ID是1 LOAD MYSQL QUERY RULES TO RUNTIME; SAVE MYSQL QUERY RULES TO DISK;
这样所有CALL开头的语句都会被路由到主节点,避免因路由到从节点导致的权限或元数据问题。
4. 验证ProxySQL的MySQL兼容性配置
确保ProxySQL的全局配置适配MySQL 8.0的认证方式和系统设置:
SET mysql-default_auth_plugin='mysql_native_password'; -- 匹配RDS的认证插件(RDS 8.0默认可能还是mysql_native_password) SET mysql-have_innodb=1; LOAD MYSQL VARIABLES TO RUNTIME; SAVE MYSQL VARIABLES TO DISK;
完成以上步骤后,重新测试.NET应用的存储过程调用,应该就能解决这个报错了。
内容的提问来源于stack exchange,提问作者Nitin Agarwal

