MySQL中真能自动锁定账户的唯一方式是FAILED_LOGIN_ATTEMPTS与PASSWORD_LOCK_TIME组合,且用户必须使用caching_sha2_password或mysql_native_password插件、MySQL≥5.7.17(推荐8.0.19+),PASSWORD_LOCK_TIME单位为整数天(如1=24小时,0=永久锁定),不支持分钟级设置;connection_control仅加延迟,不修改account_locked字段。

MySQL 里真能“自动锁定账户”的,只有 FAILED_LOGIN_ATTEMPTS + PASSWORD_LOCK_TIME 这一套组合,且必须满足硬性条件:用户认证插件得是 caching_sha2_password 或 mysql_native_password,MySQL 版本 ≥ 5.7.17(推荐 8.0.19+)。其他所谓“锁定”,比如靠 connection_control 插件,只是加延迟,不改 account_locked 字段,客户端连错误类型都分不清。
FAILED_LOGIN_ATTEMPTS 必须和认证插件绑定才生效
这个参数不是全局开关,它只对单个用户生效,而且只在创建或修改用户时显式指定才起作用。常见错误是以为配置了全局变量就能锁所有账号——没这回事。
-
CREATE USER 'appuser'@'%' IDENTIFIED WITH caching_sha2_password BY 'p' FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 1;—— 这才是正确写法;sha256_password用户设了也无效 - 已有用户要改用:
ALTER USER 'appuser'@'%' IDENTIFIED WITH caching_sha2_password BY 'p' FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 1; -
PASSWORD_LOCK_TIME单位是**天**,只能填整数:设1是锁 24 小时,0是永久锁定(不会自动恢复),填0.5或30直接报错ERROR 3671 (HY000) - 失败计数按
user@host组合独立维护,'u'@'192.168.1.10'和'u'@'192.168.1.11'完全无关
怎么确认账号是不是真被锁了?别信错误提示
输错密码和账号被锁,MySQL 都返回 ERROR 1045 (28000): Access denied for user,根本没法从客户端区分。唯一可靠方式是查系统表:
SELECT user, host, account_locked, failed_login_attempts FROM mysql.user WHERE user = 'appuser';
如果 account_locked = 'Y',说明已触发真锁定;如果 failed_login_attempts > 0 但 account_locked = 'N',说明还在累积失败次数,未达阈值。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 解锁必须由管理员执行:
ALTER USER 'appuser'@'%' ACCOUNT UNLOCK; -
ALTER USER ... ACCOUNT LOCK;是手动锁,和失败触发的自动锁机制无关 - 自动锁定后,**不会**因为时间到了就自动解锁——必须有一次成功登录,才会重置计数并清除
account_locked = 'Y'
connection_control 插件只能加延迟,不是锁定
它只让第 N 次失败后的响应变慢,不拦截连接、不改状态字段、不封 IP。很多配置看似写了,其实没效果,原因很具体:
- 必须同时加载两个插件:
INSTALL PLUGIN connection_control SONAME 'connection_control.so';和INSTALL PLUGIN connection_control_failed_login_attempts SONAME 'connection_control.so';,漏一个就静默失效 -
connection_control_failed_connections_threshold = 3表示“从第 4 次失败开始计延迟”,但如果connection_control_min_connection_delay = 0(默认值),延迟就是 0 毫秒 → 完全无感 - 延迟单位是毫秒:
1800000是 30 分钟,但这个值必须写进my.cnf的[mysqld]段并重启 mysqld,SET GLOBAL不生效 - 查是否真起作用:
SHOW STATUS LIKE 'Connection_control_delayed_connections';返回非零值才算生效
真正难的不是写那两行 ALTER USER,而是确保用户用了正确的认证插件、没混用旧插件、并且理解 PASSWORD_LOCK_TIME 的整数天限制和自动解锁依赖成功登录这一事实。MySQL 原生机制里,没有“锁 30 分钟”或“按 IP 封禁”的选项,这些得靠 fail2ban 解析错误日志,或应用层自己记失败次数。










