美文网首页
三、Mysql InnoDB锁

三、Mysql InnoDB锁

作者: 此间有道 | 来源:发表于2020-05-17 19:32 被阅读0次

Mysql有多种存储引擎,他们的锁机制也不尽相同。例如MyISAM不支持行锁只有表琐,所以本文主要讨论InnoDB引擎的锁机制。

一、前置问题

  1. 为什么要有锁?锁对性能影响大吗?
  2. 锁有几种逻辑分类?
  3. Innodb的锁是公平锁吗?
  4. 如何检测和避免死锁?Innodb会对死锁自动处理吗?
  5. 行锁是锁的什么?表琐是在哪一层实现的,服务器层还是存储引擎层?
  6. 表琐有几种?意向锁是什么?
  7. mysql有锁升级吗?什么是锁升级?

二、锁是维护数据一致性的必要条件

数据库在处理并发访问共享资源时,需要锁来保护资源数据的一致性。

三、锁分类

3.1 锁在层级上分为:1)服务器级别锁;2)存储引擎级别锁;

服务器锁:在mysql服务器层实现并发控制,会忽略存储引擎的锁;
存储引擎锁:在存储引擎层实现,锁的粒度一般比服务器层要更细;

3.2 锁从粒度上可分为:1)行锁;2)表琐;

两者都可以表现为共享性或排他性;

行锁

在存储引擎层实现;一般通过锁索引来实现;

表琐

1)Mysql服务器层;

LOCK TABLE t READ;
LOCK TABLE t WRITE;

2)InnoDB存储引擎也实现了一种表琐,意向锁(意向共享锁,意向排它锁);

select * from t where id < 3 lock in share mode;  // 表上加意向共享锁
select * from t where id < 3 lock for update;  // 表上加意向排它锁
update t set name = 'test' where id = 3; // 表上加意向排它锁
delete from t where id = 3;  // 表上加意向排它锁

意向锁是InnoDB在增加行锁时,同时在表上标记的一个信息。用于多个事务对表资源进行竞争获取锁时,避免去查看表中记录的行锁信息,提高了性能。
例如:事务A,执行语句update t set name = 'test' where id = 3;时会加两把锁:
a. 在id=3的索引上加行锁;
b. 在t表上增加意向排他锁:IX LOCK
此时,事务B要执行LOCK TABLE t READ;,需要在表上增加X锁。此时由于X,IX锁的不兼容,该事务被阻塞;

意向锁间兼容性

由于意向锁实际上是行锁的一种表级别的提示,他们都是要操作行,所以意向锁之间不会导致事务(在表级别)相互阻塞。如果是操作的相同行时通过行锁阻塞来实现并发控制。

IX IS
IX 兼容 兼容
IS 兼容 兼容
读写表琐兼容性
X S
X 不兼容 不兼容
S 不兼容 兼容
意向锁和读写锁的兼容性
X S
IX 不兼容 不兼容
IS 不兼容 兼容
3.3 锁在访问性上可分为:1)共享锁;2)排它锁

共享锁:也称为读锁,多个用户可以获取某资源的共享锁,互不阻塞;
排它锁:也称为写锁,多个用户尝试去获取排他锁时,只有一个会成功,其他的被阻塞;

四、死锁

在InnoDb中两个或多个事务并发访问多个资源时,双发都请求对方占用的资源时,会发生死锁。

死锁原因

多个事务以不同的顺序去锁定资源时,就可能会发生死锁。

如何避免死锁

以相同的顺序去请求资源,并且可以设置等待超时时间避免一直等待下去;

如何解决死锁

InnoDB引擎检测到死锁时,强制回滚其中的一方事务,解锁争抢资源;

五、锁升级

一般数据库把锁作为一种稀缺资源,当多个小粒度的锁开销较大时,会升级为一个粗粒度的锁来减小开销。类似java中的锁粗化;

举个栗子

1)Mysql中多个行锁升级为页锁,或页锁升级为表琐。
2)拿Java的锁粗化来举例:

public void doSomethingMethod(){
    synchronized(lock){
        //do some thing
    }
    //这是还有一些代码,做其它不需要同步的工作,但能很快执行完毕
    synchronized(lock){
        //do other thing
    }
}

会被优化为以下形式;

public void doSomethingMethod(){
    //进行锁粗化:整合成一次锁请求、同步、释放
    synchronized(lock){
        //do some thing
        //做其它不需要同步但能很快执行完的工作
        //do other thing
    }
}


InnoDB没有锁升级

在InnoDB中锁通过位图实现,开销是一致的,无需升级。

相关文章

  • 淘宝MySQL文档整理

    MySQL · 引擎特性 · InnoDB 事务锁系统简介 MySQL · 引擎特性 · Innodb 锁子系统浅...

  • Innodb的锁

    Innodb的锁是行级锁 mysql delete是否会锁表 MySQL的InnoDB存储引擎支持行级锁,Inno...

  • 三、Mysql InnoDB锁

    Mysql有多种存储引擎,他们的锁机制也不尽相同。例如MyISAM不支持行锁只有表琐,所以本文主要讨论InnoDB...

  • InnoDB引擎中查询锁的信息

    InnoDB中查询锁的信息主要基于三个查询语句 MySQL 5.7 MySQL 8.0 本文将分别基于 MySQL...

  • MySql InnoDB 锁机制

    MySQL InnoDB支持三种行锁定方式: l 行锁(Record Lock):锁直接加在索引记录上面,锁住...

  • mysql 排它锁之行锁、间隙锁、后码锁

    MySQL InnoDB支持三种行锁定 行锁(Record Lock):锁直接加在索引记录上面,锁住的是key。 ...

  • Mysql

    MySQL InnoDB中使用悲观锁 要使用悲观锁,我们必须关闭mysql数据库的自动提交属性,因为MySQL默认...

  • Mysql存储引擎Innodb小结

    innodb是mysql支持事务的存储引擎,也是当前mysql默认的存储引擎。innodb支持行级别锁,对并发性事...

  • MySQL面试题 | 附答案解析(十)

    接上篇:锁 5. MySQL中InnoDB引擎的行锁是怎么实现的? 答:InnoDB是基于索引来完成行锁 例: s...

  • InnoDB介绍

    InnoDB介绍 InnoDB是事务安全的mysql存储引擎,也是mysql的默认存储引擎,特点是行锁设计、支持M...

网友评论

      本文标题:三、Mysql InnoDB锁

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