InnoDB中没有主键是如何运转的
本文章翻译自 https://blog.jcole.us/2013/05/02/how-does-innodb-behave-without-a-primary-key/
原文作者的创作背景
一个下午,好基友(Arjen Lentz)和“我”讨论InnoDB在没有声明主键时候的是如何运作的,这个话题足够有趣并且又没有足够多的文档去说明。
InnoDB聚簇索引的背景
在InnoDB索引页的物理结构中,“我”讲述了”InnoDB中一切都是索引“。这意味着每个InnoDB引擎的表必须有一个“聚簇索引”,通常是主键。在手册中聚簇索引和第二索引有说:
如果表中没有主键或者一个合适的的唯一索引,InnoDB内部会以一个包含行ID值的合成列生成一个隐藏的聚簇索引。表中的行是按照InnoDB分配的ID排序的。行ID是一个6字节的字段,随着一个新行的插入单调增加。因此,行ID顺序物理上是插入顺序。
“我”之前假设过这就意味着一个不可见的列将会和自增的实现 使用相同的序列生成代码(它自身也有一些拓展性问题)。然而事实上它们是完全不同的实现方式。
隐式行ID的实现方式
如手册所说,事实上是这么实现的:如果一个表没有申明主键和一个不为null的唯一索引,InnoDB将会自动增加一个6字节(48位)的整数列,被叫做行ID,聚集数据都是依靠这列的。这列既不能通过任何查询获取到也不能做像基于行复制的任何内部操作。
手册上没提及的是:所有的表将使用行ID列共享相同的全局计数序列(手册上说“单调增长”并且没有阐明),这是数据字典的一部分。所有行ID可用的最大值(技术上讲,下一个被用到的ID)被储存于系统表空间,在第七页(type SYS),在数据字典的头部(DICT_HDR_ROW_ID字段)。
这个全局的计数权重被dict_sys->mutex保护,甚至是递增(与使用原子增量相反)。 在include / dict0boot.ic处实现(删除了很多空行):
38 UNIV_INLINE
39 row_id_t
40 dict_sys_get_new_row_id(void)
41 /*=========================*/
42 {
43 row_id_t id;
44
45 mutex_enter(&(dict_sys->mutex));
47 id = dict_sys->row_id;
49 if (0 == (id % DICT_HDR_ROW_ID_WRITE_MARGIN)) {
51 dict_hdr_flush_row_id();
52 }
54 dict_sys->row_id++;
56 mutex_exit(&(dict_sys->mutex));
57
58 return(id);
59 }
(你可能也注意到这段代码缺乏对分配给行ID超出的48位的保护。这是不必要草率的编程,但是甚至每秒连续插入1百万(可能有点乐观),也要9年才能耗尽ID空间。“我”猜也是没事的)
确保生成不冲突的ID
计数器每生成256个ID被刷新(以上定义的DICT_HDR_ROW_ID_WRITE_MARGIN),可以修改记录于事务日志的系统数据字典页的值。在启动时,InnoDB将会增加存储于硬盘的DICT_HDR_ROW_ID,至少256,至多511。这样确保生成的任何ID都将小于新的起始值,因此将不会有冲突。
性能和资源冲突的影响
InnoDB中一些其他代码是被dict_sys->mutex保护的,“我”认为任何使用隐式聚簇索引(行ID)的表可以预料到在删(不关联)的表期间经历随机插入的停顿。形成对比地,隐式索引插入到多个表可能会有性能约束,因为将会在共享互斥锁和共享计数变量的缓存争用时序列化。另外,不管事务是否已经提交了(或者未提交),每256个生成的值将会导致系统页修改的写日志和刷新。
InnoDB中没有主键是如何运转的的更多相关文章
- InnoDB一定会在索引中加上主键吗
InnoDB一定会在索引中加上主键吗 http://www.penglixun.com/tech/database/will_innodb_store_pk_in_index.html
- Transactional Replication2:在Subscriber中,主键列是只读的
在使用Transactional Replication时,Subscriber 被认为是“Read-Only”的 , All data at the Subscriber is “read-only ...
- 深入理解Redis中的主键失效及其实现机制
参考:http://blog.sina.com.cn/s/articlelist_1221155353_0_1.html 作为一种定期清理无效数据的重要机制,主键失效存在于大多数缓存系统中,Reids ...
- MySQL中的主键,外键有什么作用详解
MySQL中的主键,外键有什么作用详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 学关系型数据库的同学,尤其在学习主键和外键时会产生一定的困惑.那么今天我们就把这个困惑连根拔起 ...
- 分布式系统中我们会对一些数据量大的业务进行分拆,分布式系统中唯一主键ID的生成问题
分布式全局唯一ID生成策略 https://www.cnblogs.com/vandusty/p/11462585.html 一.背景 分布式系统中我们会对一些数据量大的业务进行分拆,如:用户表,订 ...
- MySQL中的主键约束和外键约束
1.主键约束 表通常具有包含唯一标识表中每一行的值的一列或一组列. 这样的一列或多列称为表的主键 (PK),用于强制表的实体完整性. 由于主键约束可保证数据的唯一性,因此经常对标识列定义这种约束. 如 ...
- InnoDB一定会在索引中加上主键吗?
先回答问题,是的. 故事, 如下图,今天查看慢sql发现同事在建索引的时候竟然包含了主键,第一感觉这种姿势不对. 我记得很多文章都说过二级索引会自动带上主键,为什么还有人这么操作,后来差了些资料,如下 ...
- INNODB自增主键的一些问题
背景: 自增长是一个很常见的数据属性,在MySQL中大家都很愿意让自增长属性的字段当一个主键.特别是InnoDB,因为InnoDB的聚集索引的特性,使用自增长属性的字段当主键性能更好,这里要说明下自增 ...
- INNODB自增主键的一些问题 vs mysql获得自增字段下一个值
今天发现 批量插入下,自增主键不连续了....... InnoDB AUTO_INCREMENT Lock Modes This section describes the behavior of A ...
随机推荐
- 容器下载的是centos8的镜像,scp出现packet_write_wait: Connection to **** port 22: Broken pipe 问题解决
解决方案:在~/.ssh目录新建文件config vi ~/.ssh/config #Added lines to fix. Host * IPQoS lowdelay t ...
- IMU预积分
https://www.sohu.com/a/242760307_715754 http://www.sohu.com/a/243155537_715754 https://www.sohu.com/ ...
- 转:动态库路径配置- /etc/ld.so.conf文件
Linux 共享库 Linux 系统上有两类根本不同的 Linux 可执行程序.第一类是静态链接的可执行程序.静态可执行程序包含执行所需的所有函数 — 换句话说,它们是“完整的”.因为这一原因,静态可 ...
- The Preliminary Contest for ICPC Asia Nanjing 2019 D. Robots
题意:给出一个DAG,一只机器人从1点出发,等概率地选择一条出边走或者停留在原点,机器人的第k次行动消耗能量是k(无论是走还是停留都算一次行动).问1到n的期望. 解法:因为行动消耗的能量跟行动次数有 ...
- 【转载】将本地图片转成base64
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- linux-redis-install
安装redis3.2.9 wget cd make 编译完成后,将redis-cli redis-server redis-conf redis-benchmark配置文件复制到usr/redis文件 ...
- 04.join与interrupt
join加入 public class JoinDemo { public volatile static int i = 0; public static class AddThread exten ...
- leetcode-第14周双周赛-1273-删除树节点
题目描述: 自己的提交:动态规划 class Solution: def deleteTreeNodes(self, nodes: int, parent: List[int], value: Lis ...
- beautifhulsoup4的使用
Beautiful: - 基本使用 from bs4 import BeautifulSoup - 解析器: lxml, html.parser soup = Beautiful ...
- 最佳实践 | RDS & POLARDB归档到X-Pack Spark计算
X-Pack Spark服务通过外部计算资源的方式,为Redis.Cassandra.MongoDB.HBase.RDS存储服务提供复杂分析.流式处理及入库.机器学习的能力,从而更好的解决用户数据处理 ...