业务背景
目前有5百万用户,这些用户会定时更新一份数据到数据库里面,业务就是对用的数据分析,昨天数据,今天数据大概是这样子的用途
线上故障
突然发现有大量的用户数据,更新失败,或者是没有更新
故障结论
- 由于数据库的ID 使用使用自增值,到了 int 最大条数(21亿);
- SQL语句有使用忽略错误的语法,INSERT IGNORE INTO table_name (column1, column2, ...) VALUES (value1, value2, ...);
- 同时也有 mq有消息堆积
测试过程
测试环境和线上环境都运行了一段了时间,这段时间均为正常,数据有正常插入
总结
- 对数据库的类型要熟悉
- 对用户体量有了解
- 对故障错误定位排查
其实排查了很久,看异常的用户数据跟新到是哪一天的;
看业务逻辑是否有异常;
看日志记录;
看 SQL 去排查定位;
看 SQL的数据类型;
看 mq 消息;
INT数据类型
在MySQL中,INT
数据类型的大小是固定的,不依赖于它的显示长度。INT
类型总是占用4个字节(32位),并且有一个范围从 -2,147,483,648
到 2,147,483,647
。
假设你每天插入五百万条数据(5,000,000条),并且使用无符号的 INT
作为自增ID,那么理论上,你可以插入的数据条数就是 从0到4,294,967,295
我们只需用无符号INT
的最大值除以每天插入的数据条数。假设每天插入5,000,000条数据,那么理论上可以插入的天数就是:
4,294,967,295 / 5,000,000 ≈ 858.993459(约等于2年9个月)
这意味着,在不考虑其他因素(如数据删除、事务回滚、系统停机等)的情况下,理论上可以使用无符号INT
作为自增ID插入数据约2年9个月的时间。
假设int自增从0开始
要计算多少天后 INT
会占满?
多少天后占满,2,147,483,647
/ 5,000,000 = 429.4967294(大概1年2个月左右)
但需要注意的是,这里我们假设了每天插入的数据条数是固定的,实际上可能会有所波动。此外,还需要考虑其他因素,如事务回滚、数据删除等,这些都可能影响ID的使用情况。