直接改 mysql.user 表风险极高,MySQL 5.7+ 中 user 表为视图,裸 UPDATE 会破坏元数据一致性、触发字段校验错误(如 ssl_cipher 缺失默认值),导致登录失败或权限失效;正确做法是用 ALTER USER 安全修改主机、密码及认证插件,并显式刷新权限与验证连接。

直接改 mysql.user 表风险极高,不建议用 UPDATE
MySQL 5.7+ 默认启用 sql_mode=STRICT_TRANS_TABLES,且 user 表是系统表,结构受内部校验约束。直接 UPDATE mysql.user SET host='%' WHERE user='app_user' 极可能触发错误:ERROR 1364 (HY000): Field 'ssl_cipher' doesn't have a default value 或导致用户无法登录、权限失效。这不是语法问题,而是 MySQL 服务端在写入时会校验字段完整性(如 authentication_string、password_expired、account_locked 等),裸 UPDATE 会跳过这些逻辑。
正确做法:用 ALTER USER 修改主机限制
MySQL 5.7.6+ 提供了安全可控的 DDL 方式,自动处理底层字段兼容性与密码哈希同步。关键点在于:必须显式指定原用户名和原主机(即当前完整账号),再用 IDENTIFIED WITH ... BY(如需重设密码)或仅改 REQUIRE/WITH 子句。
- 把本地用户
'dev'@'localhost'改成允许任意主机连接:ALTER USER 'dev'@'localhost' IDENTIFIED WITH mysql_native_password BY 'newpass' REQUIRE NONE;
- 若只需改主机、不改密码,先查出当前认证插件和密码哈希:
SELECT plugin, authentication_string FROM mysql.user WHERE user='dev' AND host='localhost';
再复用:ALTER USER 'dev'@'localhost' IDENTIFIED WITH mysql_native_password AS '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9';
- 批量操作需写脚本生成语句(不能直接多值
ALTER USER):
例如导出所有@'192.168.%'用户改为@'%':SELECT CONCAT("ALTER USER '", user, "'@'", host, "' IDENTIFIED WITH ", plugin, " AS '", authentication_string, "';") FROM mysql.user WHERE host LIKE '192.168.%';执行结果后手动校验并运行
MySQL 5.6 或低版本只能用 GRANT + FLUSH PRIVILEGES
旧版本不支持 ALTER USER,但也不能直接 UPDATE user。必须走授权路径:先创建新主机账号,再删旧账号。因为 GRANT 会自动填充缺失字段(如 ssl_type、x509_issuer),而 DROP USER 才真正清理记录。
- 例如迁移
'api'@'10.0.1.5'到'api'@'%':GRANT SELECT,INSERT ON mydb.* TO 'api'@'%' IDENTIFIED BY 'pwd123';<br>FLUSH PRIVILEGES;<br>DROP USER 'api'@'10.0.1.5';
- 注意
GRANT不会复制原账号的全局权限(如PROCESS、RELOAD),需单独查mysql.user补全:SELECT column_name FROM information_schema.COLUMNS WHERE table_name='user' AND column_name LIKE '%priv%';
然后手工拼GRANT ... ON *.*语句 -
FLUSH PRIVILEGES必须执行,否则内存缓存未更新,新账号仍不可用
改完必须验证连接和权限,别信“执行成功”
即使语句没报错,也常出现:新主机能连上但无库权限、密码实际失效、SSL 要求被忽略。最简验证方式是开一个新终端,用目标账号直连:
- 测试连接:
mysql -u app_user -p -h 192.168.10.20
- 进库后立刻查权限是否继承:
SHOW GRANTS FOR CURRENT_USER();
- 特别注意
max_connections、max_questions这类资源限制默认不继承,需在ALTER USER中显式指定:ALTER USER 'app_user'@'%' WITH MAX_CONNECTIONS_PER_HOUR 100;
跨大版本升级(如 5.7 → 8.0)后,plugin 字段值可能从 mysql_native_password 变为 caching_sha2_password,此时光改 host 不够,客户端驱动不兼容会导致“Access denied”。得同步调整插件和密码哈希格式。











