广告:Codex Token 低价中转站稳定接口 · 快速接入 · 开发者备用通道
Engineering article

避坑 | 数据库迁移的18种备份恢复方案

数据库迁移的18种备份恢复方案 别想着一次性搞定数据库迁移,你得提前知道哪些备份恢复方案能落地,哪些会翻车。我见过太多人用mysqldump直接转,结果在亿级数据量下卡死,甚至导致服务宕机。备份恢复方案不是选一个就完事,得看你的数据库类型、数据量、网络环境、业务连续性要求,还有你对数据完整性、性能、成本的取舍。比如,使用pg_dum

避坑 | 数据库迁移的18种备份恢复方案
配图来源于网络和AI生成,仅供参考。
数据库迁移的18种备份恢复方案
▌ 技术引导
别想着一次性搞定数据库迁移,你得提前知道哪些备份恢复方案能落地,哪些会翻车。我见过太多人用mysqldump直接转,结果在亿级数据量下卡死,甚至导致服务宕机。备份恢复方案不是选一个就完事,得看你的数据库类型、数据量、网络环境、业务连续性要求,还有你对数据完整性、性能、成本的取舍。比如,使用pg_dump配合pg_restore能快速迁移PostgreSQL数据,但是要记住指定--no-owner参数,否则权限会搞错。备份恢复方案必须包含校验机制,比如用checksum校验数据一致性,或者用工具如pt-table-checksum搞定。别指望只用一个工具,一定要结合实际环境做压力测试,比如用sysbench模拟并发写入,看恢复速度和锁表情况。最后,别忘了考虑灾备方案,比如把备份文件上传到对象存储,或者用分布式备份机制,防止单点故障。

▌ 技术参考

一 抓取增量日志并重放
在MySQL里,使用gtid或者binlog来抓取增量数据是常操作。不过别傻乎乎地用mysqlbinlog全量解析,必须用--start-dump和--start-position指定起始点。对于大规模迁移,可以结合pt-online-schema-change工具实现在线迁移,这样不会锁表。记得设置binlog_format=ROW,否则会因为格式不同导致解析失败。而且要配置log_slave_updates参数,确保从库的日志也能被记录下来。这种方案对业务影响小,但需要仔细校验日志是否完整,否则差几秒钟的数据就白忙活了。

二 全量备份配合增量同步
全量备份和增量同步是组合拳。先用mysqldump做全量,然后用binlog或GTID做增量。全量备份时间可能很长,尤其数据量大的时候,得注意调整--quick参数,避免内存溢出。增量同步可以用pt-heartbeat来监控主从延迟,或者用Percona XtraBackup做冷备份。长连接是关键,要配置max_allowed_packet=1G,这样能减少传输次数。不过这种方案对网络稳定性要求很高,一旦断开,中间的数据就会丢。

三 使用阿里云DTS进行数据迁移
DTS是阿里云内部用的工具,但对外也有接口。它支持增量同步、全量同步,还能自动修复数据类型差异。配置的时候得选好迁移模式,比如全量+增量,或者只增量。DTS会自动创建临时表,处理冲突数据,但性能取决于网络带宽。我之前用DTS迁移一个百万级表,发现它对主键冲突的处理方式会卡在某个节点,得手动调整冲突解决策略。另外,DTS在处理分区表时,必须指定相应的参数,否则会分片混乱。

四 数据库快照与恢复
对于云数据库来说,快照是一个方便的选择。比如AWS RDS或阿里云RDS,可以创建快照然后恢复。但别忘了一个关键点,快照恢复后数据库的版本可能会有差异,要确保目标实例的版本兼容。快照恢复耗时长,尤其在数据量大的时候,得提前规划好冷热数据分离。快照不是万能的,如果有临时表或者未提交事务,恢复后的数据可能不一致。而且快照恢复只能恢复到某个时间点,不能做到按秒级回滚。

五 使用文件系统级复制工具
像rsync或scp这类工具,虽然简单,但能实现快速迁移。不过别直接复制数据文件夹,得确保mysqldump或者pg_dump已经关闭了写操作,否则会出现文件锁问题。rsync的--incremental参数能减少传输的数据量,但需要在源数据库上配置只读模式。复制后的恢复需注意数据文件的权限,比如在Linux上要确保用户有读写权限。这种方案适合本地数据库迁移,但跨网络时速度可能跟不上。

六 通过中间文件库中转数据
中间库是个好办法,尤其在跨数据库迁移时。比如从MySQL迁移到PostgreSQL,中间库可以作为缓冲。要记住,中间库不能随便用,得用相同的数据类型和字段名。另外,中间库最好和源库用同种引擎,比如InnoDB,否则可能会有转换问题。中间库迁移完后,再用工具如pgloader或DataX导出数据。别用简单的导出导入,得有校验机制,比如用SQL脚本逐条比对数据。

七 利用容器化进行数据迁移
Docker和Kubernetes能用来做数据迁移。比如把源数据库容器化,然后用docker commit生成镜像。不过别把数据直接放容器里,得用volume挂载。迁移时要确保容器版本一致,否则可能有兼容问题。Kubernetes的StatefulSet能管理有状态应用,但要注意PersistentVolume的配置。我也试过用Kubernetes的ConfigMap来保存配置文件,结果发现数据量太大,存不下,只能用Secret。这种方案适合测试环境,生产上还是得谨慎。

八 数据库镜像与日志回放
数据库镜像在Oracle和SQL Server里比较常见,但MySQL和PostgreSQL一般不用。镜像能实现实时同步,但恢复时需要考虑日志是否完整。比如MySQL的binlog要启用log_slave_updates,这样镜像才会记录主库的复制过程。恢复的时候,镜像可能需要重新启动,这时候得确保没有其他进程在访问数据库。镜像同步对网络延迟敏感,如果延迟超过30秒,数据就可能不一致。

九 使用分布式备份方案
分布式备份能有效应对单点故障,比如用MinIO或阿里云OSS作为存储层。配置的时候需要保证所有节点的数据一致性,可以通过分布式锁机制实现。比如用etcd或Consul来管理备份状态。这种方案适合大型分布式系统,但部署起来复杂。分布式备份需要定期校验各节点数据,否则某个节点出问题,整个系统就不靠谱了。而且维护成本高,得有专门的监控机制。

十 多线程备份与恢复
多线程能显著提高备份恢复效率,但要合理配置线程数。比如用pg_dump的--jobs参数控制并发数,或者用mysqldump的--thread参数。不过别一上来就开满线程,像MySQL的--thread=10可能反而更慢,得根据服务器CPU和内存调整。多线程备份期间,数据库的读写性能会下降,要合理安排时间,比如在业务低峰期操作。恢复时,多线程能加快数据写入,但要注意索引和约束的顺序,否则会报错。

十一 通过ETL工具进行迁移
ETL工具比如Talend或Apache NiFi能处理复杂的数据转换。它们适合有数据清洗需求的迁移场景。比如从Oracle迁移到MySQL,可能需要调整字段类型,ETL工具能自动识别并转换。但别指望它能完全替代备份恢复,得结合其他工具。配置ETL任务时,要监控数据流,防止某个环节卡住。同时,ETL工具对网络波动敏感,得确保连接稳定,否则数据会丢失。

十二 数据压缩与传输优化
备份文件太大,得压缩。用gzip或者bzip2压缩,能减少传输时间。但别把所有文件都压,比如PostgreSQL的备份文件最好分卷,避免单个文件过大导致传输失败。压缩时要调整压缩级别,像gzip的-9参数会很慢,但数据一致性更好。另外,传输可以用rsync或scp,但要开启压缩选项。比如scp -C能提升传输速度。不过别在压缩过程中做其他操作,否则会增加CPU负载,影响数据库性能。

十三 使用云服务提供的迁移工具
比如AWS DMS,阿里云DTS,华为云DAS,这些工具能自动处理迁移过程。但别以为它们能完全解决问题,得自己做校验。比如DMS迁移完后,要跑SQL脚本检查数据一致性。配置这些工具时,得注意网络隔离,有些工具不支持跨VPC迁移。另外,它们的迁移速度取决于源库的写入压力,别指望在高峰时段完成。要提前设置好权限,比如在AWS里得配置IAM角色。

十四 数据库镜像与热备方案
热备是关键,不能停服务。比如MySQL的主从复制,可以实现热备。但得确保复制延迟在可控范围内,比如用pt-query-digest监控延迟。热备需要在从库上做恢复,这时候要避免写入操作,否则会同步失败。镜像恢复前要检查数据库日志是否完整,比如用SHOW MASTER LOGS查看是否有未同步的日志。热备对硬件资源要求高,尤其在数据量大的时候,得配置足够的内存和CPU。

十五 通过SQL脚本逐条导入
虽然效率低,但有时候只能这么做。比如数据量特别小,或者需要手动处理某些字段。导入的时候要禁用自动提交,用BEGIN;和COMMIT;来批量处理。还要注意索引和约束的顺序,否则会报错。比如在PostgreSQL里,先导入数据,再重建索引会更快。别用LOAD DATA INFILE,要改成COPY命令,或者用psycopg2的批量执行。这种方案适合测试环境,生产上还是得用更专业的工具。

十六 使用增量备份与快照结合
先做快照,再做增量备份,能减少恢复时间。比如在AWS RDS里,可以先创建快照,然后用增量备份捕获新数据。快照恢复时间长,但增量备份能实时捕获变化。不过别忽略快照的恢复策略,比如设置保留策略,防止快照被自动删除。增量备份期间要关闭写操作,否则会生成新的日志。这种方案适合有频繁更新的系统,但恢复时要确保时间点准确。

十七 数据库的日志截断与恢复
MySQL的binlog会记录所有操作,但不能无限增长。得定期清理binlog,否则占满磁盘。恢复时要确保没有截断日志,或者用--start-position指定位置。对于PostgreSQL,要配置archive_mode=on,确保WAL日志不会被过早清理。恢复之前要检查日志是否完整,比如用pg_waldump查看日志内容。别用简单的日志重放,得用工具如pg_restore或pg_basebackup。

十八 通过API或SDK进行数据迁移
有些数据库支持API迁移,比如Redis的RDB文件,或者MongoDB的mongodump。API能实现自动化迁移,但要注意数据一致性。比如MongoDB的mongodump默认会创建一个压缩文件,恢复时要使用mongorestore。API迁移对网络稳定性要求高,得配置重试机制。别用简单的HTTP请求,要确保数据包完整,或者用SDK来处理连接、断点续传等问题。这种方案适合有二次开发能力的团队。