MySQL升级记录需查mysql_upgrade执行日志,8.0.16+由mysqld自动执行;权限变更源于mysql.user表结构重构,GRANT行为受sql_mode影响,连接失败常因认证插件变更;通用日志可追溯DDL/DML操作。

查 MySQL 升级记录:先看 mysql_upgrade 是否执行过
MySQL 本身不自动记录“谁在什么时候升了哪个版本”,但每次 major 版本升级(如 5.7 → 8.0)后,必须手动运行 mysql_upgrade 工具来更新系统表结构。这个命令的执行日志、时间戳和退出状态,就是最直接的升级证据。
常见错误现象:mysql_upgrade 执行失败却没被发现,导致后续权限异常、视图报错或 INFORMATION_SCHEMA 字段缺失——这其实是升级“半途而废”的信号。
- 检查最近一次执行时间:
grep "mysql_upgrade" /var/log/mysql/error.log或翻/var/log/mysqld.log(路径依启动方式而定) - 确认是否成功:返回码为 0,且日志末尾有类似
Phase 2/2 completed的提示 - 注意:MySQL 8.0.16+ 已弃用
mysql_upgrade,改由 mysqld 启动时自动执行;但旧版本残留的未升级表仍可能引发权限问题
权限变更源头:mysql.user 表结构在 8.0 发生断裂式变化
从 MySQL 5.7 升到 8.0,mysql.user 表字段减少近一半(比如删掉了 Password、ssl_cipher 等 10+ 列),同时引入 account_locked、password_reuse_history 等新列。这不是兼容性调整,是重构——意味着所有依赖旧字段的自定义脚本、监控项、备份还原逻辑都会出问题。
典型表现:SELECT User,Password FROM mysql.user 在 8.0 报错 Unknown column 'Password' in 'field list';或者用 mysqldump 备份再导入时提示字段数不匹配。
- 升级前务必检查所有访问
mysql.user的代码,替换成authentication_string字段 -
GRANT语句行为也变了:8.0 默认启用sql_mode=STRICT_TRANS_TABLES,空用户名、无密码用户会被拒绝创建 - 权限迁移不是自动的:如果用了
mysqldump --all-databases备份再还原,mysql库不会被包含(除非显式加上),导致权限丢失
验证升级后权限是否生效:别只信 SHOW GRANTS
SHOW GRANTS FOR 'user'@'host' 显示的是当前账号的“授权快照”,但它不反映实际生效权限——尤其当存在角色(ROLE)、动态权限(如 BACKUP_ADMIN)或 proxy 用户时,权限是叠加计算的。
最容易踩的坑:升级后用老账号连不上,SHOW GRANTS 看着没问题,但其实因为认证插件从 mysql_native_password 变成 caching_sha2_password,客户端不支持就直接拒连,根本走不到权限校验环节。
- 先确认连接层是否通过:
mysql -u user -p -h host --default-auth=mysql_native_password - 再查实际权限合并结果:
SELECT * FROM information_schema.role_table_grants WHERE grantee = "'user'@'host'"; - 注意:8.0 中
CREATE USER默认绑定caching_sha2_password,老应用若用 JDBC 8.0 以下驱动,需显式配置allowPublicKeyRetrieval=true&useSSL=false
审计建议:用 general_log + 时间窗口定位升级操作痕迹
没有专用审计表?那就用 MySQL 自带的通用日志回溯。虽然它不区分“升级动作”,但能抓到 mysql_upgrade 调用时执行的一系列 ALTER TABLE、CREATE PROCEDURE 和 UPDATE mysql.* 操作,时间集中、模式固定。
性能影响明显:开启 general_log 会显著拖慢高并发写入场景,所以不能常开,只应在升级前后短期启用(比如升级前 1 小时 + 升级后 30 分钟)。
- 临时开启:
SET GLOBAL general_log = ON; SET GLOBAL general_log_file = '/tmp/mysql_upgrade_trace.log'; - 筛选关键操作:
grep -E "(ALTER TABLE.*mysql\.|UPDATE mysql\.|CREATE PROCEDURE.*mysql_upgrade)" /tmp/mysql_upgrade_trace.log - 注意:日志里不会出现“upgrade”字样,一切线索都藏在对
mysql库的 DDL/DML 中——这是唯一可靠的事后取证方式
真正麻烦的不是升级动作本身,而是那些没进日志的隐式变更:比如 performance_schema 表结构刷新、sys 库视图重装、甚至 max_connections 默认值调整。这些不会报错,但会让监控指标突然偏移,得靠比对升级前后的 SHOW VARIABLES 输出才能揪出来。


















