MySQL InnoDB存储引擎中的锁机制
1.隔离级别
Read Uncommited(RU):这种隔离级别下,事务间完全不隔离,会产生脏读,可以读取未提交的记录,实际情况下不会使用。
Read Committed (RC):仅能读取到已提交的记录。针对当前读,RC隔离级别保证对读取到的记录加锁 (记录锁),存在幻读现象。所谓幻读是指在同一个事务中,多次执行同一个查询,返回的记录不完全相同的现象。幻读产生的根本原因是,在RC隔离级别下,每条语句都会读取已提交事务的更新,若两次查询之间有其他事务提交,则会导致两次查询结果不一致。虽然如此,读提交隔离级别在生产环境中使用很广泛。
Repeatable Read (RR):针对当前读,RR隔离级别保证对读取到的记录加锁 (记录锁),同时保证对读取的范围加锁,新的满足查询条件的记录不能够插入 (间隙锁),不存在幻读现象。mysql的innodb比较特殊,RR即解决了幻读问题,主要通过间隙锁实现。
Serializable:从MVCC并发控制退化为基于锁的并发控制。不区别快照读与当前读,所有的读操作均为当前读,读加读锁 (S锁),写加写锁 (X锁)。Serializable隔离级别下,读写冲突,因此并发度急剧下降,在MySQL/InnoDB下不建议使用。
查看隔离级别:
- show variables like 'tx_isolation';
- SELECT @@tx_isolation;
- SELECT @@session.tx_isolation;
- SELECT @@global.tx_isolation;
修改隔离级别:
用户可以用SET TRANSACTION语句改变单个会话或者所有新进连接的隔离级别。它的语法如下:
- SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}
2. 一致性非锁定读和一致性锁定读
一致性非锁定读:
指InnoDB存储引擎通过行多版本控制的方式来读取当前执行时间数据库中行的数据。如果读取的行正在执行delete或update操作,这时读取操作不会因此去等待行上锁的释放。InnoDB存储引擎会去读取行的一个快照数据。快照数据是指该行的之前版本的数据,该实现是通过undo段来完成的。读取快照数据是不需要上锁的,因为没有事务需要对历史数据进行修改操作。在InnoDB存储引擎的默认设置下,这是默认的读取方式,即读取不会占用和等待表上的锁。
一致性锁定读:
在某些情况下,用户需要显式的对数据库读取操作进行加锁,以保证数据逻辑的一致性。InnoDB存储引擎对于select支持两种一致性的锁定读操作。
select...for update 对读取的行记录加一个X锁
select...lock in share mode 对读取的行记录加一个S锁
3. 行锁的三种算法
record lock:记录锁,单个记录上的锁;record lock总是会去锁住索引记录,如果InnoDB存储引擎表在建立的时候没有设置任何一个索引,则会使用隐式的主键来进行锁定。
gap lock:间隙锁,锁定一个范围,但是不包含记录本身;
next-key lock:gap lock+record lock,锁定一个范围,并锁定记录本身。设计的目的是解决幻读问题。
当查询的索引含有唯一属性时,InnoDB存储引擎会对next-key lock进行优化,将其降级为record lock,即仅锁住索引本身,而不是范围。若是辅助索引,则加的是next-key lock,特别需要注意的是,InnoDB存储引擎还会对辅助索引下一个键值加上gap lock。
可以通过下面两种方式来显式的关闭gap lock:
(1)将事务的隔离级别设置为Read Committed;
(2)将参数innodb_locks_unsafe_for_binlog设置为1.
4. 查看锁请求的信息
(1)show engine innodb status\G;
(2)show full processlist;
(3)查看information_schema下的表INNODB_TRX、INNODB_LOCKS、INNODB_LOCK_WAITS;
5. 锁相关的状态变量
- mysql> show status like 'innodb_row_lock%';
- +-------------------------------+--------+
- | Variable_name | Value |
- +-------------------------------+--------+
- | Innodb_row_lock_current_waits | 0 |
- | Innodb_row_lock_time | 490578 |
- | Innodb_row_lock_time_avg | 37736 |
- | Innodb_row_lock_time_max | 121411 |
- | Innodb_row_lock_waits | 13 |
- +-------------------------------+--------+
Innodb 的行级锁定状态变量不仅记录了锁定等待次数,还记录了锁定总时长,每次平均时长,以及最大时长,此外还有一个非累积状态量显示了当前正在等待锁定的等待数量。对各个状态量的说明如下:
- Innodb_row_lock_current_waits:当前正在等待锁定的数量;
- Innodb_row_lock_time:从系统启动到现在锁定总时间长度;
- Innodb_row_lock_time_avg:每次等待所花平均时间;
- Innodb_row_lock_time_max:从系统启动到现在等待最常的一次所花的时间;
- Innodb_row_lock_waits:系统启动后到现在总共等待的次数;
对于这5 个状态变量, 比较重要的主要是Innodb_row_lock_time_avg(等待平均时长) ,Innodb_row_lock_waits(等待总次数)以及Innodb_row_lock_time(等待总时长)这三项。尤其是当等待次数很高,而且每次等待时长也不小的时候,就需要分析系统中为什么会有如此多的等待,然后根据分析结果着手指定优化计划。
6. 合理使用InnoDB
(1)尽可能让所有的数据检索都通过索引来完成;
(2)合理设计索引,让Innodb 在索引键上面加锁的时候尽可能准确,尽可能的缩小锁定范围,避免造成不必要的锁定而影响其他Query 的执行;
(3)尽可能减少基于范围的数据检索过滤条件,避免因为间隙锁带来的负面影响而锁定了不该锁定的记录;
(4)尽量控制事务的大小,减少锁定的资源量和锁定时间长度;
(5)在业务环境允许的情况下,尽量使用较低级别的事务隔离,以减少MySQL 因为实现事务隔离级别所带来的附加成本;
几篇非常好的博客:
一个最不可思议的MySQL死锁分析:http://hedengcheng.com/?p=844
MySQL加锁处理分析:http://hedengcheng.com/?p=771
Innodb锁系统(1)之如何阅读死锁日志:http://mysqllover.com/?p=411
MySQL InnoDB存储引擎中的锁机制的更多相关文章
- MySQL数据库InnoDB存储引擎中的锁机制
MySQL数据库InnoDB存储引擎中的锁机制 http://www.uml.org.cn/sjjm/201205302.asp 00 – 基本概念 当并发事务同时访问一个资源的时候,有可能 ...
- MySQL数据库InnoDB存储引擎中的锁机制(转载)
http://www.uml.org.cn/sjjm/201205302.asp 00 – 基本概念 当并发事务同时访问一个资源的时候,有可能导致数据不一致.因此需要一种致机制来将访问顺序化. 锁就是 ...
- MySQL 温故而知新--Innodb存储引擎中的锁
近期碰到非常多锁问题.所以攻克了后,细致再去阅读了关于锁的书籍,整理例如以下:1,锁的种类 Innodb存储引擎实现了例如以下2种标准的行级锁: ? 共享锁(S lock),同意事务读取一行数据. ? ...
- MySQL InnoDB存储引擎undo redo解析
本文介绍MySQL数据库InnoDB存储引擎重做日志漫游 00 – Undo Log Undo Log 为了实现事务原子,在MySQL数据库InnoDB存储引擎,还使用Undo Log(简称:MVCC ...
- 三分钟入门 InnoDB 存储引擎中的表锁和行锁
各位对 "锁" 这个概念应该都不是很陌生吧,Java 语言中就提供了两种锁:内置的 synchronized 锁和 Lock 接口,使用锁的目的就是管理对共享资源的并发访问,保证数 ...
- 在MySQL的InnoDB存储引擎中count(*)函数的优化
写这篇文章之前已经看过了很多数据库方面的优化内容,大部分都是加索引.使用事务.要什么select什么等等.然而,只是停留在阅读的层面上,很少有实践,因为没有遇到真实的项目,一切都是纸上谈兵.实践是检验 ...
- MySQL InnoDB存储引擎
200 ? "200px" : this.width)!important;} --> 介绍 本篇文章是对Innodb存储引擎的概念进行一个整体的概括,innodb存储引擎的 ...
- MySQL InnoDB 存储引擎探秘
在MySQL中InnoDB属于存储引擎层,并以插件的形式集成在数据库中.从MySQL5.5.8开始,InnoDB成为其默认的存储引擎.InnoDB存储引擎支持事务.其设计目标主要是面向OLTP的应用, ...
- MySQL InnoDB存储引擎体系架构 —— 索引高级
转载地址:https://mp.weixin.qq.com/s/HNnzAgUtBoDhhJpsA0fjKQ 世界上只两件东西能震撼人们的心灵:一件是我们心中崇高的道德标准:另一件是我们头顶上灿烂的星 ...
随机推荐
- pl/sql插入报错
用pl/sql 命令的方法导入文件,发现一只提示文件报错.报Error reading file错误. 原来: 在pl/sql工具->导入表里的sql插入方式下,可以选择“使用命令窗口”和“使用 ...
- showModalDialog 超过问题
a.aspx页面打开一个弹出模式对话框b.aspx. a.aspx 页面页面代码: function SetPlay() { window.showModalDialog('SetAdvertisin ...
- ARC工程中添加非ARC文件
转载自:http://blog.csdn.net/zhenweicao/article/details/16988543 分类: IOS2013-11-27 17:02 626人阅读 评论(0) 收藏 ...
- .h头文件和.c文件的作用和区别
.h头文件和.c文件的作用和区别 在小工程中,.h的作用没有得到充分的使用,在大工程中才能充分体现出.h文件的作用. .h和.c文件都是代码.头文件好处有: 一:头文件便于共享,只需要添加一句“inc ...
- Android中9patch图片格式(xx.9.png)介绍与制作详解
一:9patch图片介绍: android的.9.png是android系统中一种特殊的图片格式,专门用来用来处理图片大小变化后(如拉伸)的失真,不正常,如我们看到的qq聊天中的文字气泡,不管你输入的 ...
- Solr + Hadoop = Big Data Love
FROM:http://architects.dzone.com/articles/solr-hadoop-big-data-love 许多人使用Hadoop的开源项目来处理大数据的大数据集,因为它是 ...
- 在工程中添加pch文件
在Xcode6之前,新建一个工程的时候,系统会帮我们自动新建一个以工程名为名字的pch (precompile header)文件,在开发过程中,可以将那些整个工程都广泛使用的头文件包含在该文件下,编 ...
- 1047: [HAOI2007]理想的正方形 - BZOJ
Description 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小.Input 第一行为3个整数,分别表示a,b,n的值第二行至第a ...
- Tomcat多次部署
http://blog.csdn.net/knityster/article/details/6300804
- linux 模拟延时和丢包
这是 RHCA 中的一个 BDP 的测试,这也是公司很常用的一种延时和丢包的模拟,现在分享给大家. 我们做的应用软件,还有测试 TCP/UDP 对比,测试 BDP 对 TCP/IP 的影响时,我们都 ...