首页 数据库 mysql教程 MySQL数据库锁介绍_MySQL

MySQL数据库锁介绍_MySQL

Jun 01, 2016 pm 01:28 PM
商场 资源

bitsCN.com

MySQL数据库锁介绍

 

1. 锁的基本概念

当并发事务同时访问一个资源时,有可能导致数据不一致,因此需要一种机制来将数据访问顺序化,以保证数据库数据的一致性。

锁就是其中的一种机制。

我们可以用商场的试衣间来做个比喻。商场里得每个试衣间都可供多个消费者使用,因此可能出现多个消费者同时试衣服需要使用试衣间。为了避免冲突,试衣间装了锁,某一个试衣服的人在试衣间里把锁锁住了,其他顾客就不能再从外面打开了,只能等待里面的顾客,试完衣服,从里面把锁打开,外面的人才能进去。

 

2. 锁的基本类型

数据库上的操作可以归纳为两种:读和写。

多个事务同时读取一个对象的时候,是不会有冲突的。同时读和写,或者同时写才会产生冲突。因此为了提高数据库的并发性能,通常会定义两种锁:共享锁和排它锁。

2.1 共享锁(Shared Lock,也叫S锁)

共享锁(S)表示对数据进行读操作。因此多个事务可以同时为一个对象加共享锁。(如果试衣间的门还没被锁上,顾客都能够同时进去参观)

产生共享锁的sql:select * from ad_plan lock in share mode;

2.2 排他锁(Exclusive Lock,也叫X锁)

排他锁也叫写锁(X)。

排他锁表示对数据进行写操作。如果一个事务对对象加了排他锁,其他事务就不能再给它加任何锁了。(某个顾客把试衣间从里面反锁了,其他顾客想要使用这个试衣间,就只有等待锁从里面给打开了)

产生排他锁的sql: select * from ad_plan for update;

 

对于锁,通常会用一个矩阵来描述他们之间的冲突关系。

      S      X  

S          –  

X    –      –  

代表兼容, - 代表不兼容

 

时间/事务

 

Tx1:

 

Tx2:

 

T1set autocommit=0;set autocommit=0;T2select * from ad_plan lock in share mode;T3update ad_plan set name='' ; blocking
登录后复制

 

执行sql: select * from information_schema.innodb_locks; 可以查看锁。

 

3. 锁的粒度

就是通常我们所说的锁级别。MySQL有三种锁的级别:页级、表级、行级。

相对其他数据库而言,MySQL的锁机制比较简单,其最 显著的特点是不同的存储引擎支持不同的锁机制。

比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking);BDB存储引擎采用的是页面锁(page-level locking),但也支持表级锁;InnoDB存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁。

MySQL这3种锁的特性可大致归纳如下:

表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。

行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。

数据库引擎通常必须获取多粒度级别上的锁才能完整地保护资源。

 

3.1 行锁(Row Lock)

对一行记录加锁,只影响一条记录。

 

通常用在DML语句中,如INSERT, UPDATE, DELETE等。

 

InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的。InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!

用下面例子来说明一下:

CREATE TABLE test_index(id int , name VARCHAR(50),age int )engine=innodb ;INSERT INTO test_index values(1,'张一',15);INSERT INTO test_index values(3,'张三',16);INSERT INTO test_index values(4,'张四',17);INSERT INTO test_index values(5,'张五',19);INSERT INTO test_index values(7,'刘琦',19);
登录后复制

 

不再启用多事务描述了,直接解释执行查询语句

 explain select * from test_index where id = 1;+----+-------------+------------+------+---------------+------+---------+------+------+-------------+| id | select_type | table      | type | possible_keys | key  | key_len | ref  | rows | Extra       |+----+-------------+------------+------+---------------+------+---------+------+------+-------------+|  1 | SIMPLE      | test_index | ALL  | NULL          | NULL | NULL    | NULL |    5 | Using where |+----+-------------+------------+------+---------------+------+---------+------+------+-------------+
登录后复制

 

type: all ,rows: 5 很明显是会使用全表锁。

增加索引,id加唯一索引,age加普通索引。

ALTER TABLE test_indexADD UNIQUE uk_id(id),ADD index idx_age(age);mysql> explain select * from test_index where id = 1;+----+-------------+------------+-------+---------------+-------+---------+-------+------+-------+| id | select_type | table      | type  | possible_keys | key   | key_len | ref   | rows | Extra |+----+-------------+------------+-------+---------------+-------+---------+-------+------+-------+|  1 | SIMPLE      | test_index | const | uk_id         | uk_id | 5       | const |    1 | NULL  |+----+-------------+------------+-------+---------------+-------+---------+-------+------+-------+type: const ,key:uk_id,rows:
登录后复制

 

 1 很明显是会使用行锁,锁定一条记录。

 

 

 

下面做个有趣的实验:两个事务,TX1加共享行锁, 查询age=17的记录, TX2往数据库里插入一条age=18的记录。

TX1:mysql> set autocommit=0;mysql> select * from test_index where age=17 lock in share mode;+------+------+------+| id   | name | age  |+------+------+------+|    4 | 张四 |   17 |+------+------+------+1 row in set (0.00 sec)TX2:mysql> set autocommit=0;mysql> insert test_index values(8,'test',18);ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
登录后复制

 

 

结果是TX2获取锁超时,看来TX1锁定的并不止age=17的记录,不存在的间隙age=18,也被加锁了。

 

 

执行select * from information_schema.innodb_locks;可以看到加锁的具体信息

+--------------+-------------+-----------+-----------+---------------------+------------+------------+-----------+----------+--------------------+| lock_id      | lock_trx_id | lock_mode | lock_type | lock_table          | lock_index | lock_space | lock_page | lock_rec | lock_data          |+--------------+-------------+-----------+-----------+---------------------+------------+------------+-----------+----------+--------------------+| 45288:57:5:5 | 45288       | X,GAP     | RECORD    | `test`.`test_index` | idx_age    |         57 |         5 |        5 | 19, 0x000000000208 || 45289:57:5:5 | 45289       | S,GAP     | RECORD    | `test`.`test_index` | idx_age    |         57 |         5 |        5 | 19, 0x000000000208 |+--------------+-------------+-----------+-----------+---------------------+------------+------------+-----------+----------+--------------------+
登录后复制

 

 

行锁S、X锁上做了一些精确的细分,在代码中称作Precise Mode。这些精确的模式,  使的锁的粒度更细小。可以减少冲突。  

A.间隙锁(Gap Lock),只锁间隙。  

B.记录锁(Record Lock) 只锁记录。  

C.Next-Key Lock(代码中称为Ordinary Lock),同时锁住记录和间隙。

D.插入意图锁(Insert Intention Lock),插入时使用的锁。在代码中,插入意图锁,实际上是GAP锁上加了一个LOCK_INSERT_INTENTION的标记。

 

行锁兼容矩阵

 

    G I R N

G

I – –

R – –

N – – 代表兼容, -代表不兼容. 

G代表Gap锁,I代表插入意图锁,R代表记录锁,N代表Next-Key锁.  

S锁和S锁是完全兼容的,因此在判别兼容性时不需要对比精确模式。  

精确模式的检测,用在S、X和X、X之间。

从这个矩阵可以看到几个特点:  

A. INSERT操作之间不会有冲突。  

B. GAP,Next-Key会阻止Insert。  

C. GAP和Record,Next-Key不会冲突  

D. Record和Record、Next-Key之间相互冲突。  

E. 已有的Insert锁不阻止任何准备加的锁。

 

Gap lock:

间隙锁只会出现在辅助索引(index)上,唯一索引(unique)和主键索引是没有间隙锁。

间隙锁(无论是S还是X)只会阻塞insert操作。

间隙锁的目的是为了防止幻读(但是需要应用自己加锁,innodb默认不会加锁防止幻读)。

3.2 页面锁

3.3 表锁(Table Lock)

对整个表加锁,影响标准的所有记录。通常用在DDL语句中,如DELETE TABLE,ALTER TABLE等。  

很明显,表锁影响整个表的数据,因此并发性不如行锁好。

在MySQL 数据库中,使用表级锁定的主要是MyISAM,Memory等一些非事务性存储引擎。

 

因为表锁覆盖了行锁的数据,所以表锁和行锁也会产生冲突(商场关门了,试衣间自然也没法使用了)。如:

A. trx1 BEGIN

  B. trx1 给 T1 加X锁,修改表结构。

  C. trx2 BEGIN

  D. trx2 给 T1 的一行记录加S或X锁(事务被阻塞,等待加锁成功)

trx1要操作整个表,锁住了整个表。那么trx2就不能再对T1的单条记录加X或S锁,去读取或修这条记录。 

3.3.1 表锁—意向锁

为了方便检测表级锁和行级锁之间的冲突,就引入了意向锁。

A. 意向锁分为意向读锁(IS)和意向写锁(IX)。  

B. 意向锁是表级锁,但是却表示事务正在读或写某一行记录,而不是整个表。     所以意向锁之间不会产生冲突,真正的冲突在加行锁时检查。  

C. 在给一行记录加锁前,首先要给该表加意向锁。也就是要同时加表意向锁和行锁。

 

采用了意向锁后,上面的例子就变成了:

A. trx1 BEGIN  

B. trx1 给 T1 加X锁,修改表结构。  

C. trx2 BEGIN  

D. trx2 给 T1 加IX锁(事务被阻塞,等待加锁成功)  

E. trx2 给 T1 的一行记录加S或X锁.

 

表锁的兼容性矩阵

  IS IX S X

IS –

IX – –

S – –

X – – – – 代表兼容, -代表不兼容

意向锁之间不会冲突, 因为意向锁仅仅代表要对某行记录进行操作。在加行锁时,会判断是否冲突。

 

bitsCN.com
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

115网盘怎么找资源 115网盘怎么找资源 Feb 23, 2024 pm 05:10 PM

115网盘里会有很多的资源,那么该怎么找资源呢?用户们可以在软件里搜索需要的资源,然后进入下载界面,然后选择存至网盘就可以了。这篇115网盘找资源方法介绍就能够告诉大家具体的内容,下面就是详细的介绍,赶紧来看看吧。115网盘怎么找资源答:在软件里搜索内容,然后点击存至网盘。具体介绍:1、首先在app里输入想要的资源。2、之后点击出现的关键词链接。3、接着进入下载界面。4、点击里面的存至网盘就可以了。

韩小圈为什么突然没有资源了 韩小圈为什么突然没有资源了 Feb 24, 2024 pm 03:22 PM

韩小圈是能够观看很多韩剧的软件,那么为什么突然没有资源呢?这个软件可能是因为网络问题,版本问题,或者是版权问题才没有资源。这篇韩小圈突然没有资源原因介绍就能够告诉大家具体的内容,下面就是详细的介绍,赶紧来看看吧。韩小圈为什么突然没有资源了答:由于网络问题,版本问题,版权问题导致具体介绍:1、网络问题解决方法:可以选择不同的网络,然后重新登录软件试试。2、版本问题解决方法:用户们可以从官网上下载这个软件的最新版本。3、版权问题解决方法:有的韩剧是因为版权问题下架,可以选择别的韩剧观看。

资源管理器.exe在 Windows 11 安全模式下发生崩溃的情况不再发生 资源管理器.exe在 Windows 11 安全模式下发生崩溃的情况不再发生 Aug 30, 2023 pm 11:09 PM

资源管理器.exe在Windows11的安全模式下崩溃?不会了。Microsoft刚刚发布了开发频道的新补丁,虽然此版本没有新功能,但许多修复和改进都进入了Windows预览体验计划,包括资源管理器.exe在安全模式下崩溃的烦人错误。好吧,你现在可以告别它了,至少在Windows预览体验计划中是这样。但与所有这些更新一样,它们也将进入实时Windows服务器。修复了导致资源管理器.exe无法在安全模式下工作的问题。但是,文件资源管理器还进行了其他一些修复,因此Microsoft热衷于使其正常工作

如何无限刷取消逝的光芒资源 如何无限刷取消逝的光芒资源 Jan 24, 2024 pm 04:03 PM

在消逝的光芒这个游戏中,许多玩家在前期可能会因为资源匮乏而被无数丧尸包围。有时候他们还会冒险去拯救被困的流浪者,这些流浪者可能还会提供一些支线任务,完成后会有丰厚的奖励。消逝的光芒无限资源获取首先,找到一个赈灾包裹,放入仓库。在【物品栏】的首页,选择一个数量较多的物品,在选中时使用鼠标左键点击。2然后,按【ESC】,鼠标不要移动,快速按F+A,按1下就好,隔约0.25秒,感觉仓库页面快跳出来时按鼠标左和右键,鼠标不要移且不是长按,跳出存放物品的提示即成功。3最后,在仓库找到【贩灾包裹】,被提示框

Go语言图形界面开发:探索现有工具与资源 Go语言图形界面开发:探索现有工具与资源 Mar 23, 2024 pm 03:06 PM

指导原则:Go语言本身并不直接支持图形界面开发,但是可以通过调用其他语言的库或者使用现有的工具来实现图形界面开发。本文将介绍一些常用的工具和资源,帮助读者更好地探索使用Go语言进行图形界面开发的可能性。一、Go语言图形界面开发的现状Go语言是一种高效、简洁的编程语言,适用于各种应用领域,但在图形界面开发方面并不擅长。由于Go语言的性能和并发特性,许多开发者希

突发!ChatGPT Plus停售 突发!ChatGPT Plus停售 Apr 07, 2023 pm 09:01 PM

现在,ChatGPT已不支持Plus付费了。△ChatGPT截图原因很简单:High demand。需求量太大,以至于OpenAI不得不暂停Plus的销售。之后何时开放也没有明说。前几天ChatGPT就因出现大规模封号引发热议,现在竟正儿八经地关闭了Plus付费会员的申请。不少网友归因于计算资源不够了,已经不单是靠钱能解决得了的问题。金主爸爸微软还要供给自己的用户群体。地球上已经没有足够的算力来满足需求了。还有已经付费的网友表示庆幸:真的无法想象回到GPT-3.5的日子。ChatGPT关闭Plu

Java错误:无法找到应用程序资源,如何解决和避免 Java错误:无法找到应用程序资源,如何解决和避免 Jun 24, 2023 pm 06:58 PM

Java是一种广泛应用于开发应用程序和创建网站的编程语言。然而,在开发和部署Java应用程序时,您可能会遇到以下错误:无法找到应用程序资源。这种错误常常发生在打包和部署Java应用程序时。本文将讨论此错误的原因、解决方案和避免方法。错误原因无法找到应用程序资源错误通常是由以下一些原因引起的:1.1文件丢失或损坏:当应用程序的程序包或依赖库文件缺失或损坏时,

学习高级Python编程的资源有哪些? 学习高级Python编程的资源有哪些? Sep 01, 2023 pm 02:45 PM

Python作为一种编程语言的需求推动了它在学习其不同方面上的丰富资源。虽然初学者有各种教程和指南帮助他们入门,但进阶学习者常常难以找到满足他们特定需求的资源。在本文中,我们将探讨一系列旨在提升你的Python技能的资源,涵盖高级语言特性、设计模式、性能优化等主题。高级Python语言特性TogetthemostoutofPython,it’simportanttomasteritsadvancedlanguagefeatures.Thesefeaturesenableefficient,rea

See all articles