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存储引擎中的锁机制的更多相关文章

  1. MySQL数据库InnoDB存储引擎中的锁机制

    MySQL数据库InnoDB存储引擎中的锁机制    http://www.uml.org.cn/sjjm/201205302.asp   00 – 基本概念 当并发事务同时访问一个资源的时候,有可能 ...

  2. MySQL数据库InnoDB存储引擎中的锁机制(转载)

    http://www.uml.org.cn/sjjm/201205302.asp 00 – 基本概念 当并发事务同时访问一个资源的时候,有可能导致数据不一致.因此需要一种致机制来将访问顺序化. 锁就是 ...

  3. MySQL 温故而知新--Innodb存储引擎中的锁

    近期碰到非常多锁问题.所以攻克了后,细致再去阅读了关于锁的书籍,整理例如以下:1,锁的种类 Innodb存储引擎实现了例如以下2种标准的行级锁: ? 共享锁(S lock),同意事务读取一行数据. ? ...

  4. MySQL InnoDB存储引擎undo redo解析

    本文介绍MySQL数据库InnoDB存储引擎重做日志漫游 00 – Undo Log Undo Log 为了实现事务原子,在MySQL数据库InnoDB存储引擎,还使用Undo Log(简称:MVCC ...

  5. 三分钟入门 InnoDB 存储引擎中的表锁和行锁

    各位对 "锁" 这个概念应该都不是很陌生吧,Java 语言中就提供了两种锁:内置的 synchronized 锁和 Lock 接口,使用锁的目的就是管理对共享资源的并发访问,保证数 ...

  6. 在MySQL的InnoDB存储引擎中count(*)函数的优化

    写这篇文章之前已经看过了很多数据库方面的优化内容,大部分都是加索引.使用事务.要什么select什么等等.然而,只是停留在阅读的层面上,很少有实践,因为没有遇到真实的项目,一切都是纸上谈兵.实践是检验 ...

  7. MySQL InnoDB存储引擎

    200 ? "200px" : this.width)!important;} --> 介绍 本篇文章是对Innodb存储引擎的概念进行一个整体的概括,innodb存储引擎的 ...

  8. MySQL InnoDB 存储引擎探秘

    在MySQL中InnoDB属于存储引擎层,并以插件的形式集成在数据库中.从MySQL5.5.8开始,InnoDB成为其默认的存储引擎.InnoDB存储引擎支持事务.其设计目标主要是面向OLTP的应用, ...

  9. MySQL InnoDB存储引擎体系架构 —— 索引高级

    转载地址:https://mp.weixin.qq.com/s/HNnzAgUtBoDhhJpsA0fjKQ 世界上只两件东西能震撼人们的心灵:一件是我们心中崇高的道德标准:另一件是我们头顶上灿烂的星 ...

随机推荐

  1. oracle创建表空间、用户

    创建表空间 create tablespace '<数据库名>' datafile '<存储路径>' size 500M default storage (initial 20 ...

  2. 【BZOJ 2301】[HAOI2011]Problem b

    Description 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. Input 第一行一个整数 ...

  3. 南京邮电大学CTF隐写术部分Writeup

    女神 听说这是女神的私房照,里面藏着flag哦 http://115.28.150.176/misc1.jpg 这个链接居然打不开,摔!万念俱灰!主办方可否给力点! P.S.为了方便日后学习,暂时列下 ...

  4. 监控SQL Server的job执行情况

    在服务器没有设置发邮件并且不允许发邮件的情况下, 可以通过下列语句来检查SQL Server 的job的执行情况 select top 150 a.run_date,a.run_time, b.nam ...

  5. 使用Schtasks命令的注意事项

    在使用Schtasks命令时遇到了两个棘手的问题,耗费了一点时间,出现这个问题的时候查找网络资源也找不到真正的解决方案,最后还是自己悟出来了原因,所以在此把这些问题记录下来.如下: 服务器环境:win ...

  6. Homework3

    1. 切换路径到想要保存的目录下,使用git init创建仓库: 2. 在仓库下创建文件Readme.txt,使用git add命令添加到暂存区和 git commit 命令提交到仓库: 3.  修改 ...

  7. Hadoop的安装与配置说明

    安装hadoop是一件非常容易的事情,读者可以在官网上下载到最近的几个hadoop版本.网址为http://apache.etoak.com//hadoop/core/.   目前,hadoop可以运 ...

  8. 如果Android和C#在一起?

    先看两则新闻.   一则来自新浪科技:   谷歌上诉遭拒绝 需向甲骨文支付Java使用费 大意是说,针对谷歌Android操作系统侵犯甲骨文Java知识产权的指控,美国法院最近做出了有利于甲骨文的裁决 ...

  9. 严重: The web application [] appears to have started a thread named [Abandoned connection cleanup thread] but has failed to stop it.

    今日在重新部署项目时出现此问题,虽然对项目无影响,但问题就是问题.完整信息如下(使用idea工具): 十二月 05, 2015 11:44:27 上午 org.apache.catalina.star ...

  10. CSS 命名规范及标题供参考与学习

    一.CSS 命名规范   XHTML-CSS写作建议 所有的xhtml代码小写 属性的值一定要用双引号("")括起来,且一定要有值 每个标签都要有开始和结束,且要有正确的层次 空元 ...