容器跨主机迁移不保证数据一致,必须依赖外部机制;mysqldump --single-transaction仅对InnoDB有效且依赖REPEATABLE READ,与是否容器化无关,混用MyISAM需配合--lock-all-tables,挂载卷须注意文件系统语义、权限及大小写配置,校验须显式指定连接并启用--check-plan。

直接结论:容器跨主机迁移本身不保证数据一致,必须靠外部一致性机制兜底——本质仍是 MySQL 数据迁移问题,容器只是运行载体。
为什么 mysqldump --single-transaction 在容器里也只对 InnoDB 有效
很多人以为“跑在容器里就自动带一致性”,其实 mysqldump --single-transaction 的行为完全取决于底层 MySQL 实例的存储引擎和事务隔离级别,跟是否容器化无关。它依赖 REPEATABLE READ 快照读,而 MyISAM 表仍会触发锁表;若目标库混有 MyISAM,导出时没加 --lock-all-tables,就会漏数据。
- 确认所有表引擎:执行
SELECT table_name, engine FROM information_schema.tables WHERE table_schema = 'your_db'; - 容器内执行 dump 前,务必检查
my.cnf中是否禁用了skip-log-bin——否则 binlog 不记录,后续增量同步断档 - 别信“docker commit 镜像能存数据”:
/var/lib/mysql若没挂载卷,commit 后镜像里只有空目录或旧快照,实际数据仍在容器可写层,重启即丢
挂载卷迁移时最容易被忽略的三个细节
用 docker volume 或绑定挂载(-v /host/path:/var/lib/mysql)迁移数据,看似简单,实则极易因路径、权限、文件系统语义不一致导致损坏。
- 宿主机文件系统必须支持硬链接和原子重命名(如 XFS、ext4),否则
innodb_file_per_table=ON下的 .ibd 文件拷贝可能中断,引发页校验失败 - 目标主机上
chown -R mysql:mysql /path/to/mysql/data必须执行,否则容器启动报错Operating system error number 13(权限拒绝) - 若源容器使用
lower_case_table_names=1(Linux 默认 0),而目标主机 MySQL 配置为 0,大小写敏感表名会找不到——尤其跨平台迁移时更危险
pt-table-checksum 校验前必须关掉的两个开关
在容器环境跑 pt-table-checksum,默认会尝试连本地 socket,但容器里往往没配 mysql.sock 路径,且默认开启 --no-check-plan 可能跳过执行计划校验,导致大表 chunk 划分错误、校验遗漏。
- 显式指定连接方式:
pt-table-checksum --host=source_host --port=3306 --user=root --password=xxx,避免 socket 自动 fallback - 强制启用执行计划检查:
--check-plan,防止因统计信息陈旧导致 chunk size 过大,超时中断 - 校验期间禁止任何 DDL:
pt-table-checksum会自动加FOR UPDATE锁,若此时有人执行ALTER TABLE,可能死锁或中止校验
真正麻烦的不是怎么把数据搬过去,而是怎么证明“搬过去的就是原样”。容器让部署变轻,却没让数据一致性变简单——反而因多了一层抽象,容易让人误以为“卷挂好了就万事大吉”。校验必须落到行级,且要在业务低峰期做,因为 pt-table-checksum 对大表会持续加锁,影响写入吞吐。


















