MySQL批量创建账号应使用脚本生成SQL,参数化账号名、密码、库名、主机,按业务收敛权限,显式指定认证插件,避免ON .授权,执行前校验并低峰期操作。

MySQL批量创建账号的正确姿势是用脚本生成SQL,而不是手敲
手动执行 CREATE USER 和 GRANT 命令在10个库以上就极易出错:漏授权、密码写错、主机名拼错(比如把 '%' 写成 '*')、权限粒度不一致。真正可行的方式是先构造好所有语句,再统一执行。
关键点在于:账号名、密码、数据库名、允许访问的主机这四个字段必须参数化;权限范围要按业务收敛(比如只给 SELECT,INSERT,UPDATE,不给 DROP);密码必须用 PASSWORD() 函数或原生字符串(MySQL 8.0+ 推荐用 IDENTIFIED WITH caching_sha2_password BY 'xxx')。
- 准备一个 CSV 或 Excel 表格,列名为:
username,password,dbname,host - 用 Python / awk / Excel 公式批量生成 SQL 语句,例如:
CREATE USER 'app_user_01'@'10.20.%' IDENTIFIED BY 'pwd123';<br>GRANT SELECT,INSERT,UPDATE ON `myapp_v1`.* TO 'app_user_01'@'10.20.%';<br>FLUSH PRIVILEGES;
- 检查生成的 SQL 中是否含单引号嵌套、特殊字符(如
\、换行符),避免导入失败
MySQL 5.7 和 8.0 的密码认证插件差异必须处理
MySQL 8.0 默认使用 caching_sha2_password 插件,而很多老应用连接器(如旧版 JDBC、PHP mysqli)不支持,直接报错 Authentication plugin 'caching_sha2_password' cannot be loaded。如果批量建号面向混合环境,得统一指定插件。
- MySQL 5.7 可用:
CREATE USER 'u'@'h' IDENTIFIED BY 'p'; - MySQL 8.0 兼容旧客户端:加
IDENTIFIED WITH mysql_native_password BY 'p' - 若强制用新插件,需确认客户端版本(JDBC 8.0.14+、Connector/Python 8.0.19+)
- 建号脚本里建议显式声明插件,避免依赖全局 default_authentication_plugin
批量授权时别用 ON *.*,按库前缀动态生成权限语句
业务数据库往往按环境或租户分库,比如 shop_prod_v2、shop_staging_v2、shop_test_v2。如果统一授 ON shop_%.*,可能越权访问非目标库;如果每个库单独写 GRANT,又难维护。
- 推荐在生成脚本时用正则匹配库名前缀,例如:对所有以
shop_开头的库执行授权 - 避免
GRANT ... ON *.*—— 这会赋予跨库权限,且无法被REVOKE精确收回 - 生产环境禁止授予
USAGE以外的全局权限(如PROCESS,SUPER) - 执行完记得跑一次
SELECT user,host,authentication_string,plugin FROM mysql.user;核对插件和密码哈希是否符合预期
执行批量SQL前必须做权限校验和事务模拟
MySQL 的 DDL 语句(如 CREATE USER)不能回滚,一旦某条失败,后续语句不会自动终止。直接 source batch.sql 风险极高。
- 先用
--print模式(如用mysql -e "source batch.sql"改为mysql -e "source batch.sql" --verbose)看实际执行流 - 拆成两步:先
SELECT CONCAT('SHOW GRANTS FOR ', QUOTE(user), '@', QUOTE(host), ';') FROM mysql.user WHERE user LIKE 'app_%';查现有账号,防重复建号 - 用非 root 账号试跑部分语句(如只建1个用户+授1个库),验证连接、权限、插件兼容性
- 线上操作务必在低峰期,并提前备份
mysql.user表(mysqldump --single-transaction mysql user > user_bak.sql)
实际最难的不是写脚本,是厘清每个账号该访问哪些库、从哪些网段来、用什么加密方式——这些规则一旦模糊,批量操作只会把问题放大。


















