MySQL5.5加主键锁读问题—续

背景

       上一篇说到MySQL 5.5加主键导致阻塞源表的读的问题。

有同学提到从调用函数看,在默认的old_alter_table=off的情况下,加主键过程没有看到copy to tmp table。

         这里我们再细说一下。

 

说说fast index creation

         在MySQL 5.1以后InnoDB引入了fast index creation。在有这个feature之前,MySQL认为所有的加减索引操作都必须创建临时表、拷贝数据、删除源表。

         有了这个神奇的功能之后,InnoDB跟MySQL说,稍等,要是加索引,不要你拷贝数据了,“放着我来”。怎么作的呢?

1)       扫描源表,将每行中用于索引的字段取出来

2)       排序构造新索引

3)       插入源表中

这个就是我们说的inplace-DDL了,大家看到,没有拷贝新表的操作。性能因此也提高了。这个过程叫做row_merge_build_indexes。

 

再说说加主键

         对于InnoDB来说,数据也是以索引组织的,因此加主键,在概念上说,也是加索引。于是在old_alter_table=off的情况下,MySQL照着上面的约定,调用row_merge_build_indexes。

         由于在5.5,MySQL认为InnoDB还是inplace操作,因此锁策略就如同上一篇处理。

 

         那么InnoDB是不是在源表加主键呢?

         这显然不可能。

         Fast-index-creation的精髓是只需要读主键数据,生成新索引插入到源表中。若加的是主键,说明原来没有定义主键(多么正确的废话),这时候InnoDB是使用系统分配的row_id作为主键。当我们增加主键以后,不可能“构造主键,插入源表”----那样就俩主键了。。。

 

源码实现

         实际上row_merge_build_indexes有两个参数(old_table, new_table)。 若新增的索引中不包含主键,则new_table == old_tablie,否则不等。

         对于不等的情况,这个过程就变成

1)       扫描old_table主键上的数据

2)       按照新增的索引插入到new_table中

3)       而由于“主键”索引的叶子节点,实际上是包含所有数据,所以这个过程,其实就是copy table。

 

对于new_table!=old_table的情况,在拷贝数据期间只需要加共享锁即可,只是5.5下没有意识到这个问题而已。

时间: 2024-10-30 07:43:56

MySQL5.5加主键锁读问题—续的相关文章

MySQL5.5加主键锁读问题

  背景      有同学讨论到MySQL 5.5下给大表加主键时会锁住读的问题,怀疑与fast index creation有关,这里简单说明下.   对照现象          为了说明这个问题的原因,有兴趣的同学可以做对比实验.     1)  在给InnoDB表创建主键期间,会锁住该表上的读数据     2) 但是同样的表执行删除主键期间,不会锁住该表上的读操作 ----这说明与是否fast index creation无关,因为这两个操作在数据层面的行为应该是类似的,实际上,创建/删除

ssh框架中如何为oracle中对应的表创建hibernate序列,以达到新加主键自增的功能

问题描述 ssh框架中如何为oracle中对应的表创建hibernate序列,以达到新加主键自增的功能 解决方案 .hbm 文件 <id name="id" type="java.lang.String"> <column name="ID" length="32" /> <generator class="uuid.hex" /> </id>策略不一样<

MySQL主键设计

原文:MySQL主键设计 [TOC] 在项目过程中遇到一个看似极为基础的问题,但是在深入思考后还是引出了不少问题,觉得有必要把这一学习过程进行记录. MySQL主键设计原则 MySQL主键应当是对用户没有意义的. MySQL主键应该是单列的,以便提高连接和筛选操作的效率 永远也不要更新MySQL主键 MySQL主键不应包含动态变化的数据,如时间戳.创建时间列.修改时间列等 MySQL主键应当有计算机自动生成. 主键设计的常用方案 自增ID 优点: 1.数据库自动编号,速度快,而且是增量增长,聚集

sql server-sqlserver建表时主键忘加一属性

问题描述 sqlserver建表时主键忘加一属性 现在想修改但是有其他表的外键关联了,请问怎么办,新手求助~~ 解决方案 先取消关联,再修改,再加上就是了. 解决方案二: 对,值没有改变,所以可以先取消,然后加上主键后,在关联没问题 解决方案三: 取消关联,修改属性,添加关联

Oracle 数据库针对表主键列并发导致行级锁简单演示_oracle

本文内容 •软件环境 •简单演示 Oracle 数据库并发导致行级锁 本文简单演示针对表主键并发导致的行级锁.并发是两个以上的用户对同样的数据进行修改(包括插入.删除和修改).锁的产生是因为并发.没有并发,就没有锁.并发的产生是因为系统需要,系统需要是因为用户需要. 软件环境 -------------------------------------------------------------------------------- •Windows 2003 Server •Oracle 1

[MySQL5.7] Innodb的索引锁优化

背景: . 这是一个臭名昭彰的问题,Innodb的btree发生合并/分裂等可能修改B-tree的操作时,都需要对其加排他的索引锁,这时候是无法对该索引进行读写操作的,极大的影响了性能:关于index lock,可以看看大神Domas的这篇博文:"Innodb locking makes me sad"  以及Vadim的这篇博客  . 总而言之,MySQL5.7.2的这个功能点的改进是万众期待的!  . 以下是阅读Rev6232的笔记,大概理了下关于索引锁优化的几个点.有些只是自己的

Hibernate主键生成方式 Key Generator

Hibernate主键生成方式 Key Generator 主键产生器 可选项说明: 1) assigned 主键由外部程序负责生成,无需Hibernate参与. 2) hilo 通过hi/lo 算法实现的主键生成机制,需要额外的数据库表保存主键生成历史状态. 3) seqhilo 与hilo 类似,通过hi/lo 算法实现的主键生成机制,只是主键历史状态保存在Sequence中,适用于支持Sequence的数据库,如Oracle. 4) increment 主键按数值顺序递增.此方式的实现机制

Redis的缓存策略和主键失效机制

作为缓存系统都要定期清理无效数据,就需要一个主键失效和淘汰策略. >>EXPIRE主键失效机制 在Redis当中,有生存期的key被称为volatile, 在创建缓存时,要为给定的key设置生存期,当key过期的时候(生存期为0),它可能会被删除. (1)影响生存时间的一些操作 生存时间可以通过使用 DEL 命令来删除整个 key 来移除,或者被 SET 和 GETSET 命令覆盖原来的数据, 也就是说,修改key对应的value和使用另外相同的key和value来覆盖以后,当前数据的生存时间

Hibernate(5)—— 联合主键 、一对一关联关系映射(xml和注解) 和 领域驱动设计

俗话说,自己写的代码,6个月后也是别人的代码--复习!复习!复习!涉及的知识点总结如下: One to One 映射关系 一对一单向外键(XML/Annotation) 一对一双向外键关联(XML/Annotation) 联合主键 一对一单向外键联合主键(Xml/Annotation) 一对一组件关联(XML/Annotation) 理解组件 领域驱动设计--自动生成数据库脚本 一对一关系的小结 一些出错问题的总结   自动生成数据库脚本 一般在项目开发过程中,我们的习惯是先建好数据库和表,然后