Mysql自增ID用完了怎么办

表自增ID

  1. 如果主键是auto_incrment,如果达到了最大值,不会在增长,这时候写入会报主键冲突
  2. 如果没指定,会用dict_sys.row_id的值,作为主键,长度6字节,如果达到最大值会从0开始循环写入

所以,推荐这只auto_incrment,毕竟报主键冲突比覆盖以前的数据要好的多。

XID

mysql对应事物的ID,Mysql的内存中会维护一个golbal_query_id的变量,改变量在内存中重启会清0,每次执行语句会吧当前值赋值给Query_id,并且+1,
如果当前语句是事务中的一个语句那么会把这个Xid赋值给事物ID

Mysql在重启后由于会清零,同时会有一个新的binlog所以一个binlog中xid是不冲突的。但是如果执行时间过长,理论上也可能会冲突吗,因为XID到达最大值后会从0开始分配,只不过这个值太大了2E64-1,所以冲突只存在在理论中。

Innodb trxid

区别于XID,XID是Server层的trxId是innodb层的

innodb内部维护了个max_trx_id,每次申请时候会获取当前的max_trx_id,然后max_trx_id+1;

inndob的事务可见性核心思想是:每次更新都更新了数据的trx_id,当一个事务读到数据的时候判断一致性视图和当前trx_id的关系

对于正在执行的事物可以通过:information_schema.innodb_trx表中看到当前事务的trx_id;

注意trx_id的分配规则:

  1. 只读事物不分配trx_id,把当前事物的trx_id变量的指针地址转成int+2e48
    1. 这么做的好处是只读事物中,指针地址不会变,同一个只读事务在innodb_locks和innodb_trx查出来的trx_id是一致的;
    2. 不同的事务由于指针地址会变,查出来的trx_id一定是不同的
    3. 加上2e48也是能区别于读写事物
  2. 同时trx_id可能看到不只加了1:

    1. 因为update和delete操作也会+1,(标记删除,放到purge队列中)
    2. innodb的后台操作比如表的索引信息统计等都会+1

    只读事务不分配trx_id的好处

  3. 减少事务视图中活跃事务数,innodb在创建一致性视图时候值需要copy读写事物的trx_id就好了

  4. 可以减少trx_id的申请次数

    trx_id是被持久化不会清0的所以当到达最大值后,会从0开始,这时候就可能会出现脏读。因为后续的数据trx_id变小了,变成可见的了,但是因为这个值是2e48-1所以这个错误也只存在于理论上。(50万TPS,要跑17.8年)

thread_id

mysql有个thread_id_counter每次分配完后+1,如果到达最大值后会从0开始,这时候会看到俩个一样的thread_id

不过mysql在分配时候有一个逻辑来处理这种情况

thread_ids是个唯一数组,添加失败后会一直循环(待验证)

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