最常用且易出错的远程备份方式是mysqldump直连,需确保远程mysql开放网络访问、用户具备对应ip的select等权限;常见错误为1045拒绝访问,根源多为权限不足或max_allowed_packet/超时设置不当;推荐用mysql_config_editor管理凭证、--single-transaction避免锁表、--ignore-table精准跳过表、ssh管道方式绕过网络限制。

用 mysqldump 直连远程库备份,最常用也最容易出错
只要远程 MySQL 服务开了网络访问(bind-address 允许非 127.0.0.1,且用户有远程连接权限),mysqldump 就能直接连过去导出,不用先 ssh 登录再操作。
常见错误现象:mysqldump: Got error: 1045: Access denied for user 'xxx'@'xxx.xxx.xxx.xxx'——不是密码错了,而是该用户没被授权从你的本地 IP 连接,或者没给 SELECT 权限。
- 确认远程用户权限:执行
SHOW GRANTS FOR 'user'@'%';或'user'@'your_ip',确保包含SELECT和LOCK TABLES(--single-transaction可绕过后者) - 加
--host=xxx.xxx.xxx.xxx --port=3306显式指定,别依赖配置文件或别名 - 敏感信息别硬写进命令行:用
mysql_config_editor存认证,或通过--defaults-file=/path/to/my.cnf传配置 - 大库务必加
--single-transaction(InnoDB)或--lock-tables=false(谨慎),否则可能锁表阻塞业务
mysqldump 的 --where 和 --ignore-table 是按需备份的关键
全量备份太重?又不想写脚本过滤数据?mysqldump 自带轻量筛选能力,但参数行为容易误解。
-
--where="created_at >= '2024-01-01'"只对单个表生效,必须配合db_name table_name使用,不能用于整个库 -
--ignore-table=db_name.log_table可跳过指定表,注意格式是db.table,不是table,漏写库名会报错 - 如果要排除多个表,得重复写多次
--ignore-table,不支持通配符或逗号分隔 - 用
--no-data+--skip-triggers可快速导出空表结构,适合迁移前校验
远程备份失败时,先查 max_allowed_packet 和超时设置
导着导着中断,没报错但文件不完整?大概率是网络传输中 packet 被截断,或连接被服务端主动断开。
- 远程 MySQL 的
max_allowed_packet必须 ≥ 你本地mysqldump生成的最大单条语句(比如含大 BLOB 的 INSERT),建议两边都设成256M - 加
--net-buffer-length=1048576避免频繁分包;加--timeout=3600防止短连接超时(尤其跨公网) - 如果远程库启用了
wait_timeout(默认 28800 秒),但你的 dump 耗时更长,仍可能中断——此时必须加--skip-extended-insert减少单行长度,或改用--tab分离数据与结构 - 别信“本地跑得通,远程就一定行”:内网延迟低、包不分片;公网丢包、NAT 超时、防火墙拦截都可能导致看似随机的中断
用 ssh + mysqldump 管道备份,绕过网络权限限制
当远程 MySQL 明确禁止外网直连(bind-address = 127.0.0.1),但你能 ssh 登录服务器,管道方式就是唯一可靠选择。
- 命令形如:
ssh user@host "mysqldump -u dbuser -p'dbpass' --single-transaction dbname" > backup.sql,注意引号嵌套和密码安全(推荐用密钥登录 +~/.my.cnf) - 别用
sudo mysqldump:除非 MySQL 用户是root且你有 sudo 权限,否则权限不匹配会导致无法读取系统表或触发器 - 管道备份无法用
--compress(压缩在本地做无效),但可以加gzip:ssh ... | gzip > backup.sql.gz - 如果远程磁盘空间紧张,避免先写临时文件再 scp——管道直接落地最省资源
真正麻烦的从来不是命令怎么写,而是搞不清远程 MySQL 到底开了哪些权限、哪个配置在起作用、网络链路上哪一环悄悄改了包大小或断了连接。动手前,先 mysql -h host -u user -p -e "SELECT VERSION(), @@max_allowed_packet" 看一眼实际环境,比查十篇教程都管用。










