zijing2333...大约 5 分钟

MySQL的全局锁有什么作用?了解

作用:让整个数据库就处于只读状态了,增删改会被阻塞。

使用场景:全局锁主要应用于做全库逻辑备份,不会因为数据或表结构的更新而出现备份文件的数据与预期的不一样。

缺陷:数据库里有很多数据,备份会花费很多的时间。备份期间,业务只能读数据,而不能更新数据,这样会造成业务停滞。

改进:可重复读的隔离级别,在备份数据库之前先开启事务,会先创建 Read View,然后整个事务执行期间都在用这个 Read View,而且由于 MVCC 的支持,备份期间业务依然可以对数据进行更新操作。即使其他事务更新了表的数据,也不会影响备份数据库时的 Read View,这样备份期间备份的数据一直是在开启事务时的数据。

MySQL的表级锁有哪些?作用是什么?掌握

元数据锁

作用:对数据库表进行操作时,会自动给这个表加上元数据锁,为了保证当用户对表执行 CRUD 操作时,其他线程对这个表结构做了变更。元数据锁在事务提交后才会释放。

意向锁

作用:对某些记录加上「共享锁」之前,需要先在表级别加上一个「意向共享锁」,对某些纪录加上「独占锁」之前,需要先在表级别加上一个「意向独占锁」。普通的 select 是不会加行级锁的,普通的 select 语句是利用 MVCC 实现一致性读,是无锁的。

意向共享锁和意向独占锁是表级锁,不会和行级的共享锁和独占锁发生冲突,意向锁之间也不会发生冲突,只会和共享表锁和独占表锁发生冲突。意向锁的目的是为了快速判断表里是否有记录被加锁。

提示

select也是可以对记录加共享锁和独占锁的。

AUTO-INC锁

作用:表里的主键通常都会设置成自增的,之后可以在插入数据时,可以不指定主键的值,数据库会自动给主键赋值递增的值通过 AUTO-INC 锁实现的。在插入数据时,会加一个表级别的 AUTO-INC 锁,然后为被 AUTO_INCREMENT 修饰的字段赋值递增的值,等插入语句执行完成后,才会把 AUTO-INC 锁释放掉。其他事务的如果要向该表插入语句都会被阻塞,从而保证插入数据时字段的值是连续递增的。

缺陷:对大量数据进行插入的时候,会影响插入性能,因为其他事务中的插入会被阻塞。

改进:InnoDB 存储引擎提供了一种轻量级的锁来实现自增。在插入数据的时候,会为被 AUTO_INCREMENT 修饰的字段加上轻量级锁,然后给该字段赋值一个自增的值,就把这个轻量级锁释放了,而不需要等待整个插入语句执行完后才释放锁

AUTO-INC锁控制

设置innodb_autoinc_lock_mode的系统变量,是用来控制选择用 AUTO-INC 锁。:

  • 当 innodb_autoinc_lock_mode = 0,采用 AUTO-INC 锁,语句执行结束后才释放锁;
  • 当 innodb_autoinc_lock_mode = 2,采用轻量级锁,申请自增主键后就释放锁,并不需要等语句执行后才释放。
  • 当 innodb_autoinc_lock_mode = 1:
    • 普通 insert 语句,自增锁在申请之后就马上释放;
    • 类似 insert … select 这样的批量插入数据的语句,自增锁要等语句结束后才被释放;

当 innodb_autoinc_lock_mode = 2 是性能最高的方式,但是当搭配 binlog 的日志格式是 statement 一起使用的时候,在主从复制的场景中会发生数据不一致的问题

binlog 日志格式要设置为 row,这样在 binlog 里面记录的是主库分配的自增值,到备库执行的时候,主库的自增值是什么,从库的自增值就是什么。

所以,当 innodb_autoinc_lock_mode = 2 时,并且 binlog_format = row,既能提升并发性,又不会出现数据一致性问题

MySQL的行级锁有哪些?作用是什么?重要

记录锁

作用:锁住的是一条记录,记录锁分为排他锁和共享锁。

间隙锁

作用:只存在于可重复读隔离级别,目的是为了解决可重复读隔离级别下幻读的现象。间隙锁之间是兼容的,两个事务可以同时持有包含共同间隙范围的间隙锁,并不存在互斥关系

Next-Key Lock:Next-Key Lock临键锁,是 Record Lock + Gap Lock 的组合,锁定一个范围,并且锁定记录本身。next-key lock 即能保护该记录,又能阻止其他事务将新纪录插入到被保护记录前面的间隙中。

插入意向锁:一个事务在插入一条记录的时候,需要判断插入位置是否已被其他事务加了间隙锁(next-key lock 也包含间隙锁)。如果有的话,插入操作就会发生阻塞,直到拥有间隙锁的那个事务提交为止,在此期间会生成一个插入意向锁,表明有事务想在某个区间插入新记录,但是现在处于等待状态。

MySQL怎么加锁的?了解

当查询的记录是存在的,在用「唯一索引进行等值查询」时,next-key lock 会退化成「记录锁」。

当查询的记录是不存在的,在用「唯一索引进行等值查询」时,next-key lock 会退化成「间隙锁」。

当查询的记录存在时,用非唯一索引进行等值查询除了会加 next-key lock 外,还额外加间隙锁。

当查询的记录不存在时,用非唯一索引进行等值查询只会加 next-key lock,然后会退化为间隙锁。

非唯一索引范围查,next-key lock 不会退化为间隙锁和记录锁。

你认为这篇文章怎么样?
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.14.8