背景
收假后上班的第一天,接到产品的通知需要把年前迭代的若干功能发布到线上。(研发只需要管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备份一次后,找个实验环境,走一遍你的方案,确认方案可以后,再去线上操作!