本文转载自微信公众号「后端研究所」,作者大白斯基 。转载本文请联系后端研究所公众号。
大家好,我是后端研究所大白所长!
今天和大家聊一个有趣的话题:
假如MySQL建表时主键ID是int32且自增的,谁也没想到业务发展这么快,今天忽然发现ID耗尽了,各种报警要炸锅了,请求作为后端owner的你该如何处理?
话不多说,看看我的好兄弟小黑是如何处理的,开车!
1方案一:怒刷简历 提桶跑路
这个方案很简单,怎么处理我不管,提桶跑路!
OS-1:试想大家满怀信心地加入到了一家公司,等待你的却是屎山一样的代码。
OS-2:这个项目的红利已经被前辈们吃完了,剩下的就是需要人来维护,哦,没错,没有人会在意谁在维护的,因为已经没人关注喽。
OS-3:本以为要来指点江山,谁知道却是不停填坑,唉,搞了半天还是搞土木工程的!
内心波澜起伏,终于小黑决定关上手机、下班跑路,回家改起了简历,决定提桶跑路。
画外音:小黑这种做法是不可取的,毕竟跳槽很多时候就是从一个坑到另外一个坑,还是要正视问题,努力解决才行嘛,最后我们祝福小黑。
2方案二:救命的空洞
报警还在呼呼发,小黑的脸更黑了,内心慌得一批,旁边的同事大刘见状说:"小黑别慌,先及时止损,再寻找彻底解决的方案"。
听听,听听,大刘一出手就是老架构师的味道。
大刘深知光扯方法论有个屁用,拿出解决方案才是硬道理。图片
大刘说:"小黑你看下这个表的ID是从1开始的吗?在建表初期有没有空洞之类的,先让数据强制写到前面空洞区域,缓解一下线上危机,再找DBA把ID的字段改成bigINT。"
小黑迅速get到大刘的意思,迅速看了一下,还真有100w的空洞啊!
小黑的泪水夺目而出,恨不得抱着大刘说:"恩人啊大刘。"
说干就干,小黑花了10分钟改完走了快速上线,终于报警慢慢降下来了,100w的空洞够用几天了,小黑的脸也没这么黑了。
接着小黑找到了DBA老张,和老张说明了情况于是开始了在线修改字段类型,由于表很大,这个操作非常耗时,好在空洞可以撑一段时间。
终于在晚上6点表字段改成了bigint,从32位到64位再也不用担心会耗尽了。
小黑拉上大刘和老张来到了肉串汪,好好谢谢这两位大神。
画外音:快谢谢身边那些每次都提出切实可行方案的同事吧,要成为老架构师的路还长着呢,小黑加油!
3方案三:忍痛割爱
报警就像龙卷风一样吹得小黑头晕目眩,小黑想到了图灵、想到了冯诺依曼、想到了马云、想到了马化腾...
一番思想斗争之后,小黑决定迎难而上,干!
旁边大刘凑过来说:"小黑别慌,这个是已知问题,可能是之前的人没交接清楚,挖了这个坑"。
小黑看着大刘说:"大刘有啥好办法吗?"
大刘道:"大原则是优先止损,则深度解决,印象中ID是从1开始的没有空洞,但是早期的数据应该不用了,你可以回收一波,腾出空间让新数据写到旧ID上,业务影响有限可以及时止损。"
小黑get了大刘的意思,好在前几天刚写了个删库脚本,没想到派上用场了,小黑改了一点拿到线上环境回收了100w个ID,但是这100w个ID并不是连续的。
小黑想了一下,决定加个中间层,把这100w个ID先存储到了redis中,线上服务先读redis拿到可用的ID再进行写库,从而缓解了问题。
快速修复上线后,报警逐渐降下来了,于是小黑抓紧找到了DBA老张来修改ID字段类型。
终于在晚上6点表字段改成了bigint,从32位到64位再也不用担心会耗尽了。
小黑拉上大刘和老张来到了木屋烧烤,好好谢谢这两位大神。
画外音:问题总会有解决方案的,平时注意积累,关键时刻可以提供解决问题的速度,平时多流汗,战时少流泪。
4小结
对于这个问题,网上很多相关的文章,基本上都是再说改成bigint,这种说法不能说错,但是不够及时雨。
试想32位都写满了的大表,改字段要消耗多久?这期间的新写数据怎么办?并不能及时止损,P0事故是跑不了了。
除了文中的几种方案,结合具体的场景还会有其他做法:比如新建一张表,双读&单写新表,总之方法不止一种,结合场景&及时止损才是真正的好方案。
就写这么多吧!