FAILED_LOGIN_ATTEMPTS 和 PASSWORD_LOCK_TIME 必须成对设置且仅对 caching_sha2_password 或 mysql_native_password 用户生效;PASSWORD_LOCK_TIME 单位为天,0 表示永久锁定,锁定期满需成功登录才重置;MySQL 5.7.6+ 初步支持,8.0.19+ 才稳定。

FAILED_LOGIN_ATTEMPTS 和 PASSWORD_LOCK_TIME 必须成对出现才生效
单独设置 FAILED_LOGIN_ATTEMPTS 或只写 PASSWORD_LOCK_TIME,MySQL 完全忽略——账户不会被锁,account_locked 字段始终为 N。必须同时指定两个参数,且仅在用户使用 caching_sha2_password 或 mysql_native_password 认证时起作用。
常见错误现象:ALTER USER 'u'@'%' FAILED_LOGIN_ATTEMPTS 3; 执行成功但无实际锁定效果;查 SELECT user, host, account_locked FROM mysql.user; 发现仍是 N。
- 新建用户时必须显式声明认证插件:
CREATE USER 'api'@'%' IDENTIFIED WITH caching_sha2_password BY 'pwd' FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 0.00694; - 已有用户需连插件一起改:
ALTER USER 'api'@'%' IDENTIFIED WITH caching_sha2_password BY 'newpwd' FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 0.00694; -
PASSWORD_LOCK_TIME单位是「天」,不是秒或分钟;锁 5 分钟要写0.00347(5 ÷ 1440),锁 10 分钟是0.00694
PASSWORD_LOCK_TIME 写 0 表示永久锁定,不是“不锁定”
很多人误以为 PASSWORD_LOCK_TIME 0 是关闭锁定,实际是「永久锁死」——账号无法自动恢复,只能由管理员手动执行 ALTER USER 'u'@'%' ACCOUNT UNLOCK; 解锁。生产环境慎用 0,尤其不能用于关键业务账号。
锁定期满后不会自动解锁:必须有一次**成功登录**才会重置失败计数并清除锁定状态。连续失败 3 次被锁 1 天,第 2 天首次尝试仍失败,计数继续累加,锁定时间从这次失败重新算起。
- 想实现「1 小时自动解锁」:设
PASSWORD_LOCK_TIME 0.04167(1 ÷ 24) - 临时测试可设
PASSWORD_LOCK_TIME 0.0001(约 1.4 分钟),避免反复手动解锁 - 查看当前锁定状态:
SELECT user, host, account_locked, password_locking_status FROM mysql.user WHERE user = 'u';
MySQL 5.7 和 8.0+ 的行为差异很关键
MySQL 5.7.6+ 支持该功能,但 5.7.17 前的版本不支持 FAILED_LOGIN_ATTEMPTS 语法;MySQL 8.0.19+ 才真正稳定支持自动重置与状态持久化。account_locked 字段在 5.7 中不可见,需靠 SELECT ... FROM mysql.user 查 password_last_changed 和错误日志间接判断。
Word报告自动生成神器。自动生成专业Word文档报告,支持模板填充、目录生成、表格/图表插入、页眉页脚、多级标题、样式主题、批量邮件合并。当用户需要生成Word报告、创建合同文档、批量生成通知/证书、填充Word模板、制作商业计划书时触发。
5.7 版本下即使写了参数,ALTER USER 可能报错或静默忽略;8.0.19+ 才会返回明确错误如 ERROR 3955 (HY000): Account is blocked。
- 先确认版本:
SELECT VERSION();,低于5.7.6别折腾这个参数 - 5.7 环境更推荐用
fail2ban + error.log配合max_connect_errors做 IP 层封锁 - 8.0.19+ 推荐直接用原生机制,但务必搭配
REQUIRE SSL和 IP 白名单,否则锁了账号也挡不住代理层暴力扫
锁定期单位换算容易出错,别手算
PASSWORD_LOCK_TIME 只接受浮点数表示的「天」,手算小时/分钟极易偏差。10 分钟是 10 / (24 * 60) = 0.006944...,保留 5 位小数足够;写 0.0069 或 0.007 都会导致实际锁定时间偏差 1–2 分钟。
建议用表达式代替硬编码:PASSWORD_LOCK_TIME 10/1440(MySQL 8.0.19+ 支持简单算术),既准确又易读。但注意:该写法在 CREATE USER 中不被允许,只能用于 ALTER USER。
- 锁 5 分钟:
ALTER USER 'u'@'%' ... PASSWORD_LOCK_TIME 5/1440; - 锁 30 分钟:
PASSWORD_LOCK_TIME 30/1440; - 不要写
PASSWORD_LOCK_TIME 0.5期望锁半天——它真就锁 12 小时,不是你想要的「半小时」
真正起作用的从来不是「设多大数字」,而是确保失败计数能准确归属到具体账号、锁定状态不被绕过、以及锁住之后攻击者没法换 IP 或代理继续试。原生参数只是其中一环,漏掉认证插件切换或没关 mysql_native_password,等于门开着还挂了把装饰锁。


















