mysql 8.0+ 中让某用户密码永不过期的唯一可靠方式是执行 alter user 'user'@'host' password expire never;该操作立即生效,不继承全局 default_password_lifetime,且必须精确匹配 user@host,不可用 default 或空值替代。

MySQL 8.0+ 怎么让某个用户密码永不过期
用 ALTER USER 'user'@'host' PASSWORD EXPIRE NEVER 显式关闭过期,这是唯一可靠方式。注意:PASSWORD EXPIRE DEFAULT 不是“永不过期”,它会继承全局 default_password_lifetime 值;PASSWORD EXPIRE(不带参数)则是立即过期,千万别混用。
常见错误现象:执行 ALTER USER 'app'@'10.%.%.%' PASSWORD EXPIRE DEFAULT 后发现密码还是 90 天过期——因为全局 default_password_lifetime = 90 生效了。
- 必须精确匹配
user@host,'app'@'10.0.0.%'和'app'@'%'是两个账号 - 执行后立刻生效,无需重启 MySQL
-
PASSWORD EXPIRE NEVER是字符串字面量,不能写成NULL、空字符串或数字 0
为什么 SET GLOBAL default_password_lifetime = 0 不管用
设 default_password_lifetime = 0 只影响新创建的用户,且前提是建用户时没显式指定过期策略。已有用户(尤其是 root、监控账号、应用连接池账号)完全不受影响,仍按自己原来的 password_lifetime 或上次 ALTER USER 设置生效。
典型踩坑场景:线上巡检发现 30 个业务账号里有 5 个已过期,排查发现 DBA 只改了全局变量,却漏掉了 ALTER USER 批量修正。
- 查当前全局值:
SELECT @@global.default_password_lifetime; - 永久生效推荐用
SET PERSIST default_password_lifetime = 0;(写入mysqld-auto.cnf) - 临时生效可用
SET GLOBAL default_password_lifetime = 0;,但重启即丢失
MySQL 5.7 能不能设永不过期
5.7.11+ 支持 PASSWORD EXPIRE NEVER,但仅限于 ALTER USER 语法;5.7.0–5.7.10 不识别该关键字,执行会报错 ERROR 1064 (42000)。低于 5.7 的版本压根不支持任何原生过期控制,强行更新 mysql.user 表属于高危操作,极易破坏密码哈希校验逻辑。
验证版本最准的方式不是看文档,而是直接跑:SELECT VERSION(); —— 如果返回 5.7.10 或更低,就别碰 PASSWORD EXPIRE 相关语句。
- 5.7.11+:支持
ALTER USER ... PASSWORD EXPIRE NEVER - 5.7.0–5.7.10:语法报错,只能靠人工定期巡检 + 外部脚本提醒
- MySQL 8.0.12+:最稳定,修复了早期 8.0.x 的过期状态判断 bug
密码永不过期后,应用连接池还可能出问题吗
会。即使密码永不过期,如果应用连接复用旧连接、而该连接在服务端已被 kill(比如因空闲超时),重连时若未正确处理认证响应,仍可能卡在握手阶段。更隐蔽的问题是:某些旧版 JDBC 驱动(如 mysql-connector-java 5.1.x)不识别 PASSWORD EXPIRE 状态字段,连接成功后执行第一条语句就抛 ERROR 1820。
- 建议在连接池初始化 SQL 中加一句
SELECT 1,提前触发校验 - 升级驱动到 8.0.28+ 或对应版本,确保支持过期密码协商流程
- 别依赖“永不过期”就跳过密码轮换审计——等保三级明确要求关键账号仍需定期更换,只是策略可放宽
ALTER USER ... PASSWORD EXPIRE NEVER 执行成功、应用层客户端能正常建连。少一个环节,都可能在凌晨三点收到告警。











