MySQL 8.0 的 PASSWORD_LOCK_TIME 仅支持整数天(如1=24小时,0=永久锁定),不支持分钟级设置,因其内部解析为整数天类型,0.5或30等非整数值会直接报错ERROR 3671。

MySQL 8.0 原生不支持“失败锁定后自动按分钟/小时解锁”,PASSWORD_LOCK_TIME 只接受整数天(如 1 = 24 小时,0 = 永久锁定),设 0.5 或 30 会直接报错 ERROR 3671 (HY000): Invalid value for PASSWORD_LOCK_TIME。
为什么 PASSWORD_LOCK_TIME 不能设 30 分钟
MySQL 内部将 PASSWORD_LOCK_TIME 解析为天数,且强制要求是整数。它不是浮点字段,也不做单位换算。哪怕你写 PASSWORD_LOCK_TIME 0.02083(30/1440),MySQL 启动或解析语句时就会拒绝,返回明确错误。这不是配置遗漏或权限问题,是类型硬限制。
-
PASSWORD_LOCK_TIME 1→ 锁定 24 小时 -
PASSWORD_LOCK_TIME 0→ 永久锁定,必须由管理员执行ALTER USER ... ACCOUNT UNLOCK才能恢复 -
PASSWORD_LOCK_TIME 0.5或30→ 立即报错,语句执行失败
查 account_locked 状态才能确认是否真锁了
输错密码和账号被锁都返回 ERROR 1045 (28000),客户端无法区分。唯一可靠方式是查系统表:
SELECT user, host, account_locked, failed_login_attempts FROM mysql.user WHERE user = 'u';
若 account_locked = 'Y',说明已触发真锁定;若 failed_login_attempts > 0 但 account_locked = 'N',说明还在计数中,未达阈值。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 锁定解除条件不是“时间到了就开”,而是必须有一次成功登录才会重置计数、清除
account_locked = 'Y' - 该机制只对使用
caching_sha2_password或mysql_native_password插件的用户生效;sha256_password或auth_socket用户完全不响应 -
FAILED_LOGIN_ATTEMPTS和PASSWORD_LOCK_TIME必须同时出现在同一条CREATE USER或ALTER USER语句中,缺一不可
想实现 30 分钟级控制,只能绕开原生机制
MySQL 不提供分钟级自动解锁能力,真实可行路径只有两个:
-
应用层兜底:在业务代码里维护失败记录(例如用 Redis 存
fail_count:u@h+last_fail_time:u@h),登录前检查时间差是否超 30 分钟,超则重置计数 -
IP 级延迟(非锁定):用
connection_control插件,设connection_control_min_connection_delay = 1800000(30 分钟毫秒值),但注意这只是让第 N+1 次失败响应变慢,仍返回ERROR 1045,且不修改account_locked字段
这两个方案都不依赖 PASSWORD_LOCK_TIME,也都不受其整数天限制影响,但代价是:前者增加业务逻辑复杂度,后者无法真正拦截连接请求。
最易被忽略的一点:即使你设了 PASSWORD_LOCK_TIME 1,如果用户认证插件不是 caching_sha2_password 或 mysql_native_password,或者 validate_password 插件没启用,account_locked 永远是 'N'——配置看起来全对,实际完全不生效。










