MySQL 8.0中default_password_lifetime仅影响新用户,不作用于已有用户;必须用ALTER USER 'user'@'host' PASSWORD EXPIRE INTERVAL N DAY显式设置单个用户过期策略,修改后查mysql.user表确认password_lifetime为数值而非NULL才生效。

MySQL 8.0 中不能对单个用户“单独设置密码生命周期”——必须显式执行 ALTER USER ... PASSWORD EXPIRE INTERVAL,全局变量 default_password_lifetime 只影响新用户或未显式设置的用户。
为什么 default_password_lifetime 不作用于已有用户
该变量仅作为新建用户的默认值。一旦用户已存在,其 password_lifetime 字段在 mysql.user 表中就固化为 NULL(继承全局)或具体数值(显式设置过),后续全局修改不会自动同步。
- 执行
SET GLOBAL default_password_lifetime = 90后,SELECT user, host, password_lifetime FROM mysql.user里老账号的password_lifetime仍是NULL或旧值 - 只有新
CREATE USER且未带PASSWORD EXPIRE子句时,才取该全局值 - 等保测评时若只改了全局值,但没批量修正存量账号,会直接判定“部分账户未启用密码过期”,不合规
如何为指定用户设置独立的过期天数
必须用 ALTER USER 显式覆盖。语法严格,缺一不可:
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
-
ALTER USER 'app_user'@'%' PASSWORD EXPIRE INTERVAL 90 DAY;—— 设置 90 天后强制更换 -
ALTER USER 'backup_admin'@'localhost' PASSWORD EXPIRE NEVER;—— 永不过期(慎用,需强审计支撑) - 不能写成
PASSWORD EXPIRE AFTER 90或漏掉DAY,否则报错ERROR 1064 - 修改后立即生效,下次登录即校验
password_last_changed + password_lifetime
验证是否真正生效
别只看命令有没有报错,要查系统表和实际行为:
- 确认字段值:
SELECT user, host, password_last_changed, password_lifetime FROM mysql.user WHERE user = 'app_user';——password_lifetime必须是数字(如90),不是NULL或0 - 触发过期测试:手动更新时间戳
UPDATE mysql.user SET password_last_changed = DATE_SUB(NOW(), INTERVAL 91 DAY) WHERE user = 'app_user'; FLUSH PRIVILEGES;,再登录就会遇到ERROR 1820 (HY000) - 注意:
password_expired = 'Y'是结果状态,不是配置项;它由服务器根据当前时间和password_last_changed/password_lifetime自动计算得出
容易被忽略的兼容性细节
密码过期策略依赖认证插件与密码历史机制协同工作:
- 用户必须使用
caching_sha2_password或mysql_native_password插件,sha256_password不支持过期逻辑 - 如果同时启用了
validate_password插件且设为STRONG,密码重置时还受password_history和password_reuse_interval约束,旧密码不能直接复用 - 客户端连接后首次执行任何语句(如
SELECT 1)才会触发过期检查,单纯mysql -u -p成功不代表通过了密码策略校验










