分片备份需明确四点:①按配置文件定义分片组而非库名模糊匹配;②控制并发数并用--single-transaction避免锁表;③文件名含分片组、库名、时间戳且单独压缩;④元数据表须单独高频备份,不可遗漏。

备份前先确认哪些库属于同一分片组
MySQL 本身不管理“分片逻辑”,所谓按逻辑库分组,本质是你自己定义的映射关系:比如 shard_001、shard_002 对应业务上的“用户分片”,而 order_shard_01、order_shard_02 是另一组。备份时必须靠人工或配置文件维护这个分组清单,否则脚本没法自动归类。
常见错误是直接用 SHOW DATABASES 模糊匹配(如 LIKE '%shard%'),结果把监控库、测试库也卷进去了。更稳妥的做法是维护一个分组配置文件(JSON 或纯文本),例如:
shard_user: [shard_001, shard_002, shard_003] shard_order: [order_shard_01, order_shard_02]
执行备份脚本时读这个配置,而不是依赖库名规则。
用 mysqldump 按组并发备份但避免连接打爆
mysqldump 默认单线程导出整个库,但按组并行时,每个组起一个 mysqldump 进程,容易触发 MySQL 的 max_connections 限制,尤其当分片数多、单库又大时,可能卡住或报错 Too many connections。
实操建议:
- 给每个
mysqldump加--single-transaction(InnoDB 必须),但别加--lock-tables,否则跨库锁会互相阻塞 - 用
--host+--port显式指定目标实例,防止误连到其他环境 - 限制并发数:用
GNU parallel或简单 shell 的wait控制同时最多 2–3 组在跑,别硬上&全开 - 为每组输出单独目录,路径含分组名,例如:
/backup/20240520/shard_user/,避免文件混在一起
备份文件命名必须带分片组标识和时间戳
只用 mysqldump -B db1 db2 > backup.sql 会丢失上下文:你不知道这个 SQL 文件对应哪几个库、属于哪个分片组、甚至是不是全量——下次恢复时极易配错。
正确做法是每个库单独 dump,并在文件名中固化关键信息:
- 文件名格式统一为:
{group}_{db}_{YYYYMMDD}_{HHMMSS}.sql.gz,例如shard_user_shard_001_20240520_221503.sql.gz - 用
gzip实时压缩,加-q静默,避免日志刷屏干扰判断 - 导出后立即校验:用
gzip -t检查是否损坏,再用head -n 20看前几行是否有CREATE DATABASE和库名匹配
跳过系统库和临时库,但别漏掉分片元数据表
默认排除 information_schema、performance_schema、mysql 是对的,但很多人顺手把 sys 也跳了——其实它不影响恢复;真正要小心的是你自建的分片路由表,比如叫 shard_mapping 或 db_route_config,这类表通常放在某个中心库(如 meta_db)里,不属于任何分片组,但恢复分片时必须先还原它,否则应用找不到库在哪。
所以备份策略得拆成两层:
- 分片组备份:只含各
shard_xxx库,不碰meta_db - 元数据备份:单独、高频(比如每小时)dump
meta_db,且每次备份后grep确认关键表存在 - 别用
mysqldump --all-databases,它会把所有库混在一个文件里,违背“按组隔离”初衷
分片备份不是单纯多跑几次 mysqldump,关键是分组定义清晰、并发可控、文件可追溯、元数据不遗漏——这四点里任意一点模糊,恢复时就会卡在凌晨三点对着一堆 .sql.gz 发呆。











