只读数据库能用 mysqldump
吗?可以,但得绕过权限检查
MySQL 的只读模式(
read_only=ON)本身不阻止
mysqldump,真正卡住的是用户权限。常见错误是:明明有
SELECT权限,却报
Access denied for SELECT command denied to user—— 实际上是因为
mysqldump默认会尝试执行
FLUSH TABLES WITH READ LOCK,而该操作需要
RELOAD权限,只读库用户往往没这个权限。
解决方法是跳过锁表:
加--single-transaction(对 InnoDB 表有效,靠 MVCC 保证一致性,无需全局锁) 或加
--skip-lock-tables(适用于 MyISAM 或混合引擎,但备份期间可能有数据不一致风险) 确保用户至少有
SELECT、
SHOW VIEW、
LOCK TABLES(如果没禁用锁)和
PROCESS(用于获取表结构)权限
遇到 ERROR 1290 (HY000): The MySQL server is running with the --read-only option
怎么办?
这不是备份命令报的错,而是你试图在只读实例上执行写操作(比如
mysqldump带
--master-data且服务器没开
log_bin,或用了
--dump-slave却没从库权限)。关键点在于:只读限制的是写,不是备份本身。
排查方向:
去掉--master-data=1/2或
--dump-slave=1/2—— 它们会触发
SHOW MASTER STATUS或
SHOW SLAVE STATUS,某些只读配置下这些语句被拦截 确认是否误连到了从库且该从库启用了
super_read_only=ON(比
read_only更严格,连 super 用户都受限) 用
--no-tablespaces避免因
INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES权限缺失导致失败
只读库没有 mysqldump
怎么办?用 mysqlpump
或原生导出
mysqlpump是 MySQL 5.7+ 自带的并行逻辑备份工具,对只读环境更友好:默认不加全局锁,支持
--skip-lock-tables和
--single-transaction,且权限需求更低。但它要求用户有
SELECT+
SHOW VIEW+
TRIGGER(如果导出触发器)即可。
实在不行,就退到最朴素方式:
用SELECT ... INTO OUTFILE导出单表(需
FILE权限,且文件写在服务端磁盘) 用客户端工具如
mysql -e "SELECT * FROM t" > t.csv(注意字符集和字段分隔符) 避免用
mysqldump --tab,它依赖
FILE权限且生成两部分(SQL + 数据文件),在只读+权限受限环境下极易失败
物理备份(xtrabackup
)在只读实例上可行吗?可以,但别碰日志
Percona XtraBackup不依赖 MySQL 权限,直接读取数据文件,所以
read_only对它完全透明。但要注意: 必须关闭
innodb_log_archive(已废弃,但旧配置可能残留) 不要加
--backup同时启用
--apply-log—— 后者会写入日志文件,只读文件系统或挂载为 ro 的目录会失败 若数据库启用了加密表空间(
innodb_encrypt_tables=ON),需提前准备好密钥文件路径,
xtrabackup本身不处理密钥分发 备份后校验用
xtrabackup --verify,而不是启动实例,避免意外写操作
只读环境最易被忽略的点:备份脚本里藏着
SET GLOBAL read_only=OFF这类“自动修复”逻辑 —— 在生产只读库上运行等于埋雷。所有备份操作必须严格限定在只读语义内,连临时 SET 都不该出现。
