当前位置:首页 > 问答 > 正文

数据库运维|数据迁移 实践分享:简单数据库迁移操作方法与流程

数据库运维|数据迁移 实践分享:简单数据库迁移操作方法与流程

场景引入:当数据库搬家遇上"手忙脚乱"

上周隔壁研发部的小王遇到了件头疼事——他们用了三年的MySQL数据库服务器要退役了,新机器已经到位,但怎么把上百张表、上亿条数据安全搬到新家?凌晨两点他盯着屏幕上的ERROR 2003 (HY000)报错抓狂时,我突然意识到:数据迁移这种看似基础的操作,其实藏着不少容易踩坑的细节。

今天咱们就用"搬家"的视角,聊聊数据库迁移的标准姿势,不需要高端工具,就用最基础的命令行,带你走通从老库到新库的安全通道。


搬家前的"物品清点"(准备工作)

源库体检报告

-- 查看数据库大小
SELECT table_schema "数据库名", 
ROUND(SUM(data_length+index_length)/1024/1024,2) "大小(MB)" 
FROM information_schema.tables 
GROUP BY table_schema;
-- 检查特殊对象
SHOW PROCEDURE STATUS;  -- 存储过程
SHOW FUNCTION STATUS;  -- 函数
SHOW TRIGGERS;         -- 触发器

新家验收清单

  • 确认目标库版本不低于源库(比如MySQL 5.7→8.0可以,反过来可能报错)
  • 检查磁盘空间至少是源库的1.5倍
  • 提前在目标库创建同名账号并授权

最佳搬家时间窗

数据库运维|数据迁移 实践分享:简单数据库迁移操作方法与流程

  • 低峰期操作(比如凌晨)
  • 提前发停机公告(如果允许停机)
  • 准备回滚方案(老服务器先别急着关)

三种实用搬家方案

方案1:mysqldump经典搬运车(适合中小库)

# 全库打包(包含存储过程等)
mysqldump -u root -p --routines --triggers --single-transaction --master-data=2 source_db > backup.sql
# 传输到目标服务器(推荐用scp/rsync)
scp backup.sql user@new_server:/tmp/
# 新库导入
mysql -u root -p target_db < /tmp/backup.sql

避坑指南:

  • --single-transaction避免锁表(仅InnoDB有效)
  • 大表可以用--where分批导出
  • 导入时关注max_allowed_packet参数

方案2:物理文件快递(适合超大库)

# 源库锁表备份
FLUSH TABLES WITH READ LOCK;
system cp -r /var/lib/mysql/data_dir /backup/
UNLOCK TABLES;
# 目标库替换数据文件(需停服务)
systemctl stop mysql
rm -rf /var/lib/mysql/data_dir/*
cp -r /backup/data_dir /var/lib/mysql/
chown -R mysql:mysql /var/lib/mysql/data_dir
systemctl start mysql

特别注意:

  • 确保源库和目标库版本完全一致
  • MyISAM表用这种方法更高效
  • 操作前一定要验证备份完整性

方案3:主从同步搬家(几乎零停机)

-- 目标库执行
CHANGE MASTER TO
MASTER_HOST='old_server_ip',
MASTER_USER='replica_user',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=107;
START SLAVE;
SHOW SLAVE STATUS\G  -- 查看同步状态

优雅切换技巧:

  1. 先做全量同步
  2. 配置主从关系追增量
  3. 业务低峰期修改应用连接串

搬家后的验收 checklist

  1. 数据一致性核验

    数据库运维|数据迁移 实践分享:简单数据库迁移操作方法与流程

    -- 随机抽查表记录数
    SELECT 'users', (SELECT COUNT(*) FROM source_db.users), (SELECT COUNT(*) FROM target_db.users)
    UNION ALL
    SELECT 'orders', (SELECT COUNT(*) FROM source_db.orders), (SELECT COUNT(*) FROM target_db.orders);
  2. 功能测试要点

  • 执行几个关键存储过程
  • 触发几个重要业务逻辑的触发器
  • 检查自增ID是否连续
  1. 性能基线对比
    -- 相同查询响应时间对比
    SELECT * FROM large_table WHERE create_time > '2025-01-01' LIMIT 1000;

常见翻车现场救援

场景1:导入时报外键错误

  • 临时禁用外键检查:SET FOREIGN_KEY_CHECKS=0;
  • 导入完成后记得重新开启

场景2:存储过程语法不兼容

  • 检查sql_mode是否一致:SHOW VARIABLES LIKE 'sql_mode';
  • 特别关注ONLY_FULL_GROUP_BY等严格模式

场景3:磁盘空间不足中断

数据库运维|数据迁移 实践分享:简单数据库迁移操作方法与流程

  • pv监控进度:pv backup.sql | mysql -u root -p target_db
  • 估算时间公式:数据量/(磁盘写入速度×0.7)

写在最后

记得第一次做数据迁移时,我把整个部门的订单表导重复了,最后不得不手动删了三个小时,现在回想起来,数据库迁移就像搬家——打包时觉得"这个还有用要带上",到新家才发现好多是冗余。

建议你在下次迁移前,不妨先回答三个问题:

  1. 这数据真的需要搬吗?(趁机做次数据瘦身)
  2. 最简单的方案是什么?(别为了炫技用复杂工具)
  3. 如果现在断电,知道怎么恢复吗?

(2025-08 根据生产环境案例整理)

发表评论