mysql 8.0+ 中密码最后修改时间存储在 mysql.user 表的 password_last_changed 字段,仅 root 或具备 select 权限的管理员可查询,普通用户无权访问;该字段为 timestamp 类型,值为 null 表示从未合法修改过密码,且 mysql 5.7 及更早版本不支持此字段。

MySQL 8.0+ 中密码修改时间存在,但不直接暴露给普通用户
MySQL 8.0 开始引入了 password_last_changed 字段,但它只对具备 SELECT 权限的 mysql.user 表可见,且默认只有 root 或拥有 SELECT 权限的管理员能查。普通用户即使查自己的记录也看不到该字段——权限模型默认屏蔽了它。
常见错误现象:SELECT password_last_changed FROM mysql.user WHERE User='xxx'; 执行报错 Access denied,或返回空结果(不是 NULL,是没权限读该列)。
- 必须用具有
SELECT权限的高权限账号(如 root)执行查询 - 字段仅在启用密码策略(
validate_password插件启用)且用户密码由ALTER USER ... PASSWORD EXPIRE或显式SET PASSWORD修改后才更新 - 如果用户是通过复制
authentication_string值绕过密码机制创建的,password_last_changed可能为NULL
查密码最后修改时间的正确 SQL 语句
用 root 或等效权限账号登录后执行:
SELECT User, Host, password_last_changed FROM mysql.user WHERE User = 'your_username' AND Host = 'your_host';
注意 User 和 Host 是联合主键,必须同时匹配;your_host 常见值如 'localhost'、'%' 或具体 IP,不能省略。
- 返回结果中
password_last_changed为NULL表示该用户创建后从未通过合法方式修改过密码(比如直接 UPDATEauthentication_string) - 该字段类型是
TIMESTAMP,时区跟随 MySQL 服务器时区,不是客户端会话时区 - MySQL 5.7 及更早版本没有此字段,强行查询会报错
Unknown column 'password_last_changed' in 'field list'
为什么 SHOW CREATE USER 不显示修改时间
SHOW CREATE USER 'xxx'@'yyy'; 只输出账户定义语句(如认证插件、SSL 设置、资源限制),不包含运行时状态字段。它本质上是反向生成建账语句,而非查询当前元数据快照。
- 该命令无法替代对
mysql.user表的直接查询 - 即使密码刚改完,
SHOW CREATE USER输出里也绝不会出现时间戳类信息 - 某些运维工具(如 phpMyAdmin)界面里“最后修改”时间其实是取自
password_last_changed,底层仍是查表
应用层记录密码变更更可靠
依赖 password_last_changed 有局限:它不记录谁改的、为什么改、是否成功生效(比如改完立刻被策略拒绝)。生产环境建议在应用层主动落库记录。
- 在调用
ALTER USER或SET PASSWORD后,立即向业务日志表插入一条含时间、操作人、目标用户、操作结果的记录 - 避免直接依赖 MySQL 内部字段做审计,因为权限收紧或升级可能改变行为
- 如果必须用 MySQL 原生方案,可配合
general_log或audit log插件捕获ALTER USER语句,但开销大、解析麻烦
真正要确认某次密码修改是否生效,最直接的方式是用新密码尝试连接——password_last_changed 只是辅助参考,不是权威凭证。











