专用只读备份用户可避免误操作删库或数据泄露,其最小权限为SELECT+LOCK TABLES+SHOW VIEW+TRIGGER(8.0+需TRIGGER),须限定host、禁用%、强制SSL,并显式撤销information_schema等敏感库访问权。

为什么要用专用只读用户做备份
直接用 root 或高权限账号执行 mysqldump 存在明显风险:一旦备份脚本出错、被注入或误操作,可能意外修改数据甚至删库。专用只读用户把权限收缩到最小必要范围——仅允许读取所有数据库的表结构和数据,不带任何写、管理、执行权限,是生产环境备份的事实标准做法。
创建只读用户的正确 SQL 语句
MySQL 8.0+ 和 5.7 的语法有关键差异,不能混用:
MySQL 8.0+(推荐):
CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'strong_password';<br>GRANT SELECT, LOCK TABLES, SHOW VIEW, TRIGGER ON <em>.</em> TO 'backup_user'@'localhost';<br>FLUSH PRIVILEGES;
MySQL 5.7 及更早:
CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'strong_password';<br>GRANT SELECT, LOCK TABLES, SHOW VIEW ON <em>.</em> TO 'backup_user'@'localhost';<br>-- 注意:5.7 不需要显式授予 TRIGGER,但若备份含触发器且用 --triggers 参数,需额外确认是否报错<br>FLUSH PRIVILEGES;
MySQL 8.0+(推荐):
CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'strong_password';<br>GRANT SELECT, LOCK TABLES, SHOW VIEW, TRIGGER ON <em>.</em> TO 'backup_user'@'localhost';<br>FLUSH PRIVILEGES;
MySQL 5.7 及更早:
CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'strong_password';<br>GRANT SELECT, LOCK TABLES, SHOW VIEW ON <em>.</em> TO 'backup_user'@'localhost';<br>-- 注意:5.7 不需要显式授予 TRIGGER,但若备份含触发器且用 --triggers 参数,需额外确认是否报错<br>FLUSH PRIVILEGES;
容易踩的坑:
- 忘记
LOCK TABLES:导致mysqldump --single-transaction在非事务引擎(如 MyISAM)下失败,或一致性出问题 - 漏掉
SHOW VIEW:备份视图时会报错Access denied; you need (at least one of) the SHOW VIEW privilege(s) - 用户 host 写成
'%':虽方便但扩大攻击面,建议限定为备份发起机 IP 或'localhost'(配合mysqldump -h localhost使用 socket 连接)
验证权限是否生效
别依赖“执行了 GRANT 就完事”,必须实测:
- 登录该用户:
mysql -u backup_user -p
- 执行最小验证命令:
SHOW DATABASES;<br>USE mysql;<br>SELECT COUNT(*) FROM user LIMIT 1;
- 尝试越权操作,应明确拒绝:
CREATE TABLE test_t (id INT); -- 应报 ERROR 1142 (42000): CREATE command denied
mysql -u backup_user -p
SHOW DATABASES;<br>USE mysql;<br>SELECT COUNT(*) FROM user LIMIT 1;
CREATE TABLE test_t (id INT); -- 应报 ERROR 1142 (42000): CREATE command denied
注意:如果启用了 sql_require_primary_key,而某些旧表无主键,SELECT 本身仍可执行,但 mysqldump 默认会加 --skip-lock-tables 或失败,此时需在备份命令中显式加 --skip-lock-tables(仅当确认无并发写入风险时)。
备份命令中如何安全调用该用户
不要在命令行明文写密码(会留痕在 ps aux 和 shell history):
推荐方式:使用 MySQL 配置文件 ~/.my.cnf(权限必须设为 600):
[client]<br>user=backup_user<br>password=strong_password<br>host=localhost
然后执行:mysqldump --all-databases --single-transaction --routines --events > backup.sql
若必须命令行传参,用 -p 交互输入(不跟等号):mysqldump -u backup_user -p --all-databases > backup.sql
推荐方式:使用 MySQL 配置文件 ~/.my.cnf(权限必须设为 600):
[client]<br>user=backup_user<br>password=strong_password<br>host=localhost
然后执行:mysqldump --all-databases --single-transaction --routines --events > backup.sql
若必须命令行传参,用 -p 交互输入(不跟等号):mysqldump -u backup_user -p --all-databases > backup.sql
关键细节:--single-transaction 依赖 InnoDB MVCC,对 MyISAM 表无效,此时仍靠 LOCK TABLES;而该权限已由用户具备,所以不必关掉这个选项——除非你确定全库都是 MyISAM,那就要换 --lock-all-tables 并确保用户有对应权限(其实已有 LOCK TABLES ON <em>.</em>,所以也 OK)。
备份用户看似简单,但权限粒度、版本差异、连接方式、密码管理这四点,任意一个疏忽都可能导致某次备份静默失败,等到恢复时才发现不可用。


















