【mysql45讲】自增主键用完怎么办&不同种类自增主键的区别

1.自增主键为什么会用完

因为计算机里数的大小是有上限的。

2.达到上限会出现什么情况

2.1 在表结构中定义的自增id

达到上限后,自增id不变,这就会造成错误。
因此,在建表的时候需要考察表是否有可能达到这个上限,如果有可能,就应该创建成 8 个字节的 bigint unsigned。

2.2 InnoDB 系统自增 row_id

如果你创建的 InnoDB 表没有指定主键,那么 InnoDB 会给你创建一个不可见的,长度为 6 个字节的 row_id。
InnoDB 维护了一个全局的 dict_sys.row_id 值,所有无主键的 InnoDB 表,每插入一行数据,都将当前的 dict_sys.row_id 值作为要插入数据的 row_id,然后把 dict_sys.row_id 的值加 1。
实际上,在代码实现时 row_id 是一个长度为 8 字节的无符号长整型 (bigint unsigned)。但是,InnoDB 在设计时,给 row_id 留的只是 6 个字节的长度,这样写到数据表中时只放了最后 6 个字节,所以 row_id 能写到数据表中的值,就有两个特征:row_id 写入表中的值范围,是从 0 到 2的48次方-1;当 dict_sys.row_id= 2的48次方时,如果再有插入数据的行为要来申请 row_id,拿到以后再取最后 6 个字节的话就是 0。也就是说,写入表的 row_id 是从 0 开始到 2的48次方-1。达到上限后,下一个值就是 0,然后继续循环。
当然, 2的48次方-1 这个值本身已经很大了,但是如果一个 MySQL 实例跑得足够久的话,还是可能达到这个上限的。在 InnoDB 逻辑里,申请到 row_id=N 后,就将这行数据写入表中;如果表中已经存在 row_id=N 的行,新写入的行就会覆盖原有的行。

2.3 redo log 和 binlog 共同的字段 【Xid】

Xid在 MySQL 中是用来对应事务的。 MySQL 内部维护了一个全局变量 global_query_id,每次执行语句的时候将它赋值给
Query_id,然后给这个变量加 1。如果当前语句是这个事务执行的第一条语句,那么 MySQL 还会同时把 Query_id
赋值给这个事务的 Xid。 而 global_query_id 是一个纯内存变量,重启之后就清零了。所以在同一个数据库实例中,不同事务的Xid 也是有可能相同的。

但是 MySQL 重启之后会重新生成新的 binlog 文件,这就保证了,同一个 binlog 文件里,Xid 一定是惟一的。虽然MySQL 重启不会导致同一个 binlog 里面出现两个相同的 Xid,但是如果 global_query_id 达到上限后,就会继续从0 开始计数。从理论上讲,还是就会出现同一个 binlog 里面出现相同 Xid 的场景。因为 global_query_id 定义的长度是8 个字节,这个自增值的上限是 2的64次方-1。要出现这种情况,必须是下面这样的过程:
1 执行一个事务,假设 Xid 是 A;
2 接下来执行2的64次方 次查询语句,让 global_query_id 回到 A;
3 再启动一个事务,这个事务的 Xid 也是 A。

2.4 线程thread_id

show processlist 里面的第一列,就是 thread_id。
thread_id的实现:系统保存了一个全局变量 thread_id_counter,每新建一个连接,就将 thread_id_counter 赋值给这个新连接的线程变量。
thread_id_counter 定义的大小是 4 个字节,因此达到 232-1 后,它就会重置为 0,然后继续增加。但是,你不会在 show processlist 里看到两个相同的 thread_id。

do	{
 		new_id=	thread_id_counter++;
 }	while	(!thread_ids.insert_unique(new_id).second);

// 这里没看懂

2.5 Innodb trx_id

Xid和InnoDB trx_id的区别

Xid 是由 server 层维护的。InnoDB 内部使用 Xid,就是为了能够在 InnoDB 事务和 server 之间做关联。但是,InnoDB 自己的 trx_id,是另外维护的。它就是事务 id(transaction id)。

实现

InnoDB 内部维护了一个 max_trx_id 全局变量,每次需要申请一个新的 trx_id 时,就获得 max_trx_id 的当前值,然后并将 max_trx_id 加 1。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值