这个错误通常发生在 OpenResty 通过 shared-proxy(如 ProxySQL、MySQL Router 等中间件)连接 MySQL 时,字符集协商出现问题。以下是详细解决方案:
错误原因分析
- 根本原因:中间件代理与MySQL服务端的字符集/collation协商失败
Unknown collation: '0'
表示客户端收到了无效的collation ID- 常见于:
- ProxySQL 版本较旧(<2.0)
- MySQL 8.0+ 使用了新collation (如
utf8mb4_0900_ai_ci
) - OpenResty驱动未正确传递collation参数
解决方案
方案1:强制指定连接参数(推荐)
在 OpenResty 连接配置中显式声明字符集和collation:
local mysql = require "resty.mysql"
local db, err = mysql:new()
local ok, err, errcode, sqlstate = db:connect{
host = "shared-proxy-ip",
port = proxy_port,
user = "user",
password = "password",
database = "db_name",
charset = "utf8mb4", -- 关键参数
collation = "utf8mb4_general_ci", -- 明确指定collation
max_packet_size = 1024 * 1024 -- 避免包大小问题
}
方案2:修改ProxySQL配置
如果使用 ProxySQL,需调整其字符集转发规则:
-- ProxySQL Admin界面执行:
UPDATE mysql_servers SET character_set="utf8mb4" WHERE port=3306;
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
方案3:升级中间件组件
# ProxySQL >=2.0.x(支持MySQL8.0协议)
apt-get install proxysql --upgrade
# OpenResty驱动更新
luarocks install lua-resty-mysql@0.25 --force
方案4:MySQL服务端降级Collation
临时解决方案(不推荐长期使用):
-- MySQL执行:
ALTER DATABASE your_db CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
调试技巧
抓包分析:
tcpdump -i any port proxy_port -w mysql.pcap
用Wireshark检查握手阶段的
Character Set
字段日志检查:
SHOW VARIABLES LIKE 'character%'; SHOW VARIABLES LIKE 'collation%';
测试直接连接: 绕过shared-proxy直连MySQL,确认是否是代理问题。
关键参数说明
参数 | 推荐值 | 作用 |
---|---|---|
charset |
utf8mb4 |
覆盖默认字符集 |
collation |
utf8mb4_general_ci |
避免新版本冲突 |
max_packet_size |
1048576 (1MB) |
防止大数据包截断 |
如果仍存在问题,请提供以下信息进一步诊断:
- OpenResty版本 (
nginx -V
) - Lua驱动版本 (
luarocks list
) - Shared-proxy类型及版本
内容由零声教学AI助手提供,问题来源于学员提问