mysql不保存密码修改历史,password_last_changed仅为单次快照;无mysql.password_history表;审计需提前启用server_audit插件并配置query事件,或应急启用general_log快速排查。

查 password_last_changed 只能看最后一次,不是历史记录
很多人一上来就执行 SELECT user, host, password_last_changed FROM mysql.user;,以为能翻出多次改密时间线。实际上这个字段只存最近一次成功修改的时间戳,覆盖写入,前几次全丢。它不构成“历史记录”,只是个单点快照。如果你看到某用户 password_last_changed 是 2026-05-20,那只能说明那天改过,但无法判断是第几次、谁操作的、改之前是什么密码。
MySQL 8.0 没有 mysql.password_history 表,别硬查
直接运行 SELECT * FROM mysql.password_history; 会报错 Table 'mysql.password_history' doesn't exist —— 这张表根本不存在。MySQL 社区版从没提供过内置的历史密码表。网上教程里提到的 mysql.password_history 要么是误传,要么混淆了 Percona Server 或 MariaDB 的扩展功能。你查不到,不是权限问题,是它压根没被创建。
真要审计,必须提前启用 server_audit 插件
这是社区版唯一可行的审计路径,但前提是:日志得在密码被改之前就开着。临时抱佛脚没用。
- 确认插件路径:
SELECT @@plugin_dir;,下载对应平台的server_audit.so(Linux)或server_audit.dll(Windows)放进去 - 安装并启用:
INSTALL PLUGIN server_audit SONAME 'server_audit.so';,然后SET GLOBAL server_audit_logging = ON; - 关键配置:
SET GLOBAL server_audit_events = 'QUERY';(必须含QUERY,否则ALTER USER和SET PASSWORD不会被捕获) - 日志默认写到
server_audit.log(在datadir下),内容类似:20260610 09:15:22,192.168.1.100,admin,QUERY,ALTER USER 'app'@'%' IDENTIFIED BY '***'
注意:server_audit 不记录失败的改密操作,也不记录绕过 SQL 接口的手动更新 mysql.user 表行为 —— 那种改法连审计都抓不住。
临时排查可开 general_log,但别留着
如果审计插件没装、又急需定位最近一次改密是谁干的,且数据库负载不高、磁盘够大,可短时启用通用日志:
- 先查路径:
SHOW VARIABLES LIKE 'general_log_file'; - 开启:
SET GLOBAL general_log = ON; - 快速过滤:
grep -i "alter user\|set password\|create user" /var/lib/mysql/hostname.log - 立刻关掉:
SET GLOBAL general_log = OFF;(不关的话,几小时就能撑爆磁盘)
general_log 记录所有语句,包括敏感明文密码,且不区分权限上下文 —— 它不是审计方案,只是应急快照。生产环境绝不能长期开着。
真正能回溯“谁、何时、为什么改密码”的,只有持续运行的审计日志。事后补救,基本等于没有。











