MySQL表级锁

62 阅读2分钟

表级锁分类

  • 表锁
  • 元数据锁
  • 意向锁
  • AUTO-INC锁

表锁

// 读锁 共享锁
lock tables table_name read;

// 写锁 独占锁
lock tables table_name write;

// 释放表锁
unlock tables;

元数据锁(MDL)

是一种数据库执行事务时自动执行加上的锁,当对进行数据库操作时会自动加上MDL锁,MDL锁有两种类型:

  • CRUD操作时加上的MDL读锁
  • 更改表结构操作时加上的MDL写锁

特点:

  • 事务执行期间,MDL锁会一直持有
  • 写锁获取优先级高于读锁
  • 锁是存放在一个队列里面

意向锁

在加上锁之前加的意向锁,作用是快速找出表中那些需要被加锁的记录

分类:

  • 意向共享锁
  • 意向独占锁

特点:

  • 共享锁是表级锁,和行级别的锁不会发生冲突
  • 共享锁之间不会产生冲突
  • 只会和共享锁和独占锁发生冲突

如果没有意向锁,那么在加独占表锁时会遍历表里所有记录,查看是否有独占锁 如果有意向锁,由于在对记录加上独占锁时,首先会加上表级别的意向独占锁,那么在加独占表锁时,就不需要遍历所有记录去判断是否有独占锁了

AUTO-INC锁

作用是:在有自增主键的表中,插入记录不指定自增主键的值,数据库会自动赋值一个自增的值,只是AUTO-INC锁来实现的

有两种释放锁的方式:

  • 执行完插入语句后就释放锁
  • 对自增字段进行赋值完毕后就释放锁(轻量级锁)
AUTO-INC是一个特殊的锁,普通的锁一般是在事务提交后才进行释放

问题:如果出现大量的插入语句时,每条插入语句都会加上一个AUTO-INC锁,会出现性能方面问题,MySQL在MySQL 5.1.22 版本开始,InnoDB 存储引擎引入了轻量级锁。

MySQL中InnoDB引擎提供了一个系统变量: innodb_autoinc_lock_mode来控制三种不同的模式:

  • innodb_autoinc_lock_mode = 0 : 执行完插入语句时才释放AUTO-INC锁
  • innodb_autoinc_lock_mode = 1 :执行完插入语句时才释放AUTO-INC锁
    • 普通Insert语句 :自增锁在申请之后就马上释放(轻量级锁)
    • insert ... select 这样批量插入的语句 :自增锁还是要等语句结束后才被释放
  • innodb_autoinc_lock_mode = 2 : 采用轻量级锁,申请完自增主键后就释放锁