MySQL 8.0原生不支持密码过期前自动告警,password_expiration_warning_days仅影响SHOW CREATE USER输出注释,对客户端、驱动、连接池无实际提醒作用,真实告警需外部脚本轮询mysql.user表并外发通知。

MySQL 8.0 **原生不支持密码过期前自动告警**(如邮件、弹窗、日志警告等),所谓“告警”必须由外部系统实现;password_expiration_warning_days 只影响 SHOW CREATE USER 输出中的注释,**对客户端、驱动、连接池完全无实际提醒作用**。
为什么 password_expiration_warning_days 不会真正告警
这个系统变量仅控制 MySQL 在执行 SHOW CREATE USER 时,是否在输出 SQL 的注释里加上类似 /* PASSWORD EXPIRE INTERVAL 90 DAY WARNING 7 DAY */ 的说明。它:
- 不触发任何日志写入、不生成 error log 或 general log 条目
- 不修改客户端行为:JDBC、MySQL Shell、Django ORM 都不会解析或响应这个注释
- 不改变登录流程:用户仍能正常连接,直到真正过期那一刻才报
ERROR 1820 - 无法被监控工具(如 Prometheus + mysqld_exporter)直接采集为指标
真实可用的“告警”只能靠外部脚本轮询
生产环境要实现提前通知,唯一可靠路径是定时查表 + 外发通知。关键逻辑基于 password_last_changed 和 @@default_password_lifetime 计算剩余天数:
- 查出所有需关注的用户:
SELECT user, host, password_last_changed, password_lifetime FROM mysql.user WHERE password_last_changed IS NOT NULL AND (password_lifetime > 0 OR @@default_password_lifetime > 0) - 对每个用户,计算过期时间:
TIMESTAMPADD(DAY, IFNULL(password_lifetime, @@default_password_lifetime), password_last_changed) - 筛选 7 天内将过期的账号:
HAVING expires_at BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 7 DAY) - 用 Python/Shell 调用邮件、钉钉或企业微信 API 发送通知——注意:别用 root 账号发,建议专用只读账号
ALTER USER 设置后,password_last_changed 时间不准怎么办
这是告警误报/漏报最常见原因。以下操作不会更新 password_last_changed:
-
SET PASSWORD FOR 'u'@'h' = 'xxx'(已弃用,且不更新该字段) - 直接
UPDATE mysql.user(禁止,且无效) - 通过
mysqladmin password命令改密
只有以下方式能**同时改密+刷新时间戳**:
-
ALTER USER 'u'@'h' IDENTIFIED BY 'newpass'(推荐) -
ALTER USER 'u'@'h' IDENTIFIED BY 'newpass' PASSWORD EXPIRE INTERVAL 90 DAY(一步到位)
若已有用户时间戳为空或陈旧,先执行一次 ALTER USER 'u'@'h' IDENTIFIED BY 'same_old_hash_or_new_one' 强制刷新,否则告警永远算不准。
别忽略 host 匹配和权限边界
同一个用户名在不同 host 是独立账户,比如 'app'@'10.1.2.%' 和 'app'@'localhost' 必须分别检查。另外:
- 执行告警脚本的数据库账号只需
SELECT权限(限定在mysql.user表),**绝不给 SUPER 或 SYSTEM_VARIABLES_ADMIN** - 避免在主库高峰期执行全表扫描,可加
WHERE user NOT IN ('mysql.infoschema', 'mysql.session', 'mysql.sys')过滤系统用户 -
password_last_changed存储的是 UTC 时间,脚本中做时间计算时统一用UTC_TIMESTAMP(),别混用NOW()
真正的告警不是配置一个变量就能跑起来的——它依赖准确的时间戳、隔离的查询权限、以及脱离 MySQL 自身能力边界的外部协作。漏掉任意一环,都可能让“7 天提醒”变成“当天凌晨 ERROR 1820 爆炸”。


















