数据库自增主键用完了?

265 阅读2分钟

背景

线上大面积告警,数据库主键超长:

Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLDataException: '2.148269064E9' in column '1' is outside valid range for the datatype INTEGER

心想,这真就碰上了主键用完的情况?话说int类型的数据范围如下表,出问题的表主键使用的类型是int,约么21亿的数据,无符号整型更是高达41亿的数据,我们的业务都这么大量级了?

类型名称字节值范围
int4-2,147,483,648 到2,147,483,647
unsigned int40 到4,294,967,295

查看表结构,分明是bigint呀,咋还能超长了呢? 再看逻辑,好家伙!insert之后会给返回对象的id赋值,但是mybatis的mapper.xml代码映射时id的类型写的是integer,因此会抛出异常。

关键修复动作:评估风险后,直接新建一张表,rename表,先保证线上可用,随后再处理影响数据。

惊心动魄后...

不论结果怎样,复盘还是要复盘的。

1、为什么代码映射类型跟数据库类型不一致?

这张表是之前改的,只关注了逻辑处理,没有仔细检查这里。

再往深问,也只能这么回答了,是真的没有仔细审核,测试流程也通过了,提交pr也有人帮check,就...(长叹)

2、这么大的数据量,没有分库分表吗?

其实,这张表就是分库分表改造时加的关系表,哎...

2.1 为什么要分库分表

首先,如果数据库的业务数据量变大的情况下,数据库很容易出现性能瓶颈,诸如:慢sql变多,请求被阻塞,无法存储等等。无论是对于上述系统的读写性能瓶颈,还是我们日常的维护都是一件极为困难的事情。此时,对数据库表进行拆分是一种极为有效的方法。

分库 :分库可以降低单个集群的负载压力,提升整体的读写性能。

分表 :分表可以提高数据操作的效率,尤其是提高读效率。

2.2 什么时候要进行分库分表

《阿里巴巴Java 开发手册》中有提出:单表行数超过500万行或者单表容量超过2GB时,推荐进行分库分表。实际上,分库分表可以根据MySQL配置以及机器硬件来考虑,结合实际需求,在业务初期倒也不必过度设计。

2.3 分库分表怎么做?

这块内容较多,单说吧。

展望未来

好好学习,抓紧跑路🏃