关于MySQL建表对DML的影响

今天一位同学问到线上曾经碰到过连续建表,导致阻塞普通的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并不会被阻塞?

时间: 2024-10-31 21:57:15

关于MySQL建表对DML的影响的相关文章

总结MySQL建表、查询优化的一些实用小技巧

本篇文章是对MySQL建表以及查询优化的一些实用小技巧进行了详细的分析介绍,需要的朋友参考下   MySQL建表阶段是非常重要的一个环节,表结构的好坏.优劣直接影响着后续的管理维护,赶在明天上班前分享总结个人MySQL建表.MySQL查询优化积累的一些实用小技巧. 技巧一.数据表冗余记录添加时间与更新时间 我们用到的很多数据表大多情况下都会有表记录的"添加时间 (add_time)",我建议大家再新增一个记录"更新时间(update_time)"字段,在我的工作里需

总结MySQL建表、查询优化的一些实用小技巧_Mysql

MySQL建表阶段是非常重要的一个环节,表结构的好坏.优劣直接影响着后续的管理维护,赶在明天上班前分享总结个人MySQL建表.MySQL查询优化积累的一些实用小技巧. 技巧一.数据表冗余记录添加时间与更新时间 我们用到的很多数据表大多情况下都会有表记录的"添加时间(add_time)",我建议大家再新增一个记录"更新时间(update_time)"字段,在我的工作里需要为市场部.运营部等建立各种报表,而很多报表里的数据都是需要到大记录表里去查询的,如果直接查询大表的

Mysql建表与索引使用规范详解

本篇文章是对Mysql建表和索引使用规范进行了详细的分析介绍,需要的朋友参考下   一. MySQL建表,字段需设置为非空,需设置字段默认值. 二. MySQL建表,字段需NULL时,需设置字段默认值,默认值不为NULL. 三. MySQL建表,如果字段等价于外键,应在该字段加索引. 四. MySQL建表,不同表之间的相同属性值的字段,列类型,类型长度,是否非空,是否默认值,需保持一致,否则无法正确使用索引进行关联对比. 五. MySQL使用时,一条SQL语句只能使用一个表的一个索引.所有的字段

mysql建表unknown storage engine innodb

问题描述 mysql建表unknown storage engine innodb 建表的时候出现的问题,网上百度了一下给出的方法都没有解决. 解决方案

mysql-操作MYSQL建表时不能保存,id也不能选择自动递增

问题描述 操作MYSQL建表时不能保存,id也不能选择自动递增 急,在线等o(╯□╰)o,截图没有设置长度,其实设置了也是一样的问题,所以这个排除了 解决方案 你用的是mysql图形界面客户端软件是什么呢?我用的是SQLYog客户端,是有自增选项的. 解决方案二: 数据表定义有问题吧,不是提示说length没设置吗

Mysql建表与索引使用规范详解_Mysql

一. MySQL建表,字段需设置为非空,需设置字段默认值.二. MySQL建表,字段需NULL时,需设置字段默认值,默认值不为NULL.三. MySQL建表,如果字段等价于外键,应在该字段加索引.四. MySQL建表,不同表之间的相同属性值的字段,列类型,类型长度,是否非空,是否默认值,需保持一致,否则无法正确使用索引进行关联对比.五. MySQL使用时,一条SQL语句只能使用一个表的一个索引.所有的字段类型都可以索引,多列索引的属性最多15个.六. 如果可以在多个索引中进行选择,MySQL通常

1.5 MySql建表

create table [模式名]表名 ( # 列定义 ) 例:向study数据库中插入表person CREATE TABLE IF NOT EXISTS study.person (     id INT(11)NOTNULL AUTO_INCREMENT,     username VARCHAR(20)NOTNULL,     age INT,     grade DOUBLE,     addTime DATE,     PRIMARYKEY(id) ) ENGINE = MyISA

MySQL 建表的优化策略 小结_Mysql

目录 1. 字符集的选择 1 2. 主键 1 3. 外键 2 4. 索引 2 4.1. 以下情况适合于创建索引 2 4.2. 以下的情况下不适合创建索引 3 4.3. 联合索引 3 4.4. 索引长度 4 5. 特殊字段 4 5.1. 冗余字段 4 5.2. 分割字段 4 5.3. BLOB和CLOB 5 6. 特殊 5 6.1. 表格分割 5 6.2. 使用非事务表类型 5 1. 字符集的选择 如果确认全部是中文,不会使用多语言以及中文无法表示的字符,那么GBK是首选. 采用UTF-8编码会占

MySQL 建表语句

问题描述 CREATETABLEorder(IDintauto_increment,CODEchar(15)notnull,DATE_TIMEdatetimenotnull,RECEIVERvarchar(10)notnull,TELvarchar(13)notnull,CARDvarchar(20)notnull,EMAILvarchar(20),ADDRESSVARCHAR(80)notnull,constraintT_ORDER_FKprimarykey(ID));我是个初学者,这个建表语