记录一次生产环境数据库迁移
迁移要求
不要清理目标数据
迁移是老环境迁移到新环境, 新环境之前有过使用记录了, 要求不删除现有的数据, 将老数据导入。有以下几个问题:
- 导出的 sql 里面不能带 drop table 语句,所以在 mysqldump 的时候需要加上
--skip-add-drop-table
参数 - 主键或唯一键重复的问题,需要增加参数
--skip-extended-insert
- sql 执行失败了需要继续, 因为现有数据可能和老环境冲突, 所以插入失败不能影响其他数据的插入, 这里选择在 mysql 控制台执行 source 命令。
备份源数据库
1 | mysqldump -h192.168.21.26 -P3306 -uroot -p<password> --skip-add-drop-table --skip-extended-insert --databases test_database > test.sql |
–skip-add-drop-table 这个参数为了不在 sql 文件里面增加 drop 语句,不加的话,执行这个 sql 会先将表删掉,再重新创建。
–skip-extended-insert 导出的 sql 一个 insert 对应一条数据。
如何将备份的 sql 发送到目标机器
数据量较大,又受限于网络情况, 所以直接在服务器上导出后,使用 tar 压缩, 然后通过 nginx 将文件暴露出来,在目标机器上使用 wget 下载。
遇到的一些问题
迁移后数据量相差过大
因为目标数据库不需要清空,所以增加了 --skip-add-drop-table
参数,导出的 sql 是不带 drop 语句的, 默认情况下 mysqldump 导出的 sql 为下图右边这种,即会把很多条数据整合成一条 insert 语句,那么如果里面有一条数据存在主键冲突,整条 insert 就会失败,这就是造成数据量相差过大的原因。所以这种情况需要增加 --skip-extended-insert
参数。
库名不一致如何修改
两个环境库名不一致, 需要修改 sql 里面的库名, sql 文件又太大, 选择使用 sed 命令来修改 (不要小瞧这一步,我们一个 24G 的 sql 文件修改耗时 15 分钟左右)
1 | sed -e 's/USE `idk_base`;/USE `db_idk_base`;/g;' -i test.sql |
下载上传太慢的问题
选择服务器使用公网直接传输,不再通过自己的电脑中转。
跳板机超时被关闭的问题
在 mysql 命令行界面执行 source 命令, 如果窗口被关闭,那么执行就停止了, 使用 nohup 又无法做到交互式执行, 于是选择 screen
使用 screen -L 来创建一个新的虚拟窗口(-L 参数可以将控制台的所有输出记录到当前目录下的一个文件内), 在里面执行 mysql 命令 source 命令后,按下 ctrl +a d 就可以放到后台执行, 执行 screen -r 恢复连接之前的 screen 界面。
screen 详细使用教程可以查看 Linux终端复用器Screen和tmux