暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

从一次生产事故来谈谈数据主键设计

原创 aisql 2022-12-09
694
一、事故原因

saas系统新版发布后,灰度环境引发一个严重的阻断性bug,开发发来了bug修复的数据库脚本。脚本如下:

ALTER TABLE billno ADD COLUMN `posno` NVARCHAR(200) NOT NULL DEFAULT '' COMMENT 'pos机设备号'; alter table billno drop primary key; ALTER TABLE `billno` ADD PRIMARY KEY (`tid`,`billtype`,`datas`,`posno`);

考虑到要重建主键,这个脚本在生产环境修复执行风险很高,但如果不执行,灰度环境bug将不能得到及时修复,左右为难。

我去select count(*) from billno 抽样检查了几个库这个表的行数。发现都不高。高的10万左右,低的只有两三万行,且此表是一个小表。

我就在生产上执行此语句,然后就产生了严重后果。数据库直接被打死。

show full processlist 发现大量的 Waiting for table metadata lock

咨询开发 billno 这个表并发量非常大。所以 ALTER TABLE 一直拿到不 metadata lock 造成了后面所有对此表的所有操作都堵塞

二、解决过程;

第一个想到的是kill掉 所有堵塞的语句。
发现根本行不通。由于是业务高峰期,kill掉后还是不断有操作此表的命令打进来。

线上客户不断的咨询客服,系统出问题了。压力山大。

最终和开发确认,停掉应用服务器。重新执行脚本

重新执脚本。发现创建主键已不成功了。原因是有些库 alter table billno drop primary key; 这句执行成功了。但创建主键执行不了。所以数据库已有重复数据了。

然后我们修复重复数据,再执行脚本。恢复应用服务器,系统终于正常运行了。

三、谈谈主键设计

这个系统是17年前设计的老系统了。主键都是采用业务主键。
而当业务发生变化的时候,就只能重建主键。虽然我们可以选择在晚上业务低峰执行。但这种还是有较大风险的。

这种业务主键显而易见的几个问题
1、业务发生变化,引发重建主键,对线上业务是毁灭性的。
2、造成极大的存储空间浪费
3、页分裂明显增多,造成数据库抖动也就增加。

综上所述,数据库主键我的建议是 用单一主键,雪花等算法业务生成即可。
我不用建议用自增的原因是,当父子表,主外键关联表(业务需要的,数据库不建主外键) 等子表与外键表 需要查一次主表才能获到自增ID的值。

如果mysql 能早日实现 sql server output子句,那么就可以直接采用自增主键了。

以上为个人浅见。大佬有不同的看法,欢迎评论指出。

最后修改时间:2022-12-14 09:47:24
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论