这个错误是因为 ShardingSphere-Proxy 默认要求使用更安全的密码认证协议,而 OpenResty 中某些 MySQL 客户端库可能尝试使用旧的认证协议导致连接被拒绝。
以下是解决方案:
1. 根本原因
- MySQL 8.0+ 默认使用
caching_sha2_password
认证插件,而旧版客户端(如某些 Lua MySQL 库)可能仅支持mysql_native_password
协议。 - ShardingSphere-Proxy 背后依赖的 MySQL 版本如果较高(如 8.0),会强制使用新协议。
2. 解决方案
方案一:修改 ShardingSphere-Proxy 后端的 MySQL 用户认证方式
在 ShardingSphere-Proxy 实际连接的 后端 MySQL 服务器 上执行:
-- 将用户密码认证方式改为 mysql_native_password
ALTER USER 'your_username'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password';
FLUSH PRIVILEGES;
说明:
这将允许旧版客户端通过 mysql_native_password
协议连接。但需注意安全性略低于 caching_sha2_password
。
方案二:升级 OpenResty 的 MySQL 客户端库
确保使用的 Lua MySQL 库支持新认证协议:
- 推荐使用
lua-resty-mysql
(OpenResty 官方维护):
更新到最新版本,并确认其支持caching_sha2_password
。 - 如果使用的是较老的库(如
luasql.mysql
),建议替换为lua-resty-mysql
。
示例连接代码(需显式指定协议):
local mysql = require "resty.mysql"
local db, err = mysql:new()
if not db then
ngx.say("Failed to create MySQL object: ", err)
return
end
db:set_timeout(1000) -- 1秒超时
-- 连接时显式指定认证协议选项(部分库支持)
local ok, err, errcode, sqlstate = db:connect{
host = "shardingsphere-proxy-host",
port = 3307, -- ShardingSphere-Proxy 默认端口
database = "your_database",
user = "your_username",
password = "your_password",
options = {
auth_plugin = "mysql_native_password" -- 强制使用旧协议(兼容性方案)
}
}
if not ok then
ngx.say("Connection failed: ", err, " (", errcode, ")", sqlstate)
return
end
方案三:调整 ShardingSphere-Proxy 的服务器配置
在 ShardingSphere-Proxy 的配置文件 server.yaml
中,调整 MySQL 兼容性参数:
props:
#允许旧版认证协议
authentication-method: mysql_native_password
###3. 验证步骤
- 测试直接连接后端 MySQL:
先用标准 MySQL客户端连接 ShardingSphere-Proxy的后端数据库,确认认证方式是否兼容。 - 检查库版本:
确认 OpenResty中使用的 Lua MySQL库是否为最新版。
###4. 注意事项
- 安全性权衡:使用
mysql_native_password
会降低认证安全性,仅建议在内部网络或测试环境使用。 - 代理层限制:ShardingSphere Proxy本身对认证协议的转发可能存在限制,需确保其版本与后端MySQL兼容。
如果问题仍存在,请提供以下信息以便进一步排查:
- OpenResty版本及 Lua MySQL库名称和版本;
- ShardingSphere Proxy和后端MySQL的版本;
3.完整的错误日志。
内容由零声教学AI助手提供,问题来源于学员提问