记一次线上数据库迁移脚本执行报错的处理经过

背景

收假后上班的第一天,接到产品的通知需要把年前迭代的若干功能发布到线上。(研发只需要管CI流程,把近期迭代的rb-1.0.13合并到master后,触发jenkins构建后端镜像的任务,查看harbor仓库是否已经包含最近镜像!然后填写jira工单告知运维同事处理CD流程,把最新的镜像更新到线上即可!)

运维同事发布后,上线确认一下migrate迁移脚本的执行正确性:

emmm,报错了,没道理嘛!看了一下线上的mysql容器里的db的s9_table表,发现已经存在task_id字段,且已经有935条记录的task_id字段不为null。。。

打算看一下这个迁移脚本是谁写的,

emmm,居然是我写的,

回忆了一下,应该是离职的同事当初做这个功能时,没有按照标准流程导致的,意思是他直接去线上运行了alter语句去变更了表结构,导致我后面补上了这个迁移脚本后,反而执行会有冲突,因为这个字段已经存在了!!!

解决

那现在怎么办呢?

迁移脚本的目的就是为了规范数据表结构的增删改的操作,便于团队共享db的变更,同时迁移脚本归属于项目代码,被git管理起来,能更清晰的了解随着项目的迭代,数据库变更的若干细节!

那么,毫无疑问的是,现在我需要执行迁移脚本!那么,只能先备份s9_table,

mysqldump -t s9 -uroot -p --tables s9_table >/var/lib/mysql/xxx.sql

 

然后手动删除掉task_id列(当然这样就会丢失task_id的历史值),

alter table s9_table DROP COLUMN task_id;

接着,进入php-fpm容器,找到php项目的根目录,执行:

php think migrate:status

php think migrate:run

到这一步,我们的迁移脚本就执行完毕了!!!剩下的事情就是把task_id的历史数据更新回去!

接着,使用s9_table的数据来构造一批update语句,把新增的task_id的历史值,更新回去。

进入线上服务器的mysql容器,查看task_id不为null的记录数

select count(*) from s9_table where task_id is not null;

结果:935条(用于后面验证更新后的记录值与此值是否一致!)

把线上数据库task_id不为null的记录查询出来:

select `name`,task_id from s9_table where task_id is not null;

复制为update语句

通过sublime的正则替换,最终把这935条update语句替换为:

关于sublime正则用法,在此举个例子:

替换完毕保存在sql文件,rz上传到线上服务器mysql数据目录的挂载的源文件中,

我的是

/var/lib/mysql/xxx.sql

然后,进入mysql容器,

use s9;

set names utf8;

source /var/lib/mysql/xxx.sql

执行完毕,查看是不是935记录的task_id不为null,

终于,大功告成!

注意事项:

线上操作,切记三思而后行,大批量的sql语句,尽量执行source命令!当然最保险的操作,还是把线上db备份一次后,找个实验环境,走一遍你的方案,确认方案可以后,再去线上操作!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值