本文来自这里

今天一位同学问到线上曾经碰到过连续建表,导致阻塞普通的insert、update等。不过也没有保留现场。因此有疑问为什么建表会影响DML?

分析

         首先这个现象不是在所有场景都会碰到(否则MySQL的用户们早就跳起来了)。

一来建表这个操作本身很快,只涉及到写表定义文件和初始化表空间。中间涉及到redo和undo的操作也很少(这里只讨论InnoDB表)。因此除非碰到磁盘IO响应不了,否则多数情况下建表操作很快结束,不会“稳定复现”

二来即使由于io原因,建表过程执行时间较长,建表操作也不会阻塞一些DML操作。

因此只能从代码出发看冲突的case。

假设session 1正在执行一个create table操作,且由于io原因阻塞在写表空间文件这个步骤上。讨论session2作如下操作的场景。

无主键表insert

         此时insert操作由于需要申请系统自增主键,需要对dict_sys->mutex加锁。而这个锁需要等session1建表操作完成后才释放,因此出现等待。

有外键表的操作

         此时session2需要判断外键一致性,需要对dict_sys->mutex加锁。

这里包含几个方面:外键约束的child表插入数据时和parent表删除数据时,已经这两个表的关联外键字段被修改时,均会触发等待。

有同学会说我们线上这两种情况都禁止了,是不是就不会因为这个锁的原因导致阻塞dml?

新打开表时

         若这个insert操作需要新打开一个表时,需要根据表名从字典中取出信息,也会触发等待。

即使原来已经打开过的表,也会因为执行了flush table或者表空间淘汰而要求下次访问需要重新打开。

影响的其他操作

         顺着dict_sys->mutex我们还可以发现有以下几个操作,若发生在session2,都会被阻塞

1)                 1) Flush tables

2)                    select * from information_schema.tables;

2) 以上两个因为都要访问到表对象列表,还比较好理解

3)                 select * from information_schema.innodb_sys_tables;

3)实际上可以用另外一个锁来单独处理sys_tables

4)                  show create table another_table

这个是因为必须判断是否有外键关联

简单留个问题:为什么show tables并不会被阻塞?

关于MySQL建表对DML的影响【转】的更多相关文章

  1. 【记录】Mysql 建表注意事项

    博主最近打算搭建商城,由于之前对建表只有很浅显的理解,没有太过深入了解,建表过程中遇到一些问题,现记录如下, 如有问题请各位留言指正,感激不尽: 建表时设置如何设置联合主键?如下标红处: CREATE ...

  2. 基于表的数据字典构造MySQL建表语句

    表的数据字典格式如下: 如果手动写MySQL建表语句,确认麻烦,还不能保证书写一定正确. 写了个Perl脚本,可快速构造MySQL脚本语句. 脚本如下: #!/usr/bin/perl use str ...

  3. mysql建表出现Timestamp错误

    mysql建表时如果有两个或以上的字段为Timestamp,那么可能会出现如下错误: Incorrect table definition; there can be only one TIMESTA ...

  4. MySql 建表出现的问题:[ERR] 1064 - You have an error in your SQL syntax; check the manual.......

    使用 MySql 建表出现的问题 在使用 Navicat Premium 运行 sql 语句进行建表时,MySQL 报错如下: 建表语句: DROP DATABASE IF EXISTS javawe ...

  5. MySQL 建表语句 create table 中的列定义

    MySQL 建表语句 create table 中的列定义: column_definition: data_type [NOT NULL | NULL] [DEFAULT default_value ...

  6. 三种常用的MySQL建表语句

    MySQL建表语句是最基础的SQL语句之一,下面就为您介绍最常用的三种MySQL建表语句,如果您对MySQL建表语句方面感兴趣的话,不妨一看. 1.最简单的: CREATE TABLE t1(    ...

  7. 【转载】mysql建表date类型不能设置默认值

    如题,mysql建表date类型的不能设置一个默认值,比如我这样: CREATE TABLE `new_table` ( `biryhday` datetime NULL DEFAULT '1996- ...

  8. Mysql建表通用写法

    Mysql建表通用写法 CREATE TABLE IF NOT EXISTS stu( id ) PRIMARY KEY AUTO_INCREMENT,//主键 自增 stuname ) NOT NU ...

  9. MySQL建表DDL规范(欢迎补充)

    MySQL建表DDL规范(欢迎补充) 基本规范: 表名和字段名全大写,一般表名以T开头 脚本需支持可重复执行,带IF NOT EXISTS ,但不可带DROP语句 字符集使用utf8mb4 (CHAR ...

随机推荐

  1. ABAP数据转换规则

    数据转换规则: 可以将基本数据类型的源字段内容赋给其它基本数据类型的目标字段(除了数据类型 D 无法赋给数据类型 T,反之亦然).ABAP/4 也支持结构化数据和基本数据对象之间或结构不同的数据对象之 ...

  2. Ubuntu 16.04 server版本开机启动脚本不支持

    Ubuntu16.04开机启动的脚本一直不支持,错误用在将开机启动脚本放到了home/usr/的目录下,应该放到/root才能正常启动.#!/bin/sh -e ## rc.local## This ...

  3. 初识SeekBar

    SeekBar拖动条,是Progress的间接子类 <SeekBar android:id="@+id/seekBar1" android:layout_width=&quo ...

  4. Lucene-如何编写Lucene程序

    Lucene版本:7.1 使用Lucene的关键点 创建文档(Document),添加文件(Field),保存了原始数据信息: 把文档加入IndexWriter: 使用QueryParser.pars ...

  5. Easyui validatebox后台服务端验证

    Easyui validatebox的验证提示十分好用,可是在实际项目的运用中,经常会遇到需要服务器验证后并返回验证结果信息,比如验证用户名.手机号.邮箱是否已存在.于是就想着怎么拓展Easyui的验 ...

  6. MVC4学习之官方教程中迁移版本库报错

    因工作需要,学习MVC4,但是微软官方教程中迁移版本库步骤在本地测试报错 官方教程地址:http://www.asp.net/mvc/overview/older-versions/getting-s ...

  7. PostgreSQL缓存

    目录[-] pg_buffercache pgfincore pg_prewarm dstat Linux ftools 使用pg_prewarm预加载关系/索引: pgfincore 输出: 怎样刷 ...

  8. centos7-httpd服务器

    Apache WEB服务器入门简介: Apache HTTP Server是Apache软件基金会的一个开源的网页服务器,可以运行在几乎所有广泛使用的计算机平台上,由于其跨平台和安全性被广泛使用,是目 ...

  9. WINDOWS-基础:SafeArray的使用方法

    1 SafeArray的作用 使用SafeArray SafeArray是VB中的数组存储方式.通过SafeArray,可以在VC++和VB间相互调用. SafeArray也是Automation中的 ...

  10. Mac下快捷键的符号所对应的按键