HelloCoder HelloCoder
首页
《Java小白求职之路》
《小白学Java》
计算机毕设
  • 一些免费计算机资源
  • 脚手架工具
  • 《从0到1学习Java多线程》
  • 《从0到1搭建服务器》
随笔
关于作者
首页
《Java小白求职之路》
《小白学Java》
计算机毕设
  • 一些免费计算机资源
  • 脚手架工具
  • 《从0到1学习Java多线程》
  • 《从0到1搭建服务器》
随笔
关于作者
  • 《LearnJavaToFindAJob》

    • 导读

    • 【初级】6~12k档

    • 【中级】12k-26k档

      • JVM进阶

      • Java进阶

      • MySQL

        • Innodb和MyISAM索引的区别
        • MySQL一些索引失效的场景和原理
        • MySQL如何行转列?
        • MySQL的架构和执行流程
        • MySQL的自增ID用完了会怎样?
        • MySQL索引的分类、何时使用、何时不使用、何时失效?
        • MySQL联合索引在B+数的存储结构和最左匹配原则原理
        • Mysql的索引和主键的区别
        • binlog、redolog、undolog的区别和作用
        • 什么是前缀索引,什么情况才使用?
        • 可重复读是否能解决幻读?
        • 我以为我对Mysql事务很熟,直到我遇到了阿里面试官
        • 聊聊MySQL索引的分类和结构吧
      • 中间件

      • 算法

      • 高阶

    • 【高级】26k+档

    • 大厂面试题

    • 求职建议

    • 面经

  • LearnJavaToFindAJob
  • 【中级】12k-26k档
  • MySQL
#MySQL #ID #自增
码农阿雨
2022-06-02
目录

MySQL的自增ID用完了会怎样?

我本人没有遇到这个问题,但是看到群里的小伙伴被问了,这也是个很有趣的问题,涉及MySQL的原理了,而且还是个坑,会牵涉很多问题。

面试官:MySQL的自增ID用完了会怎样?

小白:那插入应该有问题吧。

面试官:会报错吗?还是会覆盖其他列,还是会申请额外空间?

小白:应该会报错。

面试官:那你知道原理是什么吗?

小白:这个不清楚~

# 1、MySQL的自增ID用完了会怎样?

MySQL版本:8.0.13

既然想知道自增ID用完了会出现什么样的结果,那干脆来测试一下。

int占4个字节,如果是无符号那么它最大的范围是2^32-1 = 4,294,967,295,约43亿。

我这里使用int作为主键,建表,设置最大的自增ID:

CREATE TABLE test 
( 
	id INT UNSIGNED auto_increment PRIMARY KEY,
	name VARCHAR(20) NOT NULL DEFAULT ''

) auto_increment = 4294967295;

INSERT INTO test(`name`) VALUES ( "HaC" );

这个语句是插入成功的:

mysql> select * from test;
+------------+------+
| id         | name |
+------------+------+
| 4294967295 | HaC  |
+------------+------+
1 row in set (0.00 sec)

我们此时再插入一条语句 INSERT INTO test(name) VALUES ( "HelloCoder" );

mysql> INSERT INTO test(`name`) VALUES ( "HelloCoder" );
ERROR 1062 (23000): Duplicate entry '4294967295' for key 'PRIMARY'

以上结果说明,当再次插入时,使用的自增ID还是 4294967295,并不会再自增,报主键冲突的错误。所以说,MySQL的自增ID用完了,会导致插入直接报错。

原理就是设置的主键int的范围决定的。

# 2、达到最大值了怎么办?

相信你答出插入出错,面试官依然还会问:

面试官:假如刚开始选自增ID的时候,使用了int又恰好用完了,那应该怎么办?

小白:简单,使用alter语句修改就行了,换成更大的bigint就行了。

这样答也不是没有问题,但是其实还是跳入了另外一个坑。

bigint 占8个字节,2^64 -1 = 18446744073709551615 。

但是,你想想看,上千万上亿的数据,你一个:

ALTER TABLE test modify  COLUMN id BIGINT NOT NULL;

这得到猴年马月,IO不得等很久?服务器都要告警了。

面试官:alter修改大表没有什么注意事项吗?

小白:额....应该会锁表

Mysql在5.6版本之前,直接修改表结构的过程中会锁表,所以不能直接alter表;优选的方案的操作步骤如下:

  • (1)首先创建新的临时表,表结构通过命令ALTAR TABLE新定义的结构
  • (2)然后把原表中数据导入到临时表
  • (3)删除原表
  • (4)最后把临时表重命名为原来的表名

Mysql 5.6 虽然引入了Online DDL,在修改表结构的时候,增加ALGORITHM=INPLACE, LOCK=NONE,在运行 alter table 操作的同时允许运行 select,insert,update,delete语句。

ALTER TABLE tbl_name CHANGE c1 c1 BIGINT, ALGORITHM=COPY;

但是以下一些场景,仍然会锁表:

  • ①某个慢SQL或者比较大的结果集的SQL在运行,执行ALTER TABLE时将会导致锁表发生;

  • ②存在一个事务在操作表的时候,执行ALTER TABLE也会导致修改等待;

参考MySQL的Online DDL介绍: https://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl-operations.html#online-ddl-column-operations

这是我从上面MySQL官网截取的5.6版本对于Online DDL的支持:

所以如果你直接使用 ALTER 这样的语句在线修改表数据结构,还是会导致这张表无法进行更新类操作 ( DELETE、UPDATE、DELETE )。

这里有个问题也要注意一下,在执行DDL的时候,还是可以进行DML( DELETE、UPDATE、DELETE )操作的,因为DDL一旦开始了,就无法停止,MySQL会把DML语句缓存到有个buff里面

面试官:既然alter会锁表,那有什么办法可以解决吗?

小白:额...

列举一些建议:

  • online DDL前,最好确认一下当前数据库有没有类似table metadata lock存在
  • 查看一下有没有未提交的事务,查看事务nformation_schema.innodb_trx表
  • 以上两个问题,总结就是尽量选择流量小的时间点执行,这也是为什么深夜上线的原因。
  • 借助第三方工具,这些工具在DDL是可以不阻塞表,比如说pt-online-schema-change
  • 最好的方案还是主从切换来做,直接在从库上进行表结构修改,不会阻塞从库的读操作,改完之后,进行主从切换即可。

可以参考阿里的解决方案:https://help.aliyun.com/document_detail/94566.html

# 3、有遇到过ID用完的情况吗?

噼里啪啦前面都答出来.....

面试官:(小伙子还不错)

面试官:那,有遇到过ID用完的情况吗?

小白:额...

你想想看,既然这个表到达了索引上限,我算它一天插入 10w 条数据,那么就是 4294967295 / 100000 / 365 = 117 年才用完,再考虑一些删除、ID不连续,那也得好几十年才用完。

好吧,如果面试官非要杠假如一天就1百万、1千万条数据了。

那么就上bigint吧。

等等!

回到最开始的问题上,业务上一个表竟然可以达到几个亿,那说明B+树(Innodb)的查询效率已经很慢了,那为什么不分库分表呢?

小白:没听清,你再问我一遍

面试官:有遇到过ID用完的情况吗?

小白:没遇到过,即使是用int类型的主键,但是我们在ID达到最大值之前,就分库分表了。

面试官:.....好吧,那分库分表分哪几种,如何分?

欲知下事,且听下回:对分库分表的理解,为什么要分库分表?

阅读全文
×

(为防止恶意爬虫)
扫码或搜索:HelloCoder
发送:290992
即可永久解锁本站全部文章

解锁
#MySQL#ID#自增
上次更新: 2025-02-21 06:04:57
最近更新
01
《LeetCode 101》
02-21
02
IDEA、Golang、Pycharm破解安装
02-21
03
《LeetCode CookBook》
02-21
更多文章>
Theme by Vdoing | Copyright © 2020-2025 码农阿雨
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式