美文网首页
MySQL 锁之二——表锁

MySQL 锁之二——表锁

作者: smartmhs | 来源:发表于2019-10-13 12:33 被阅读0次

1、概述

MySQL 表级锁是以单个表为粒度的锁,InnoDB 和 MyISAM 引擎都支持表级锁;

2、表锁分类及原理

2.1 表级共享锁和表级排它锁

加锁方式:lock tables … read/write;
解锁方式:可以使用 unlock table; 主动解锁,也可以等客户端断开连接时自动释放;
兼容性:
共享锁可以兼容其他共享锁,但不兼容排它锁,排它锁则不兼容任何锁;
注意:
lock tables 语法除了会限制别的线程的读写外,也限定了本线程的操作对象;
举例说明:如果在某个线程 A 中执行 lock table t1 read, t2 write; 这个语句,则其他线程写 t1、读写 t2 的语句都会被阻塞。同时,线程 A 在执行 unlock tables 之前,也只能执行读 t1、读写 t2 的操作。连写 t1 都不允许,自然也不能访问其他表;

2.2 意向共享锁和意向排它锁

意向锁是用来解决表级锁和行级锁的共存问题的,那么它如何做到呢?

例如:事务 A 在表的某一行中加了记录锁,事务 B 想在该表上添加表级排它锁,这时,事务 B 想要知道是否可以添加表级排它锁,就要做全表扫描,看是否有记录上有记录锁,这样效率极其低下,基本不可用,这时就需要意向锁来解决该问题;

有了意向锁之后,事务 A 在申请记录锁之前,数据库会自动先给事务 A 先申请表的意向排他锁,当事务 B 去申请表级排它锁时就会失败,因为表上有意向排他锁之后事务 B 申请表级排它锁时会被阻塞,这样事务 B 就避免了全表扫描操作了;

所以,总结一下意向锁的作用:
当一个事务在需要获取资源的锁定时,数据库会自动给该事务申请一个该表的意向锁,如果需要一个共享锁定,就申请一个意向共享锁,如果需要排他锁定,则申请一个意向排他锁,这样其他事务再来申请资源的时候,就不用扫描全表来判断是否有冲突了;

2.3 自增锁

自增锁是一种专门针对 AUTO_INCREMENT 类型的列的锁,用来保证自增主键的顺序和唯一性,有几种模式可选,通过 innodb_autoinc_lock_mode 参数来设置模式,同一种模式对于不同的插入类型起到的作用会不同;

2.3.1 插入类型

Simple Insert(简单插入):
插入的记录数以及内容都确认,语句包括:insert into values、replace;

Bulk Insert(批量插入):
插入的记录数不能马上确认,语句包括:INSERT ... SELECT、REPLACE ... SELECT、LOAD DATA;

Mixed-mode Insert(混合插入):
指插入的值中有部分 value 的 id 确认,另一部分则默认自增,如:

  • INSERT INTO t1 (c1,c2) VALUES (1,‘a‘), (NULL,‘b‘), (5,‘c‘), (NULL,‘d‘);
  • INSERT ... ON DUPLICATE KEY UPDATE;
2.3.2 自增模式

innodb_autoinc_lock_mode = 0
优点:极其安全;
缺点:写入性能差,任何一种 Insert 语句,都会产生一个自增锁,即:所有的插入语句都串行执行;

innodb_autoinc_lock_mode = 1
优点:非常安全,对于 “innodb_autoinc_lock_mode = 0”,性能要好很多;
缺点:依然会产生自增锁;
运行原理:

  • 当发生 Bulk Inserts 时,会产生一个特殊的自增锁直到语句结束,注意:(这里是语句结束就释放锁,并不是事务结束哦,因为一个事务可能包含很多语句),对于 Simple Inserts,则使用的是一种轻量级锁,只要获取了相应的自增 key 就释放锁,并不会等到语句结束;
  • 当有自增锁时,这种轻量级的锁也不会加锁成功,会等待;

思考:这里的自增锁起到什么作用呢?
他能保证 Bulk Insert 自增 id 的连续性,防止在 Bulk Insert 的时候,被其他的插入语句抢走自增值;

innodb_autoinc_lock_mode = 2
优点:性能最好;
缺点:Bulk Insert 时可能得到不连续的自增 id,SBR 模式下,会导致复制出错;
原理:当进行 Bulk Insert 的时候,不会产生自增锁,因为它是允许其他插入语句同时进行插入,来一个记录,插入分配一个自增值,不会预分配;

2.4 MDL 读锁和 MDL 写锁

MDL 锁也叫元数据锁,不需要显示添加,是在访问表的时候自动添加,若在表上做增删改查,则添加 MDL 读锁,若对表结构进行变更,则添加 MDL 写锁;

读锁之间不互斥,读写锁、写锁之间互斥;

3、总结

  • InnoDB 和 MySIAM 都支持表级锁;
  • 表级共享锁和表级排它锁可以主动加锁解锁,其他表级锁都不需要主动操作;
  • 意向锁解决了表级锁和行级锁共存的问题;
  • 自增锁有三种模式可选,我们可根据业务需要灵活配置;
  • MDL 锁只在修改表结构的时候起作用;

4、参考资料

5、遗留问题

MySQL 的 SBR 模式是什么,如何工作,有什么优缺点?

相关文章

  • MySQL锁篇

    1 MySQL锁介绍 2 MySQL表级锁 2.1 表级锁介绍 ​ 表级锁由SQL layer实现。M...

  • MySQL 锁之二——表锁

    1、概述 MySQL 表级锁是以单个表为粒度的锁,InnoDB 和 MyISAM 引擎都支持表级锁; 2、表锁分类...

  • MySQL的锁机制

    mysql的锁机制 1、MySQL锁的基本介绍 MyISAM:MySQL的表级锁有两种模式:表共享读锁(Table...

  • Mysql的锁

    MySql锁的分类 Mysql里的锁大致可以分为全局锁、表级锁和行锁三类。 全局锁 Mysql 增加全局锁的方法:...

  • Mysql 锁详解

    Mysql 锁详解一、前言二、MyISAM2.1 MyISAM表锁2.2 查询表级锁争用情况2.3 MySQL表级...

  • 总结Mysql中的锁

    MySQL中的锁 概述 MyISAM支持表锁,InnoDB支持表锁和行锁,默认为行锁 表级锁:开销小,加锁快,不会...

  • MS汇总

    数据库相关[MS-关于锁(乐观锁,悲观锁,行锁、表锁,共享锁,排他锁)Mysql索引优化Mysql查询优化Mysq...

  • MySQL知识点

    Mysql中有哪几种锁? MyISAM支持表锁,InnoDB支持表锁和行锁,默认为行锁 表级锁:开销小,加锁快,不...

  • InnoDB引擎的行锁和表锁

    在Mysql中,Innodb数据引擎支持行锁和表锁,Myisam数据引擎只支持表锁 1 行锁和表锁 行锁是通过索引...

  • rails中乐观锁和悲观锁的使用

    MySQL乐观锁和悲观锁的介绍可以参考之前的一篇文章MySQL中的锁(行锁,表锁,乐观锁,悲观锁,共享锁,排他锁)...

网友评论

      本文标题:MySQL 锁之二——表锁

      本文链接:https://www.haomeiwen.com/subject/gycdrctx.html