mysql不支持单条create user创建多个用户,必须逐条执行;grant同理,且需先建用户再授权;密码含特殊字符时应避免命令行直接传参,推荐使用here-doc或stdin方式执行sql。

怎么用 SQL 脚本一次性建多个 MySQL 用户
直接执行 CREATE USER 语句即可,但要注意:MySQL 不支持一条语句创建多个用户(比如 CREATE USER 'a'@'%' , 'b'@'%' 是语法错误)。必须逐条写,或用脚本循环生成。
常见错误是把多个用户名写在同一个 CREATE USER 后面,结果报错 ERROR 1064 (42000) —— 这不是权限问题,是语法不合法。
- 每个用户必须单独一行
CREATE USER,例如:CREATE USER 'app1'@'10.20.%' IDENTIFIED BY 'pwd1';<br>CREATE USER 'app2'@'10.20.%' IDENTIFIED BY 'pwd2';
- 如果用户名/密码来自配置表或 CSV,建议用 shell 或 Python 生成 SQL 文件,而不是手写几十条
- MySQL 8.0+ 默认要求强密码策略,若脚本执行失败,先检查
validate_password.length和validate_password.policy是否拦住了简单密码
批量授权时 GRANT 语句能不能合并写
不能。和 CREATE USER 一样,GRANT 也不支持逗号分隔多个用户,比如 GRANT SELECT ON db.* TO 'u1'@'%', 'u2'@'%' 会报错。
更关键的是:MySQL 的 GRANT 语句中,TO 后面只能跟一个用户(或用户列表加引号的旧写法,已弃用),且该用户必须已存在 —— 所以必须先确保 CREATE USER 成功,再逐条 GRANT。
- 推荐把建用户和授权拆成两个步骤:先统一建用户,再统一授权,避免某条失败导致权限不一致
- 授权时注意主机名匹配,
'user'@'localhost'和'user'@'127.0.0.1'是两个不同用户,不能混用 - 如果用
GRANT ... WITH GRANT OPTION,记得后续要FLUSH PRIVILEGES(仅在直接操作mysql.user表时才强制需要;正常用GRANT则自动刷新)
脚本里怎么安全处理密码和特殊字符
MySQL 命令行客户端(mysql -e)传参时,密码如果含空格、单引号、反斜杠等,容易被 shell 解析错,进而导致用户创建失败或密码不符。
最稳的方式不是拼接字符串,而是用 mysql 的 --defaults-file 配置文件方式登录,或者改用 mysql --execute + stdin 输入 SQL(避开命令行参数解析)。
- 避免这种写法:
mysql -uroot -p"m'y&pwd" -e "CREATE USER 'x'@'%' IDENTIFIED BY 'm'y&pwd'"—— 单引号嵌套直接崩 - 推荐用 here-doc 或管道:
mysql -uroot -p"$ROOT_PWD" <<'EOF'<br>CREATE USER 'svc_a'@'10.20.%' IDENTIFIED BY 'A1#b2$c3';<br>GRANT SELECT,INSERT ON appdb.* TO 'svc_a'@'10.20.%';<br>EOF
- 密码里含
$、`、\时,务必用单引号包裹整个 heredoc 标记(如),否则 shell 会提前变量替换
MySQL 5.7 和 8.0 在批量建用户时的关键差异
主要是默认认证插件和密码加密方式变了。MySQL 8.0 默认用 caching_sha2_password,而很多老应用只认 mysql_native_password,如果脚本没显式指定,连上去就报 ERROR 2059 (HY000): Authentication plugin 'caching_sha2_password' cannot be loaded。
- MySQL 8.0 建用户时,务必加
IDENTIFIED WITH mysql_native_password BY 'xxx',除非确认客户端支持新插件 - MySQL 5.7 没这个限制,但要注意
old_passwords=1已废弃,别在配置里设它 - 脚本若需兼容两个版本,可以用条件判断:
SELECT VERSION()结果来分支,或统一用ALTER USER ... IDENTIFIED WITH ...补救
脚本跑通不难,难的是所有用户都用对了主机名、认证插件、密码策略,而且没有漏掉 FLUSH PRIVILEGES(虽然多数情况不用,但跨版本迁移时,宁可多写一句)。










