(十六)分区表,自增id用完

35 分区表

对一个表进行n个分区后,对于引擎层来说,这是 n 个表;对于 Server 层来说,这是 1 个表。

  • 分区表的特点
  1. MySQL 在第一次打开分区表的时候,需要访问所有的分区;
  2. 在 server 层,认为这是同一张表,因此所有分区共用同一个 MDL 锁;(因此分区表,在做 DDL 的时候,影响会更大。)
  3. 在引擎层,认为这是不同的表,因此 MDL 锁之后的执行过程,会根据分区表规则,只访问必要的分区。
  • 分区表的应用场景
  1. 分区表的一个显而易见的优势是对业务透明,相对于用户分表来说,使用分区表的业务代码更简洁。
  2. 还有,分区表可以很方便的清理历史数据。如果一项业务跑的时间足够长,往往就会有根据时间删除历史数据的需求。这时候,按照时间分区的分区表,就可以直接通过 alter table t drop partition …这个语法删掉分区,从而删掉过期的历史数据。
  3. 这个 alter table t drop partition …操作是直接删除分区文件,效果跟 drop 普通表类似。与使用 delete 语句删除数据相比,优势是速度快、对系统影响小。
  • 分布表与分库分表

分区表和手工分表,一个是由 server 层来决定使用哪个分区,一个是由应用层代码来决定使用哪个分表。因此,从引擎层看,这两种方式也是没有差别的。

分区表,在做 DDL 的时候,影响会更大。如果你使用的是普通分表,那么当你在 truncate 一个分表的时候,肯定不会跟另外一个分表上的查询语句,出现 MDL 锁冲突。

如查询需要跨多个分区取数据,查询性能就会比较慢

用业务分表,对业务开发同学没有额外的复杂性,对 DBA 也更直观,自然是更好的。

因此应该优先使用手动分表

36 自增id用完怎么办

  • 主键自增id

表定义的自增值达到上限后的逻辑是:再申请下一个 id 时,得到的值保持不变。

自增id对于一个频繁插入删除数据的表来说,是可能会被用完的。因此在建表的时候你需要考察你的表是否有可能达到这个上限,如果有可能,就应该创建成 8 个字节的 bigint unsigned

  • 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 写入表中的值范围,是从 0 到 2^48-1;当 dict_sys.row_id=2^48时,如果再有插入数据的行为要来申请 row_id,拿到以后再取最后 6 个字节的话就是 0。

在 InnoDB 逻辑里,申请到 row_id=N 后,就将这行数据写入表中;如果表中已经存在 row_id=N 的行,新写入的行就会覆盖原有的行。因此可能导致数据丢失,所以在通常情况下,都应该给表添加主键。

  • Xid

redo log 和 binlog 相配合的时候,提到了它们有一个共同的字段叫作 Xid

MySQL 内部维护了一个全局变量 global_query_id,每次执行语句的时候将它赋值给 Query_id,然后给这个变量加 1。如果当前语句是这个事务执行的第一条语句,那么 MySQL 还会同时把 Query_id 赋值给这个事务的 Xid。

因为 global_query_id 定义的长度是 8 个字节,这个自增值的上限是 2^64
-1。不过,2^64这个值太大了,大到你可以认为这个可能性只会存在于理论上。

  • Innodb trx_id

Xid 和 InnoDB 的 trx_id 是两个容易混淆的概念。Xid 是由 server 层维护的。InnoDB 内部使用 Xid,就是为了能够在 InnoDB 事务和 server 之间做关联。但是,InnoDB 自己的 trx_id,是另外维护的。

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

InnoDB 数据可见性的核心思想是:每一行数据都记录了更新它的 trx_id,当一个事务读到一行数据的时候,判断这个数据是否可见的方法,就是通过事务的一致性视图与这行数据的 trx_id 做对比。(MVVC原理)

对于只读事务,InnoDB 并不会分配 trx_id,在执行修改类操作或在 select 语句后面加上 for update,才会分配trx_id。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值