给一个日IP三千的网站做数据迁移,结果数据库崩了四小时

王尘宇 经验分享 2

上个月做了一件蠢事,觉得有必要写下来。帮朋友把一个日IP三千左右的站从一台阿里云ECS迁到另一台,本来想着两小时搞定,结果数据库崩了四个小时,中间老板打了三通电话过来问"网站怎么打不开"。

事情经过

迁移计划是这样的:先在新服务器装好环境,然后导出旧服务器的数据库和文件,传到新服务器导入。套路很常规,我也不是第一次干。

翻车的地方出在数据库导入这一步。旧的MySQL是5.7版本,新服务器装的是8.0。mysqldump导出的时候用了默认参数,导入到8.0的时候直接报错:datetime字段的默认值格式不兼容,几十张表挂了七八张。

这时候我犯了个更大的错误——没先在新服务器上做测试导入。我直接把旧服务器停掉了,想着一口气迁完。结果新服务器导入卡住,旧的又关了,两边都打不开。

怎么修好的

第一步,先恢复旧服务器的数据库服务。旧服务器只是关了Web服务,数据库还在,重新启动MySQL就行。网站立马恢复——先让用户能用再说。

第二步,在新服务器上建一个测试库,把mysqldump的文件导进去,逐一检查报错。最终找到三个坑:

1. datetime默认值0000-00-00在MySQL 8.0里不支持,需要改成NULL或者改成1970-01-01。

2. 字符集从utf8mb3变成了utf8mb4,部分索引长度超限,删了重建。

3. 有个插件的自定义表用了MyISAM引擎,在新服务器上跑了半天才发现数据不一致,改成InnoDB才正常。

学到的教训

第一,迁移永远先做测试导入,确认无误再切流量。这句话听过无数遍,但着急的时候就忘了。

第二,停旧服务器之前,给自己留一条回滚的路。我这次是把Web关了但数据库没关,算是运气好。更稳的做法是用nginx的反向代理切流量,新旧环境并跑一段时间。

第三,MySQL大版本升级要提前做兼容性检查。工具可以用mysqlcheck或者pt-upgrade,花十分钟检查,省四小时救火。

写了这么多,其实就是一句话:别急,也别懒。

标签: 数据库迁移 mysql 踩坑记录 服务器运维

发布评论 0条评论)

  • Refresh code

还木有评论哦,快来抢沙发吧~