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 ...
随机推荐
- java并发编程之美-阅读记录5
java并发包中的并发List 5.1CopeOnWriteArrayList 并发包中的并发List只有CopyOnWriteArrayList,该类是一个线程安全的arraylist,对其进行的修 ...
- SQL数据库— <3>高级查询、常用函数 --摘录网络
SQL Server T-SQL高级查询 高级查询在数据库中用得是最频繁的,也是应用最广泛的. Ø 基本常用查询 --select select * from student; --all 查询所有 ...
- redis与mysql一致性方案解析
一 前言 首先,缓存由于其高并发和高性能的特性,已经在项目中被广泛使用.在读取缓存方面,大家没啥疑问,都是按照下图的流程来进行业务操作 但是在更新缓存方面,对于更新完数据库,是更新缓存呢,还是删除缓存 ...
- Codeforces 1188D Make Equal DP
题意:给你个序列,你可以给某个数加上2的幂次,问最少多少次可以让所有的数相等. 思路(官方题解):我们先给序列排序,假设bit(c)为c的二进制数中1的个数,假设所有的数最后都成为了x, 显然x &g ...
- 九、结构模式之装饰(Decorator)模式
装饰模式又叫包装模式,装饰模式以客户端透明的方式扩展对象的功能,是继承关系的一个替代方案.装饰模式可以在不使用创造更多的子类的情况下,将对象的功能加以扩展. 装饰模式结构图如下: 其包含的角色就分为: ...
- Git--将已有的项目添加到github(转)
转自:https://blog.csdn.net/north1989/article/details/53471439 1. 目标: 把本地已经存在的项目,推送到github服务端,实现共享. 2. ...
- css强制换行和超出部分隐藏实现
一.强制换行 1 word-break: break-all; 只对英文起作用,以字母作为换行依据. 2 word-wrap: break-word; 只对英文起作用,以单词作为换行依据. 3 whi ...
- Mybatis基于接口注解配置SQL映射器(一)
上文已经讲解了基于XML配置的SQL映射器,在XML配置的基础上MyBatis提供了简单的Java注解,使得我们可以不配置XML格式的Mapper文件,也能方便的编写简单的数据库操作代码. Mybat ...
- Linux系统之-文件系统,桌面环境
文件系统 文件类型普通文件,目录文件,连接文件,设备与设备文件,套接字,管道 普通文件(regular file):就是一般存取的文件,由ls -al显示出来的属性中,第一个属性为 [-],例如 [- ...
- ! Unknown property attribute "class"
当时是在用Xcode 7进行编译ASDK的代码发现报错了 当时就蒙圈了,@property(class)--这是啥呀,太久没看过object-c了,但是不至于@property是没有class属性的, ...