背景

     有同学讨论到MySQL 5.5下给大表加主键时会锁住读的问题,怀疑与fast index creation有关,这里简单说明下。

对照现象

         为了说明这个问题的原因,有兴趣的同学可以做对比实验。

1)  在给InnoDB表创建主键期间,会锁住该表上的读数据

2) 但是同样的表执行删除主键期间,不会锁住该表上的读操作

—-这说明与是否fast index creation无关,因为这两个操作在数据层面的行为应该是类似的,实际上,创建/删除主键都必须copy data。

3) 在创建主键期间,会锁住该表上执行的show create table

—-用1、3的现象可以猜测出,实际上与meta data lock有关。

关于meta data lock(MDL)

         MySQL 5.5中引入了MDL,当需要访问、修改表结构时,都需要对meta data加锁(读或写)。比如,当一个线程需要修改表结构的任意一部分时,此时需要阻塞对表结构的访问,当然也需要阻塞对数据行的访问。

加主键流程

         当对一个表作加主键操作时,大致流程如下

1) MDL加写锁

2) 操作数据,最耗时部分,注意需要copy data,因此流程上是

a)创建一个临时表A,表A定义为修改后的表结构

b)从原表读取数据插入表A

c)删除原表,将表A重命名为原表名

3)  MDL释放写锁

从这个流程可以看到,在最耗时的部分,meta data是被一个X锁保护的。因此在此期间,show create table或者select data都是会被阻塞。

这解释了上面的1) 3)。

删除主键流程

1)  MDL加读锁

2)  操作数据,最耗时部分

a) 创建一个临时表A,表A定义为修改后的表结构

b) 从原表读取数据插入表A

3) MDL将读锁升级为写锁

c) 删除原表,将表A重命名为原表名

4)  MDL释放写锁

这个在最耗时的数据操作部分,加的是MDL的读锁,这样不会影响访问原表的表结构或数据(当然要做更新是不行的)。而最后升级为写锁的时间,只是做重命名表的操作,阻塞的时间就很短。

结论

1) 显然第二个流程更合理

2) 这个可以认为是MySQL一个可改进的点,并且在5.6下已经改进

3) 这个问题与是copy data还是inplace方式执行DDL无关,实际上由于InnoDB的聚集索引组织结构,增、删主键都是必须得copy data的。

=================================更新====================================

有同学问说为什么在5.5 set old_alter_table=on;之后是不会阻塞读的? 因为打开old_alter_table之后,MySQL认为这次无论如何是要copy data的,所以锁用的是“删除主键流程”的策略。

实际上无论old_alter_table是否打开,对主键操作都是必须copy data的,5.6的改进就是基于这个判断。

原文地址:

http://dinglin.iteye.com/blog/1884696

MySQL 5.5加主键锁读问题【转载】的更多相关文章

  1. MySQL为什么需要一个主键

    主键 表中每一行都应该有可以唯一标识自己的一列(或一组列). 一个顾客可以使用顾客编号列,而订单可以使用订单ID,雇员可以使用雇员ID 或 雇员社会保险号. 主键(primary key) 一列(或一 ...

  2. (转)MyBatis+MySQL 返回插入的主键ID

    MyBatis+MySQL 返回插入的主键ID 需求:使用MyBatis往MySQL数据库中插入一条记录后,需要返回该条记录的自增主键值. 方法:在mapper中指定keyProperty属性,示例如 ...

  3. mybatis+mysql返回插入的主键,参数只是提供部分参数

    mybatis+mysql返回插入的主键,参数只是提供部分参数 <insert id="insertByChannelIdOpenid" useGeneratedKeys=& ...

  4. JDBC 复习5 mysql 的自增长主键 auto_increment

    MySQL 自增长主键 (1)如果把一个NULL插入到一个AUTO_INCREMENT数据列里去,MySQL将自动生成下一个序列编号.编号从1开始,并1为基数递增. (2)把0插入AUTO_INCRE ...

  5. hibernate主键生成策略(转载)

    http://www.cnblogs.com/kakafra/archive/2012/09/16/2687569.html 1.assigned 主键由外部程序负责生成,在 save() 之前必须指 ...

  6. Mysql EF 触发器生成主键id 存储区更新、插入或删除语句影响到了意外的行数(0)。实体在加载后可能被修改或删除。刷新 ObjectStateManager 项 ;System.Data.Entity.Infrastructure.DbUpdateConcurrencyException

    http://stackoverflow.com/questions/24725261/how-to-use-a-custom-identity-column-in-sql-with-entity-f ...

  7. mysql生成varchar类型主键排序

    用uuid生成20位的主键 SELECT LEFT(REPLACE(UUID(), '-', ''),20) FROM DUAL 另一种方法: 因为数据库中有字母 需要排序的时候去除字母,重新取最大值 ...

  8. MySQL,Oracle建立主键自增表

    MySQL 在建表的时候声明字段即可 id int auto_increment primary key not null Oracle 第一步:建立表 drop table t_role; crea ...

  9. MyBatis+MySQL 返回插入的主键ID

    需求:使用MyBatis往MySQL数据库中插入一条记录后,需要返回该条记录的自增主键值. 方法:在mapper中指定keyProperty属性,示例如下: <insert id="i ...

随机推荐

  1. 嵌入式开发之hi3519---PCIE DMA

    http://blog.csdn.net/abcamus/article/details/76167747 大话pcie dma http://blog.csdn.net/qingfengtsing/ ...

  2. php memcached 扩展

    php_memcache.dll下载地址:http://windows.php.net/downloads/pecl/releases/memcache/3.0.8/ 查看php线程:phpinfo ...

  3. react如何监听路由url变化

    "componentWillReceiveProps" "shouldComponentUpdate" "componentWillUpdate&qu ...

  4. orcal数据库基本操作

    1.连接 SQL*Plus system/manager 2.显示当前连接用户 SQL> show user 3.查看系统拥有哪些用户 SQL> select * from all_use ...

  5. NLog类库的使用探索——认识配置+实习小感悟

    1 写在前面 1.1 为什么学了软件 1.高考失败,分数不高,不能随心所欲 2.农村孩子,学点技术,将来有口饭吃 3.有科技含量,想玩电脑(那个时候是这么想的,那个时候觉得学计算机就是玩电脑) 1.2 ...

  6. Jmeter-安装配置

    一.安装JDK 1 [步骤一]安装jdk 1.下载jdk,到官网下载jdk,地址:http://www.oracle.com/technetwork/java/javase/downloads/ind ...

  7. /usr/bin/ld: cannot find -lncurses是咋回事?

    你的系統是32位的還是64位的? 如果是32位的就用:sudo apt-get install libncurses5-dev 如果是64位的,就用:sudo apt-get install lib3 ...

  8. 【消灭代办】第1周 - 敏感词判断、图片206、parseInt

    11.16代办一:[敏感词判断] 代办描述: 一堆字符串组成的数组,给你一个字符串,让你去查找这个字符串是否在这个数组当中? 关键考点: 数组匹配,看一个数组中有没有这个字符串. 解决思路: 遍历数组 ...

  9. 图表统计FusionCharts

    工作中用的图形统计,用的FusionCharts,发现Chenssy总结了很详细了,特此记录一下.tks Chenssy. tks: http://www.cnblogs.com/chenssy/ar ...

  10. 【CF573D】Bear and Cavalry 线段树

    [CF573D]Bear and Cavalry 题意:有n个人和n匹马,第i个人对应第i匹马.第i个人能力值ai,第i匹马能力值bi,第i个人骑第j匹马的总能力值为ai*bj,整个军队的总能力值为$ ...