mysql中alter user password expire never必须精确匹配(user,host)二元组,host错误会报error 1396;set global default_password_lifetime=0仅影响新用户且重启失效,需同步修改配置文件并重启服务;8.0+禁止用set password或update mysql.user修改过期状态,唯一安全方式是alter user 'u'@'h' identified by 'xxx' password expire never;验证是否生效须查select user,host,password_expired from mysql.user,而非仅看全局变量。

ALTER USER PASSWORD EXPIRE NEVER 必须带 host 匹配
MySQL 用户是 (user, host) 二元组,'root'@'localhost' 和 'root'@'%' 是两个完全不同的账户。执行 ALTER USER 时若 host 写错,会直接报 ERROR 1396 (HY000): Operation ALTER USER failed,而不是密码相关错误。
先查准真实 host:
SELECT user, host FROM mysql.user WHERE user = 'root';- Windows 下常见的是
'root'@'127.0.0.1'或'root'@'::1',不是'localhost' - 如果不确定,可临时用通配符(仅限测试环境):
ALTER USER 'root'@'%' PASSWORD EXPIRE NEVER;
SET GLOBAL default_password_lifetime = 0 不等于永久生效
动态设置 SET GLOBAL default_password_lifetime = 0 只影响新创建的用户,且重启 MySQL 后失效——除非你同时写入配置文件。
必须同步修改 /etc/my.cnf(Linux)或 C:\ProgramData\MySQL\MySQL Server X.X\my.ini(Windows):
[mysqld] default_password_lifetime = 0
改完要重启服务:sudo systemctl restart mysql 或 net stop MySQL && net start MySQL。
注意:该参数对已存在的用户无影响,已有用户的过期状态仍需单独处理。
MySQL 8.0+ 不要碰 SET PASSWORD 或 UPDATE user 表
SET PASSWORD 在密码过期状态下不重置 password_expired 标志位,执行后看似成功,但下次登录仍报 ERROR 1820。
直接 UPDATE mysql.user 更危险:
- MySQL 8.0+ 已废弃
PASSWORD()函数,authentication_string字段必须用插件方式生成哈希 - 手动更新系统表可能破坏账户一致性,导致无法登录
-
FLUSH PRIVILEGES在 8.0+ 中对ALTER USER无效,但对UPDATE行为反而可能引发权限缓存混乱
唯一安全路径:用 ALTER USER 'u'@'h' IDENTIFIED BY 'xxx' PASSWORD EXPIRE NEVER; 一条命令完成密码更新 + 过期关闭。
检查是否真关掉了,别只信 SHOW VARIABLES
SHOW GLOBAL VARIABLES LIKE 'default_password_lifetime'; 返回 0,只说明全局策略关闭了,不代表用户已解除过期状态。
必须查用户实际状态:
SELECT user, host, password_expired FROM mysql.user WHERE user = 'root';
返回 'Y' 就代表仍过期;'N' 才算真正生效。如果仍是 'Y',说明你漏掉了 PASSWORD EXPIRE NEVER,只改了密码没关过期标记。
生产环境建议设为非零值(如 90),而非彻底禁用——完全关闭会掩盖长期未轮换密码的风险。











