MySQL中InnoDB存储引擎的锁的基本使用教程

MyISAM和MEMORY采用表级锁(table-level locking)

BDB采用页面锁(page-leve locking)或表级锁,默认为页面锁

InnoDB支持行级锁(row-level locking)和表级锁,默认为行级锁

各种锁特点

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

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

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

InnoDB存储引擎的锁

InnoDB存储引擎实现了如下两种锁

1、共享锁(S Lock),允许事务读一行数据

2、排他锁(X Lock),允许事务更新或者删除一行数据

共享锁和排他锁的兼容如下图所示

一致性的非锁定读

一致性的非锁定行读(consistent nonlocking read)是指InnoDB存储引擎通过行多版本控制(multi versioning)的方式来读取当前执行时间数据库中行的数据。如果读取的行正在执行DELETE、UPDATE操作,这是读取操作不会因此而会等待行上锁的释放,相反,InnoDB会去读取行的一个快照数据。

之所以称其为非锁定读,因为不需要等待访问的行上X锁的释放。快照数据是指改行之前版本的数据,该实现是通过undo段来实现的。但是在不同事务隔离级别下,读取的方式不同,并不是每个事务隔离级别下读取的都是一致性读。

例如:

对于read committed的事务隔离级别,他总是读取行的最新版本,如果行被锁定了,则读取该行版本的最新一个快照。

对于repeatable read(innoDB存储引擎的默认隔离级别),总是读取事务开始时的行数据。

非锁定读的机制大大提高了数据读取的并发性,在Innodb存储引擎默认设置下,这是默认的读取方式,但是在某些情况下,可以对读进行加锁,比如:

1、显式对读进行加锁,如使用 select --- for update ;select --- lock in share mode

2、在外键的插入和更新上,因为在外键的插入和更新上,对于数据的隔离性要求较高,在插入前需要扫描父表中的记录是否存在,所以,在外键的插入删除上,InnoDB会使用加S锁的方式来实现。

InnoDB锁的算法

1、Record Lock:单个行记录上的锁

2、Gap Lock:间隙锁,锁定一个范围,但不包含记录本身

3、Next-key Lock:Gap Lock+Record Lock,锁定一个范围,并且锁定记录本身

Record Lock总是会去锁住索引记录,如果InnoDB存储引擎表建立的时候没有设置任何一个索引,这时InnodB存储引擎会使用隐式的主键来进行锁定,在Repeatable Read隔离级别下,Next-key Lock 算法是默认的行记录锁定算法。

锁带来的问题

1、丢失更新

如何避免丢失更新:让事务变成串行操作,而不是并发的操作,即对每个事务开始---对读取记录加排他锁。

2、脏读

脏读即一个事务可以读到另一个事务中未提交的数据,这违反了数据库的隔离性。

脏读发生的条件是需要事务的隔离级别为Read uncommitted。

3、不可重复读

不可重复读与脏读的区别是:脏读是读到未提交的数据,而不可重复读读到的是已经提交的数据。

一般来说,不可重复读是可以接受的,在InnoDB存储引擎中,通过使用Next-Key Lock算法来避免不可重复读的问题。

值得注意的是,默认情况下InnoDB存储引擎不会回滚超时引发的错误异常。

死锁的相关问题

1、死锁发生的条件

互斥条件:一个资源每次只能被一个进程使用;请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放;不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺;循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

2、死锁检测(根据网上的经验)

Innodb检测死锁有两种情况,一种是满足循环等待条件,还有另一种策略:锁结构超过mysql配置中设置的最大数量或锁的遍历深度超过设置的最大深度时,innodb也会判断为死锁(这是提高性能方面的考虑,避免事务一次占用太多的资源)。

因循环等待条件而产生的死锁只有可能是四种形式:两张表两行记录交叉申请互斥锁、同一张表则存在主键索引锁冲突、主键索引锁与非聚簇索引锁冲突、锁升级导致的锁等待队列阻塞。

3、死锁避免(根据网上的经验)

1.如果使用insert…select语句备份表格且数据量较大,在单独的时间点操作,避免与其他sql语句争夺资源,或使用select into outfile加上load data infile代替 insert…select,这样不仅快,而且不会要求锁定
2. 一个锁定记录集的事务,其操作结果集应尽量简短,以免一次占用太多资源,与其他事务处理的记录冲突。
3.更新或者删除表格数据,sql语句的where条件都是主键或都是索引,避免两种情况交叉,造成死锁。对于where子句较复杂的情况,将其单独通过sql得到后,再在更新语句中使用。
4. sql语句的嵌套表格不要太多,能拆分就拆分,避免占有资源同时等待资源,导致与其他事务冲突。
5. 对定点运行脚本的情况,避免在同一时间点运行多个对同一表进行读写的脚本,特别注意加锁且操作数据量比较大的语句。
6.应用程序中增加对死锁的判断,如果事务意外结束,重新运行该事务,减少对功能的影响。

4、死锁解决

1)先执行show processlist找到死锁线程号.然后Kill pid

2)Show innodb status检查引擎状态 ,可以看到哪些语句产生死锁

3)查看information_schema架构下的innodb_locks、innodb_trx、innodb_lock_waits等表

PS:Mysql死锁

既然谈到死锁,那附带地就专门说一下。
何为死锁?
 
死锁是对资源的分配和使用不当而造成的。是两个进程争夺某一资源而出现相互等待的现象。具体的来讲,出现死锁需要满足四个必要条件:
(1)互斥条件:每一个资源都只能被一个进程使用
(2)请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放
(3)不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4)循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
很显然,出现死锁需要两个或者两个以上的进程,换句话说,死锁发生在并发的程序中。在Mysql中,由于目前只有InnoDB引擎使用事务(InnoDB支持锁),便有了InnoDB和死锁的旷世基情。
死锁的检测
 
1、通过使用Show innodb status检查引擎状态 ,可以看到哪些语句产生deadlock
2、MySQL提供了一个information_schema,通过查看innodb_locks、innodb_trx、innodb_lock_waits这几个表检测死锁。
因循环等待条件而产生的死锁只有可能是四种形式:两张表两行记录交叉申请互斥锁、同一张表则存在主键索引锁冲突、主键索引锁与非聚簇索引锁冲突、锁升级导致的锁等待队列阻塞。

死锁避免

1.如果使用insert…select语句备份表格且数据量较大,在单独的时间点操作,避免与其他sql语句争夺资源,或使用select into outfile加上load data infile代替 insert…select,这样不仅快,而且不会要求锁定
2. 一个锁定记录集的事务,其操作结果集应尽量简短,以免一次占用太多资源,与其他事务处理的记录冲突。
3.更新或者删除表格数据,sql语句的where条件都是主键或都是索引,避免两种情况交叉,造成死锁。对于where子句较复杂的情况,将其单独通过sql得到后,再在更新语句中使用。
4. sql语句的嵌套表格不要太多,能拆分就拆分,避免占有资源同时等待资源,导致与其他事务冲突。
5. 对定点运行脚本的情况,避免在同一时间点运行多个对同一表进行读写的脚本,特别注意加锁且操作数据量比较大的语句。
6.应用程序中增加对死锁的判断,如果事务意外结束,重新运行该事务,减少对功能的影响。

(0)

相关推荐

  • MySQL InnoDB之事务与锁详解

    引题:为何引入事务? 1>.数据完整性 2>.数据安全性 3>.充分利用系统资源,提高系统并发处理的能力 1. 事务的特征 事务具有四个特性:原子性(Atomiocity).一致性(Consistency).隔离性(Isolation)和持久性(Durability),这四个特性简称ACID特性. 1.1原子性 事务是数据库的逻辑工作单位,事务中包括的所有操作要么都做,要么都不做. 1.2 一致性 事务执行的结果必须是使数据库从一个一致性的状态变到另外一个一致性状态. 1.3 隔离性 一

  • 详谈innodb的锁(record,gap,Next-Key lock)

    Record lock单条索引记录上加锁,record lock锁住的永远是索引,而非记录本身,即使该表上没有任何索引,那么innodb会在后台创建一个隐藏的聚集主键索引,那么锁住的就是这个隐藏的聚集主键索引.所以说当一条sql没有走任何索引时,那么将会在每一条聚集索引后面加X锁,这个类似于表锁,但原理上和表锁应该是完全不同的. Gap lock在索引记录之间的间隙中加锁,或者是在某一条索引记录之前或者之后加锁,并不包括该索引记录本身.gap lock的机制主要是解决可重复读模式下的幻读问题,关

  • mysql之innodb的锁分类介绍

    一.innodb行锁分类 record lock:记录锁,也就是仅仅锁着单独的一行 gap lock:区间锁,仅仅锁住一个区间(注意这里的区间都是开区间,也就是不包括边界值. next-key lock:record lock+gap lock,所以next-key lock也就半开半闭区间,且是下界开,上界闭. www.jb51.net next-key 锁定范围:(负无穷大,最小第一记录],(记录之间],(最大记录,正无穷大) 二.语句锁定情况分析 SELECT ... FROM ... F

  • MySQL中InnoDB存储引擎的锁的基本使用教程

    MyISAM和MEMORY采用表级锁(table-level locking) BDB采用页面锁(page-leve locking)或表级锁,默认为页面锁 InnoDB支持行级锁(row-level locking)和表级锁,默认为行级锁 各种锁特点 表级锁:开销小,加锁快:不会出现死锁:锁定粒度大,发生冲突的概率最高,并发度最低 行级锁:开销大,加锁慢:会出现死锁:锁定粒度最小,发生锁冲突的概率最低,并发度也最高 页面锁:开销和加锁时间介于表锁和行锁之间:会出现死锁:锁定粒度介于表锁和行锁之

  • 详解MySql中InnoDB存储引擎中的各种锁

    目录 什么是锁 InnoDB存储引擎中的锁 锁的算法 行锁的3种算法 幻像问题 锁的问题 脏读 不可重复读 丢失更新 死锁 什么是锁 现实生活中的锁是为了保护你的私有物品,在数据库中锁是为了解决资源争抢的问题,锁是数据库系统区别于文件系统的一个关键特性.锁机制用于管理对共享资源的并发访. 数据库系统使用锁是为了支持对共享资源进行并发访问,提供数据的完整性和一致性 InnoDB存储引擎区别于MyISAM的两个重要特征就是:InnoDB存储引擎支持事务和行级别的锁,MyISAM只支持表级别的锁 In

  • 聊聊MySQL中的存储引擎

    基础知识 在关系型数据库中每一个数据表相当于一个文件,而不同的存储引擎则会构建出不同的表类型. 存储引擎的作用是规定数据表如何存储数据,如何为存储的数据建立索引以及如何支持更新.查询等技术的实现. 在Oracle以及SqlServer等数据库中只支持一种存储引擎,故其数据存储管理机制都是一样的,而MySQL中提供了多种存储引擎,用户可以根据不同的需求为数据表选择不同的存储引擎,用户也可以根据自己的需要编写自己的存储引擎. 如处理文本文件可使用txt类型,处理图片可使用png类型 存储引擎 在My

  • 详解mysql中的存储引擎

    mysql存储引擎概述 什么是存储引擎? MySQL中的数据用各种不同的技术存储在文件(或者内存)中.这些技术中的每一种技术都使用不同的存储机制.索引技巧.锁定水平并且最终提供广泛的不同的功能和能力.通过选择不同的技术,你能够获得额外的速度或者功能,从而改善你的应用的整体功能. 例如,如果你在研究大量的临时数据,你也许需要使用内存存储引擎.内存存储引擎能够在内存中存储所有的表格数据.又或者,你也许需要一个支持事务处理的数据库(以确保事务处理不成功时数据的回退能力). 这些不同的技术以及配套的相关

  • MySql中的存储引擎和索引

    目录 一.MySql的逻辑结构 二.什么是存储引擎 MySQL支持的存储引擎 三.操作 四.数据库的索引 索引的分类 五.索引操作 一.MySql的逻辑结构 MySQL体系结构分为四层:分别是连接层.服务层.存储引擎层.系统文件层. 连接层又称为客户端连接器(Client Connectors):提供与MySQL服务器建立的支持.连接池:管理.缓冲用户的连接,线程处理等需要缓存的需求. 服务层是MySQL Server的核心:主要包含系统管理和控制工具.SQL接口.解析器.查询优化器.缓存. 存

  • MySQL的InnoDB存储引擎的数据页结构详解

    目录 1InnoDB页的概念 2数据页的结构 3记录在页中的存储 4PageDirectory页目录 5FileHeader文件头部 6InnoDB页和记录的关系 7没有索引时查找记录 总结 1 InnoDB页的概念 InnoDB是一个将表中的数据存储在磁盘上的存储引擎,即使我们关闭并重启服务器,数据还是存在.而真正处理数据的过程发生在内存中,所以需要把磁盘中的数据加载到内存中,所以需要把磁盘中的数据加载到内存中.如果处理写入和修改请求,还需要将内存中的内容刷新到磁盘上.而我们知道读写磁盘的速度

  • Mysql详细剖析数据库中的存储引擎

    目录 前言 存储引擎 什么是存储引擎? Mysql的体系结构: Mysql的体系结构分为四层: 存储引擎的查看 存储引擎的指定 存储引擎的特点 InnoDB介绍 InnoDB特点 InnoDB文件 存储引擎的选择 总结撒花 前言 哈喽各位友友们,我今天又学到了很多有趣的知识,现在迫不及待的想和大家分享一下!我仅已此文,和大家分享[Mysql系列]——详细剖析数据库中的存储引擎~都是精华内容,可不要错过哟!!! 存储引擎 什么是存储引擎? 存储引擎是数据库中非常关键的部分,它就像是飞机.火箭中的引

  • 深入理解mysql事务与存储引擎

    目录 一.MySQL事务 1.事务的概念 2.事务的 ACID 特点 3.事物之间的互相影响 二.Mysql及事务隔离级别 1.查询全局事务隔离级别 2.查询会话事务隔离级别 3.设置全局事务隔离级别 4.设置会话事务隔离级别 三.事务控制语句 1.相关语句 2.案例 3.使用 set 设置控制事务 四.MySQL 存储引擎 1.存储引擎概念介绍 2.查看系统支持的存储引擎 3.查看表使用的存储引擎 4.修改存储引擎 一.MySQL事务 1.事务的概念 (1)事务是一种机制.一个操作序列,包含了

  • 深入探讨:MySQL数据库MyISAM与InnoDB存储引擎的比较

    MySQL有多种存储引擎,MyISAM和InnoDB是其中常用的两种.这里介绍关于这两种引擎的一些基本概念(非深入介绍).MyISAM是MySQL的默认存储引擎,基于传统的ISAM类型,支持全文搜索,但不是事务安全的,而且不支持外键.每张MyISAM表存放在三个文件中:frm 文件存放表格定义:数据文件是MYD (MYData):索引文件是MYI (MYIndex).InnoDB是事务型引擎,支持回滚.崩溃恢复能力.多版本并发控制.ACID事务,支持行级锁定(InnoDB表的行锁不是绝对的,如果

  • MySQL中Innodb的事务隔离级别和锁的关系的讲解教程

    前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力.所以对于加锁的处理,可以说就是数据库对于事务处理的精髓所在.这里通过分析MySQL中InnoDB引擎的加锁机制,来抛砖引玉,让读者更好的理解,在事务处理中数据库到底做了什么. 一次封锁or两段锁? 因为有大量的并发访问,为了预防死锁,一般应用中推荐使用一次封锁法,就是在方法的开始阶段,已经预先知道会

随机推荐