1. 数据迁移前的准备工作
在开始数据迁移之前,我们需要做好充分的准备工作。这就像搬家前要打包物品一样,准备工作做得好,迁移过程就会顺利很多。
1.1 评估迁移数据量
首先需要评估要迁移的数据总量。使用du -sh命令可以查看目录大小:
bash复制du -sh /var/www/html # 查看网站目录大小
du -sh /var/lib/mysql # 查看MySQL数据库大小
对于数据库,还需要考虑:
- 表数量
- 单表最大数据量
- 是否有大字段(BLOB/TEXT等)
- 数据增长速度
提示:对于超过50GB的大型数据库,建议采用增量迁移策略,先全量再增量。
1.2 检查源服务器环境
记录源服务器的软件环境非常重要:
bash复制# 查看系统版本
cat /etc/*release
# 查看MySQL版本
mysql --version
# 查看PHP版本
php -v
# 查看Web服务器类型和版本
nginx -v 或 httpd -v
同时检查当前服务器的资源使用情况:
bash复制top -n 1 # CPU和内存使用情况
df -h # 磁盘使用情况
1.3 准备目标阿里云服务器
在阿里云控制台创建ECS实例时需要注意:
- 选择与源服务器相同或更高版本的操作系统
- 确保磁盘空间至少是源服务器使用量的1.5倍
- 对于数据库服务器,建议使用SSD云盘
- 网络带宽要足够(内网迁移可不考虑)
建议配置:
- Web服务器:2核4G起步
- 数据库服务器:4核8G起步(根据数据量调整)
1.4 建立服务器间连接
确保两台服务器之间网络通畅:
- 如果都在阿里云,可以使用内网IP,速度更快且免费
- 跨云或本地到云,需要开通安全组规则:
- 开放SSH端口(22)
- 开放数据库端口(3306,6379等)
- 限制访问IP为源服务器IP
测试连接:
bash复制ping 目标服务器IP
telnet 目标服务器IP 22
2. 文件数据迁移方案
文件迁移是数据迁移中最基础的部分,我们需要根据文件类型和大小选择合适的迁移方式。
2.1 使用rsync增量同步文件
rsync是最常用的文件同步工具,支持增量同步:
bash复制rsync -avz --progress -e "ssh -p 22" /源目录/ 用户名@目标IP:/目标目录/
参数说明:
-a:归档模式,保留文件属性-v:显示详细过程-z:压缩传输--progress:显示进度-e:指定ssh端口
对于首次同步后的小文件更新,可以添加--delete参数删除目标端不存在的文件:
bash复制rsync -avz --delete --progress -e "ssh -p 22" /源目录/ 用户名@目标IP:/目标目录/
2.2 大文件分卷压缩传输
对于单个大文件(>10GB),建议先分卷压缩再传输:
bash复制# 压缩
tar cvzf - /path/to/largefile | split -b 2G - largefile.tar.gz.
# 传输
rsync -avzP largefile.tar.gz.* 用户名@目标IP:/目标目录/
# 目标服务器合并解压
cat largefile.tar.gz.* | tar xvzf -
2.3 网站文件迁移注意事项
网站文件迁移需要特别注意:
- 配置文件中的路径可能需要调整
- 检查
.htaccess文件中的重写规则 - 确保文件权限正确:
bash复制chown -R www-data:www-data /var/www/html chmod -R 755 /var/www/html - 检查软链接是否正确迁移
2.4 使用SCP直接传输
对于小规模文件,可以使用scp直接传输:
bash复制scp -P 22 -r /本地目录 用户名@目标IP:/远程目录/
3. 数据库迁移方案
数据库迁移是数据迁移中最关键也最容易出问题的环节,需要格外小心。
3.1 MySQL数据库迁移
3.1.1 使用mysqldump导出导入
基本导出命令:
bash复制mysqldump -u root -p --single-transaction --routines --triggers --all-databases > alldb.sql
参数说明:
--single-transaction:保证数据一致性--routines:导出存储过程和函数--triggers:导出触发器
对于大型数据库,可以边导出边压缩:
bash复制mysqldump -u root -p dbname | gzip > dbname.sql.gz
导入到目标服务器:
bash复制mysql -u root -p < alldb.sql
# 或
zcat dbname.sql.gz | mysql -u root -p dbname
3.1.2 使用Percona XtraBackup热备份
对于大型生产数据库,建议使用Percona XtraBackup实现热备份:
- 源服务器备份:
bash复制xtrabackup --backup --user=root --password=密码 --target-dir=/backup/
xtrabackup --prepare --target-dir=/backup/
-
将备份文件传输到目标服务器
-
目标服务器恢复:
bash复制xtrabackup --copy-back --target-dir=/backup/
chown -R mysql:mysql /var/lib/mysql
systemctl start mysql
3.2 Redis数据迁移
Redis迁移相对简单,有以下几种方式:
3.2.1 RDB文件迁移
- 源服务器执行:
bash复制redis-cli save # 同步保存
# 或
redis-cli bgsave # 后台保存
-
传输dump.rdb文件到目标服务器
-
目标服务器替换RDB文件后重启Redis
3.2.2 使用redis-cli直接同步
bash复制# 在目标服务器执行
redis-cli --rdb /tmp/dump.rdb -h 源服务器IP
3.2.3 使用AOF方式
如果启用了AOF持久化,可以直接复制AOF文件:
bash复制# 源服务器
redis-cli BGREWRITEAOF
# 复制appendonly.aof到目标服务器
3.3 数据库迁移后的验证
数据库迁移完成后必须验证:
- 检查所有表是否存在:
sql复制SELECT table_name FROM information_schema.tables WHERE table_schema = '数据库名';
- 抽样检查数据:
sql复制SELECT COUNT(*) FROM 重要表名;
SELECT * FROM 重要表名 LIMIT 5;
- 检查存储过程和触发器:
sql复制SHOW PROCEDURE STATUS;
SHOW TRIGGERS;
- 检查用户权限:
sql复制SELECT user, host FROM mysql.user;
SHOW GRANTS FOR '用户名'@'主机';
4. Docker容器迁移方案
随着容器化技术的普及,越来越多的应用运行在Docker中,迁移方式也有所不同。
4.1 迁移Docker容器
4.1.1 使用docker commit保存容器状态
bash复制docker commit 容器ID 新镜像名:标签
docker save -o 备份文件.tar 新镜像名:标签
将备份文件传输到目标服务器后:
bash复制docker load -i 备份文件.tar
docker run -d -p 主机端口:容器端口 新镜像名:标签
4.1.2 使用docker-compose迁移
如果有docker-compose.yml文件:
- 复制docker-compose.yml到目标服务器
- 复制所有需要的配置文件
- 启动服务:
bash复制docker-compose up -d
4.2 迁移Docker数据卷
数据卷是Docker持久化存储的关键,迁移方法:
4.2.1 直接备份数据卷目录
bash复制# 查找数据卷位置
docker inspect 容器ID | grep "Source"
# 备份数据
tar cvzf data_volume.tar.gz /var/lib/docker/volumes/卷名
4.2.2 使用专用工具备份
bash复制docker run --rm -v 卷名:/volume -v /backup:/backup alpine \
tar cvzf /backup/backup.tar.gz -C /volume ./
4.3 重建Docker网络环境
迁移后可能需要重建网络:
- 创建相同名称的网络:
bash复制docker network create 网络名
- 启动容器时指定网络:
bash复制docker run --network=网络名 ...
- 检查网络连通性:
bash复制docker exec 容器ID ping 其他容器名
5. 迁移后的收尾工作
数据迁移完成后,还需要进行一系列的验证和优化工作。
5.1 配置检查和调整
- 检查服务器时区:
bash复制timedatectl
- 检查DNS设置:
bash复制cat /etc/resolv.conf
- 检查防火墙设置:
bash复制iptables -L -n
# 或
firewall-cmd --list-all
- 检查计划任务:
bash复制crontab -l
5.2 服务启动顺序
正确的服务启动顺序很重要:
- 数据库服务
- 缓存服务(Redis等)
- 消息队列
- 应用服务
- Web服务器
可以使用systemd的依赖关系管理:
ini复制[Unit]
After=mysql.service redis.service
5.3 性能调优
根据新服务器配置进行调优:
5.3.1 MySQL调优
编辑/etc/my.cnf:
ini复制[mysqld]
innodb_buffer_pool_size = 4G # 建议为内存的50-70%
innodb_log_file_size = 512M
max_connections = 200
5.3.2 PHP调优
编辑php.ini:
ini复制memory_limit = 256M
upload_max_filesize = 64M
post_max_size = 64M
opcache.enable=1
5.3.3 Web服务器调优
Nginx示例:
nginx复制worker_processes auto;
worker_connections 1024;
keepalive_timeout 65;
gzip on;
5.4 监控和日志
设置监控:
- 安装基础监控工具:
bash复制# 对于CentOS
yum install sysstat
# 对于Ubuntu
apt install sysstat
- 配置日志轮转:
bash复制vim /etc/logrotate.d/nginx
- 设置日志分析:
bash复制# 安装goaccess
yum install goaccess
# 分析nginx日志
goaccess /var/log/nginx/access.log -o report.html --log-format=COMBINED
6. 常见问题与解决方案
在实际迁移过程中,可能会遇到各种问题,这里总结一些常见问题的解决方法。
6.1 文件权限问题
迁移后常见的权限问题:
- Web服务器无法访问文件:
bash复制chown -R www-data:www-data /var/www/html
find /var/www/html -type d -exec chmod 755 {} \;
find /var/www/html -type f -exec chmod 644 {} \;
- SELinux导致的问题:
bash复制# 临时禁用
setenforce 0
# 永久禁用
vim /etc/selinux/config
SELINUX=disabled
6.2 数据库连接问题
迁移后数据库连接失败的常见原因:
- 用户权限未迁移:
sql复制-- 在源服务器导出权限
mysql -uroot -p --skip-column-names -A -e"SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',host,''';') FROM mysql.user WHERE user<>''" | mysql -uroot -p --skip-column-names -A | sed 's/$/;/g' > grants.sql
-- 在目标服务器导入权限
mysql -uroot -p < grants.sql
- 防火墙阻止连接:
bash复制# 开放3306端口
firewall-cmd --zone=public --add-port=3306/tcp --permanent
firewall-cmd --reload
6.3 时区不一致问题
数据库和应用服务器时区不一致会导致时间显示错误:
sql复制-- MySQL设置时区
SET GLOBAL time_zone = '+8:00';
SET time_zone = '+8:00';
PHP设置时区:
php复制date_default_timezone_set('Asia/Shanghai');
6.4 性能下降问题
迁移后性能可能下降的原因:
- 阿里云服务器未开启性能模式:
bash复制# 检查CPU模式
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
# 设置为性能模式
echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
- 磁盘IO性能差:
bash复制# 测试磁盘IO
dd if=/dev/zero of=testfile bs=1G count=1 oflag=direct
- 网络延迟高:
bash复制# 测试网络延迟
ping 目标IP
mtr 目标IP
7. 迁移后的测试策略
完整的测试是确保迁移成功的最后一步,也是最重要的一步。
7.1 基础功能测试
- Web服务测试:
bash复制curl -I http://localhost
- 数据库连接测试:
bash复制mysql -u用户名 -p密码 -h127.0.0.1 -e "SHOW DATABASES;"
- API接口测试:
bash复制curl -X GET "http://localhost/api/test" -H "accept: application/json"
7.2 性能测试
- 使用ab进行压力测试:
bash复制ab -n 1000 -c 100 http://localhost/
- 数据库性能测试:
sql复制-- 创建测试表
CREATE TABLE test_table (id INT AUTO_INCREMENT PRIMARY KEY, data VARCHAR(255));
-- 插入测试数据
INSERT INTO test_table (data) VALUES (REPEAT('a', 255));
-- 性能测试查询
SELECT BENCHMARK(1000000, MD5('test'));
7.3 全链路测试
模拟真实用户访问流程:
- 用户登录
- 浏览商品
- 加入购物车
- 下单支付
- 查看订单
记录每个步骤的响应时间和成功率。
7.4 监控系统运行
设置监控指标:
- CPU使用率
- 内存使用量
- 磁盘IO
- 网络带宽
- 服务响应时间
使用工具:
bash复制# 实时监控
top
htop
iotop
iftop
# 历史数据分析
sar -u 1 3
sar -r 1 3
8. 回滚方案设计
即使准备充分,迁移仍有可能失败,必须准备回滚方案。
8.1 文件回滚
保留源服务器文件至少7天,回滚步骤:
- 停止目标服务器服务
- 使用rsync反向同步:
bash复制rsync -avz --delete 用户名@源服务器IP:/源目录/ /目标目录/
8.2 数据库回滚
- 如果使用mysqldump,保留源服务器数据库不变
- 如果使用了Percona XtraBackup,保留源服务器二进制日志
回滚命令:
bash复制mysql -uroot -p -e "STOP SLAVE; RESET SLAVE ALL;"
mysql -uroot -p < 备份文件.sql
8.3 DNS切换回滚
如果修改了DNS解析,可以设置较短的TTL(如300秒),出现问题立即切换回原IP。
8.4 容器回滚
对于Docker容器,可以快速切换回旧版本:
bash复制docker stop 新容器
docker start 旧容器
或者使用标签回滚:
bash复制docker-compose pull
docker-compose up -d --force-recreate
8.5 回滚测试
定期测试回滚流程:
- 模拟故障
- 执行回滚
- 验证系统状态
- 记录回滚时间
目标是能在30分钟内完成回滚操作。
