记一次线上操作bug
身为程序猿,可以说天天都会遇到bug,今天没为什么记下这次bug呢?说来惭愧,因为这次bug是由于自己不仔细没有仔细检查没有测试就对线上数据下手造成的,一方面是记下这个bug的由来,修复方法和犯下的失误的地方,另一方面也是留下记录警示自己操作线上数据一定要小心再小心,还有就是不要对自己过于自信,测试很重要。
先说一下bug的缘由,19号晚上我们上线了一个新功能,有一个功能模块是另外一个同事负责的,所以对其实现不是很了解,但数据导入有老夫负责,所以数据导入的时候,有一个结束时间没有考虑清楚,只有日期没有时间(产品经理和另一位同事当时也没有给我说),所以数据库里面结束时间变成了默认的“00:00:00”,本来修起来应该很简单,读出来update一下时间就好了,但由于是部门间的协作,比较麻烦,就考虑用SQL解决,所以就写出了如下的SQL:
CREATE TABLE t_goods_bak AS SELECT REPLACE(a.endtime,'00:00:00','23:59:59') end_time,a.* FROM t_goods a; ALTER TABLE `commercialization`.`t_goods_bak` CHANGE `id` `id` INT(11) DEFAULT 0 NOT NULL FIRST, CHANGE `end_time` `end_time` DATETIME CHARSET utf8 COLLATE utf8_general_ci NOT NULL AFTER `endtime`, CHANGE `price` `price` DECIMAL(10,2) NOT NULL COMMENT '商品单价' AFTER `end_time`; ALTER TABLE `commercialization`.`t_goods_bak` DROP COLUMN `endtime`; ALTER TABLE `commercialization`.`t_goods_bak` CHANGE `end_time` `endtime` VARCHAR(19) CHARSET utf8 COLLATE utf8_general_ci DEFAULT '' NOT NULL COMMENT '商品失效时间'; DROP TABLE `t_goods_bak`; RENAME TABLE `commercialization`.`t_goods_bak` TO `commercialization`.`t_goods`;
整体思想就是新建一张表,在新建这张表的时候,把数据修对,修对的数据放在了新添加的end_time字段,然后把这张新表t_goods_bak修改成和原来的表一致,最后把原表删除,再把这张表改一下名字,就达到了替换以前表的目的,所以就OK,看到这里也许有同学已经发现问题了:先别OK,你这新表没主键啊!!!
对,老夫当时就没有多想,以为就此OK了,所以就出现bug了,因为我没有仔细看SQL语句(这些SQL除了,第一句之外都是自动生成的),新表根本没主键,这还不是问题的关键,仔细看第二句SQL,id字段默认是0,所以所有插入的数据,默认值都是0,因为没有自增,这就是最为关键的两个问题。所以综上所述,关于修这个bug,老夫至少忘了如下几件事:
1. 为新表添加主键;
2. 设置主键自增(当然是不是自增,这和具体的业务相关);
3. 设置数据库自增开始值(当前数据里面最大的id+1)
除此之外,还有第四件事要做,要把相关的系统重启一下,否则会报表不存在的问题。
所以,修复bug不难,只要仔细看一下就能发现问题,这个bug也会警示老夫,线上数据不是测试环境,操作线上数据一定要仔细再仔细确认!最好线下测试好再操作!
// 有人说,把时间修对,根本无需如此大费周折,限于老夫SQL的水平,还请有识之士留言交流,谢谢。
2016-04-25 10:45更新:
经朋友指点,其实很简单的一条SQL,就能解决:
UPDATE `t_goods` SET `t_goods`.`endtime` = REPLACE(endtime,'00:00:00','23:59:59');
其实这件事,对我的触动更多的是:
1. 线上数据不要乱操作,一点要测试再测试,不要盲目自信;
2. 当年学习的时候没有好好学,导致SQL不好,才导致了今天的错误,其实这些SQL都是同事教着写出来的,但别人不一定知道你的具体需求,所以写出来的不一定就是你想要的
作 者: BridgeLi,https://www.bridgeli.cn
原文链接:http://www.bridgeli.cn/archives/266
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。
近期评论