1. 为什么MySQL要升级认证插件?
如果你最近升级到MySQL 8.4或9.0,可能会遇到一个头疼的问题:用老方法连接数据库突然不好使了。这其实是因为MySQL从8.0开始,把默认的认证插件从mysql_native_password换成了caching_sha2_password。我刚开始用8.0的时候也被这个改动坑过,明明密码是对的却死活连不上。
简单来说,mysql_native_password用的是SHA-1算法,这个算法现在已经被证明不够安全了。而caching_sha2_password用了更先进的SHA-256算法,还加了盐值(就是随机字符串)和5000轮哈希,安全性提升了好几个档次。打个比方,就像你家门锁从普通的弹子锁升级成了指纹+密码+人脸识别的智能锁。
不过这个升级也带来了一些兼容性问题。很多老版本的客户端工具(比如MySQL 5.7的客户端)还不支持新的认证方式,连接时会报"Authentication plugin 'caching_sha2_password' cannot be loaded"这样的错误。我在帮客户升级时就遇到过好几次这种情况,下面我会详细说说怎么解决。
2. 两种认证插件的技术对比
2.1 mysql_native_password的工作原理
这个老牌认证插件的工作方式其实挺简单:
- 你把密码存到MySQL时,它会用SHA1算法算两次(SHA1(SHA1(password))),然后把结果存到mysql.user表的authentication_string字段里
- 登录时客户端用同样的算法算一遍密码,把结果发给服务端比对
-- 查看使用mysql_native_password的用户 SELECT user, host, plugin FROM mysql.user WHERE plugin = 'mysql_native_password';但问题在于:
- SHA1算法现在很容易被暴力破解
- 同样的密码生成的哈希值相同,容易被彩虹表攻击
- 没有加盐机制,安全性不够
2.2 caching_sha2_password的改进
新插件做了这些升级:
- 使用SHA256算法,强度更高
- 每次加密都会生成随机盐值,相同密码也会得到不同哈希值
- 默认进行5000轮哈希计算,大大增加破解难度
- 支持内存缓存,验证过的用户下次登录更快
-- 新创建的用户默认使用新插件 CREATE USER 'new_user'@'%' IDENTIFIED BY 'securePassword123'; -- 查看会发现plugin是caching_sha2_password实际存储的密码格式类似这样:
$A$005$1%h5f1OdZ0'46}M[uz5Di5wW2WWg8eeLWynsg2h3xnzHwQLmm39bEqLBxB0其中:
- $A$表示算法类型
- 005表示迭代次数
- 后面跟着盐值和哈希值
3. 迁移到caching_sha2_password的完整步骤
3.1 检查当前使用的认证插件
迁移前先看看现有用户的情况:
SELECT user, host, plugin, authentication_string FROM mysql.user;如果看到plugin列大部分是mysql_native_password,说明需要迁移。
3.2 单个用户迁移方法
最简单的迁移方式是使用ALTER USER命令:
-- 迁移单个用户 ALTER USER 'existing_user'@'%' IDENTIFIED WITH caching_sha2_password BY 'new_password'; -- 迁移后记得刷新权限 FLUSH PRIVILEGES;注意:如果客户端工具不支持新插件,这时候连接可能会出问题。别急,后面会讲解决方案。
3.3 批量迁移所有用户
如果需要迁移大量用户,可以用这个脚本:
-- 生成迁移语句 SELECT CONCAT('ALTER USER \'', user, '\'@\'', host, '\' IDENTIFIED WITH caching_sha2_password BY \'临时密码\';') FROM mysql.user WHERE plugin = 'mysql_native_password' AND user NOT LIKE 'mysql.%';把生成的SQL执行后,记得通知用户修改密码。
3.4 修改默认认证插件
如果想确保新用户都用新插件,修改my.cnf配置文件:
[mysqld] default_authentication_plugin=caching_sha2_password改完后需要重启MySQL服务。
4. 常见问题解决方案
4.1 客户端不支持新插件怎么办
如果遇到"Authentication plugin 'caching_sha2_password' cannot be loaded"错误,有几种解决方案:
- 升级客户端:MySQL 8.0+的客户端都支持新插件
- 临时降级用户认证:
ALTER USER 'your_user'@'%' IDENTIFIED WITH mysql_native_password BY 'password'; - 连接时指定公钥:
mysql -u your_user -p --get-server-public-key
4.2 远程连接失败问题
新插件默认要求安全连接,如果没配SSL可能会报错。解决方法:
- 启用SSL(推荐)
- 或者修改用户设置:
ALTER USER 'remote_user'@'%' REQUIRE SSL; -- 或者 REQUIRE NONE
4.3 性能调优建议
新插件默认5000轮哈希,如果服务器压力大可以调整:
-- 降低哈希轮数(最小5000) SET GLOBAL caching_sha2_password_digest_rounds = 5000;但要注意,轮数越少安全性越低。
5. 安全性最佳实践
5.1 密码策略配置
配合新认证插件,建议加强密码策略:
-- 密码有效期90天 ALTER USER 'user'@'%' PASSWORD EXPIRE INTERVAL 90 DAY; -- 密码历史记录5次 SET GLOBAL password_history = 5;5.2 监控和审计
定期检查认证方式:
-- 检查仍在使用旧插件的用户 SELECT user, host FROM mysql.user WHERE plugin = 'mysql_native_password';5.3 备份恢复注意事项
迁移认证插件后,备份恢复时要注意:
- 导出数据时加上--all-databases和--users参数
- 恢复前检查my.cnf中的默认认证插件设置
- 测试恢复后各应用的连接情况
6. 实际迁移案例分享
去年帮一个电商平台做MySQL 5.7到8.0的升级,就遇到了认证插件的问题。他们的ERP系统用的老版本JDBC驱动,直接升级后全部连不上数据库。
我们的解决方案是:
- 先批量把关键业务用户改回mysql_native_password
- 升级所有客户端驱动
- 分批次迁移用户到新认证插件
- 最后设置默认使用caching_sha2_password
整个过程花了2周时间,中间遇到最坑的问题是某个报表系统用的第三方工具,厂商已经不更新了,最后只能单独为这个系统保留了一个用旧认证插件的用户。