数据库迁移核心取决于数据库类型、停机容忍度、数据量及目标环境初始化情况;mysql优先用mysqldump管道直传并加--single-transaction等参数,postgresql推荐-fc格式+pg_restore并行处理,不停机需主从或逻辑复制+数据一致性校验。
直接转移数据库到另一台服务器,核心取决于你用的是什么数据库、是否允许停机、数据量大小,以及目标环境是否已初始化。mysql 和 postgresql 最常用,方案差异明显;盲目用 mysqldump 或 pg_dump 全量导出再导入,常在大库上卡住或丢权限/时区/序列值。
MySQL:停机可接受时,优先用 mysqldump + mysql 管道直传
比先写文件再 scp 更快,避免中间磁盘 IO 瓶颈,也省空间。但必须确保源库无长事务、目标库字符集一致、且 max_allowed_packet 足够大(否则导入中途报错 Got a packet bigger than 'max_allowed_packet' bytes)。
实操建议:
- 加
--single-transaction保证一致性(仅对 InnoDB 有效),别漏掉--routines --triggers --events,否则存储过程和事件不会导出 - 目标服务器执行前先创建空库:
CREATE DATABASE `dbname` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;,否则默认字符集可能不兼容 - 管道命令示例(跳过
CREATE DATABASE语句,由你手动控制):mysqldump -h source_host -u user -p --single-transaction --routines --triggers --no-create-db --no-create-info dbname | mysql -h target_host -u user -p dbname
- 如果提示
Access denied for user ... using password: NO,检查是否用了-p但没输密码——交互式输入密码时不能跟在-p后面写明文
PostgreSQL:用 pg_dump 的 --clean 和 --if-exists 避免重复建表失败
PostgreSQL 默认导出含 DROP TABLE,但若目标库已有同名对象而权限不足,会中断。更稳妥的是导出为自定义格式(-Fc),再用 pg_restore 控制还原粒度,比如跳过某些大表或只还原 schema。
实操建议:
- 导出时加
--no-owner --no-privileges,避免因用户不存在导致还原失败;权限和属主留到后期统一配置 - 大库务必用
-j N(如-j 4)启用并行 dump,否则单线程太慢;但pg_restore并行还原需目标库开启max_parallel_workers_per_gather - 还原前清空目标库(如果需要):
dropdb dbname && createdb -E UTF8 -l C -T template0 dbname,注意-l C防止 locale 不一致报错collation "en_US.UTF-8" for encoding "UTF8" does not exist
不停机同步:MySQL 主从 or PostgreSQL 逻辑复制,不是“导出”,而是持续追平
真正意义上的“转移”往往隐含“服务不中断”。这时导出导入只是第一步,后续必须建立复制链路,等延迟归零再切流。别把 CHANGE MASTER TO 或 CREATE SUBSCRIPTION 当成一劳永逸的开关——网络抖动、WAL 归档缺失、复制槽未清理,都会让同步无声挂掉。
关键点:
- MySQL 主从:源库必须开
binlog_format=ROW,且server_id唯一;执行SHOW MASTER STATUS记下File和Position,还原后立刻START SLAVE,再查Seconds_Behind_Master - PostgreSQL 逻辑复制:源库需设置
wal_level = logical,且发布端表必须有 replica identity(通常加主键即可);订阅端执行CREATE SUBSCRIPTION后,初始数据同步走的是内部 COPY,但大表仍可能锁表几秒 - 无论哪种,首次同步完成后,务必在目标库跑一遍
CHECKSUM TABLE(MySQL)或pg_checksums(PG 12+),验证数据一致性,别只看复制状态是running
最易被忽略的是时间相关字段和序列:MySQL 的 TIMESTAMP 默认随系统时区变,PostgreSQL 的 serial 列还原后当前值不会自动更新,下次插入会冲突。这些细节不提前处理,上线就报错。










