CREATE USER 语句必须指定 IDENTIFIED BY 吗?
MySQL 8.0+ 默认启用
validate_password插件,且不允许空密码。不加
IDENTIFIED BY会报错
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements或直接拒绝创建。即使绕过策略,也极不安全——生产环境绝不能用空密码或弱密码。
实操建议:
始终显式指定强密码:CREATE USER 'app_user'@'192.168.1.%' IDENTIFIED BY 'P@ssw0rd_2024';若需临时禁用密码策略(仅限测试库),先执行:
SET GLOBAL validate_password.policy = LOW;,但之后必须重置回
MEDIUM或
STRONG
'app_user'@'localhost'和
'app_user'@'%'是两个完全独立的用户,授权需分别处理
GRANT 之后为什么 FLUSH PRIVILEGES 不一定需要?
GRANT语句本身会自动重载权限表,绝大多数情况下无需手动
FLUSH PRIVILEGES。只有在**直接修改 mysql.user / mysql.db 等系统表**后才必须执行该命令——否则新权限不生效。
常见错误场景:
误以为GRANT没生效就反复执行
FLUSH PRIVILEGES,其实只是掩盖了其他问题(比如 host 匹配失败) 用
INSERT INTO mysql.user手动加用户却忘了
FLUSH,导致登录失败 MySQL 8.0+ 的角色(ROLE)授权后,
FLUSH仍无效,必须用
SET DEFAULT ROLE激活
验证权限是否已加载:用新用户连接后执行
SHOW GRANTS;,结果应与预期一致。
授予 SELECT 权限时,database.table 和 *.* 的区别在哪?
权限粒度直接影响安全边界和后续维护成本。例如:
GRANT SELECT ON myapp.* TO 'report_user'@'%';—— 允许查
myapp库下所有表,但无法查
information_schema或其他库
GRANT SELECT ON *.* TO 'dba_backup'@'10.0.5.%';—— 允许查所有库所有表(除系统视图外),风险极高,通常应配合
WITH GRANT OPTION严格限制使用范围
GRANT SELECT (id, name) ON myapp.users TO 'api_user'@'%';—— 列级权限,只暴露必要字段,MySQL 8.0+ 支持,但不支持函数索引列等特殊情况
注意:
GRANT SELECT ON myapp.users(不带星号)是合法语法,但只授给单表;而
GRANT SELECT ON myapp.后面漏掉
*会导致语法错误。
撤销权限后用户还能登录吗?
能。权限(privileges)和认证(authentication)是分离的。
DROP USER或
REVOKE ALL PRIVILEGES只影响操作能力,不影响登录资格。
典型表现:
执行REVOKE ALL ON *.* FROM 'old_dev'@'%';后,该用户仍可成功登录,但执行任何 SQL 都报
ERROR 1044 (42000): Access denied for user...真正禁止登录要用
DROP USER 'old_dev'@'%';,或设为空密码+禁用账户(MySQL 8.0+ 支持
ACCOUNT LOCK) 如果用户有
USAGE权限(默认新建用户就有),它只代表“能连上”,不赋予任何操作权,此时
SHOW GRANTS显示的就是
GRANT USAGE ON *.* TO ...
最容易被忽略的是:应用配置里残留的旧账号未清理,即使已撤权,仍可能因连接池复用导致偶发超时或日志刷屏——删用户比撤权更彻底,也更易审计。
