上篇文章主要聊了全局锁和表锁,并详细分析MDL锁的作用以及可能带来的问题。今天我们主要来聊一聊Innodb存储引擎的行锁。MySQL的行锁是在引擎层由引擎自己实现的,并不是所有的引擎都支持行锁,MyISAM 引擎就不支持行锁。行锁,顾名思义就是针对数据表中的行记录的锁。比如事物A更新了一行,而事物B也要更新同一行,就必须等待事物A的操作完成后才能进行。下面我们就介绍下行锁的种类,针对不同的锁进行操作演示。一. 行锁的种类

1.单个记录的锁(record lock),在RC隔离级别下只有record  lock记录锁模式。

2.间隙锁(Gap lock)

3.记录锁和间隙锁的组合(next-key lock),加锁的基本单位就是next-key lock。

以下所有演示都是在RR隔离级别下进行的。

演示表t,主键是id,索引是age字段。

表数据如下:

二. 单个记录的锁

Session Amysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> update t set name='lili' where age=24;

Query OK, 0 rows affected (0.00 sec)

Rows matched: 1  Changed: 1  Warnings: 0

Session Bmysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> update t set name='jim' where age=24;

试验结果:Session B

通过这个演示可以看出两个事务针对同一行数据修改时,后执行的事务会出现锁等待现象,超过innodb_lock_wait_timeout(默认50s)定义的时间后会超时。

我们再做个试验,把age上面的索引删除,看看会出现什么样的试验效果。alter table t drop index idx_age;//删除索引

session  Amysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> update t set name='lili' where age=24;

Query OK, 1 row affected (0.00 sec)

Rows matched: 1 Changed: 1 Warnings: 0

Session Bmysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> update t set name='jim' where age=16;

试验结果:Session B

通过试验看出,虽然更新了不同的行,也出现了锁超时的情况。两个实现不同的地方就是试验2把索引删除了,试验结果就截然不同了。通过这个试验,我们可以看出,就是Innodb的行锁是加在索引上的。三. 间隙锁(Gap lock)

在RR隔离级别下,为了避免幻读现象,引入了Gap lock。它锁定行记录的范围,不包含记录的本身,不允许在此范围内插入任何数据。

表数据如下:

Session Amysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from t where age<24 lock in share mode;

+----+------+------+

| id | name | age  |

+----+------+------+

|  4 | jack |   16 |

+----+------+------+

1 row in set (0.01 sec)

Session Bmysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into t(name,age) value('angel',20);

实验结果:Session B

可以看出innodb在age<24的范围内加了间隙锁,导致session B插入age=20的记录时阻塞。

注意:间隙锁只在RR隔离级别下生效,RC隔离级别下是允许出现幻读现象的。四. Next-key Lock

Next-keys Lock是记录锁和间隙锁的组合,Innodb扫描索引记录时,会先对索引记录加上记录锁(Record Lock),再对索引记录之间的间隙加上间隙锁(Gap Lock)。

Innodb加锁的基本单位是next-key lock,是前开后闭区间。

Session Amysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from t where age >=16 and age<24 for update;

+----+------+------+

| id | name | age  |

+----+------+------+

|  4 | jack |   16 |

+----+------+------+

1 row in set (0.00 sec)

session Bmysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql>insert into t(name,age) value('lucy',17);

Session Cmysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql>update t set name='lucy' where age=24;

试验结果:

Session B

Session C

Innodb引擎加锁有个原则:查找过程中访问到的对象才会加锁。

在上面的例子中当用到age=16的时候,会在索引age上(5,16]范围内加next-key锁,同时在(16,24]范围内加next-key锁,这样session A加锁的范围就是(5,24]。从结果上看也符合这个预期。五. 锁监控

关于MySQL锁的监控,我们一般可以通过show processlist和show engine innodb status来查看和监控数据库的锁信息,其实还有一些更简单的方法,MySQL把事务和锁的信息记录在了information_schema库中,设计到的三张表分别是INNODB_TRX、INNODB_LOCKS和INNODB_LOCK_WAITS。

我们模拟了一个锁等待的场景,以下是从这三张表收集的信息

通过以下命令可以查看锁源头:SELECT

r.trx_wait_started AS wait_started,

TIMEDIFF(NOW(),

r.trx_wait_started) AS wait_age,

rl.lock_table AS locked_table,

rl.lock_index AS locked_index,

rl.lock_type AS locked_type,

r.trx_id AS waiting_trx_id,

r.trx_mysql_thread_id AS waiting_pid,

sys.format_statement(r.trx_query) AS waiting_query,

rl.lock_id AS waiting_lock_id,

rl.lock_mode AS waiting_lock_mode,

b.trx_id AS blocking_trx_id,

b.trx_mysql_thread_id AS blocking_pid,

sys.format_statement(b.trx_query) AS blocking_query,

bl.lock_id AS blocking_lock_id,

bl.lock_mode AS blocking_lock_mode

FROM information_schema.INNODB_LOCK_WAITS w

INNER JOIN information_schema.INNODB_TRX b

ON b.trx_id = w.blocking_trx_id

INNER JOIN information_schema.INNODB_TRX r ON r.trx_id = w.requesting_trx_id

INNER JOIN information_schema.INNODB_LOCKS bl ON bl.lock_id = w.blocking_lock_id

INNER JOIN information_schema.INNODB_LOCKS rl ON rl.lock_id = w.requested_lock_id ORDER BY r.trx_wait_started\G

1. 请简述mysql数据库的锁机制_【MySQL入门】之MySQL数据库的锁机制(二)相关推荐

  1. 易语言 mysql支持库支持多线程_易语言多线程查询数据库 易语言多线程并发

    为什么易语言两个线程同时对一个MYSQL数据? 数据库有自己的连接锁机制,如果是针对同一台机器使用同一个接口进行插入的话多线程和单线程是一样的.除非你有好几台数据库服务器,这样再使用多线程来进行上面的 ...

  2. mysql数据库查询源码_超简单php mysql数据库查询类

    本文章为你免费提供一款漂亮的超简单php mysql数据库查询类哦 */ class Config{ private $host; //主机名称:一般是localhost private $root; ...

  3. 阿里云查看mysql数据库密码是多少_阿里云服务器查看数据库密码是多少

    全网最新活动请看下方内容或右侧内容! --------------- 阿里云服务器查看数据库密码是多少,阿里云开源数据库. 在阿里云ecs云服务器上部署数据库后,在平常的操作中可能会遇到些问题,可以先 ...

  4. mysql 数据库备份到本地_如何备份远程 MySQL 数据到本地

    对于远程的 MySQL 数据库,如何定期将数据备份到本地呢?对于需要远程备份数据的童鞋来说我想这个是经常需要用到的. 1.首先远程数据库必须支撑远程连接,提供有供远程连接的IP或者域名. 假设远程数据 ...

  5. MySQL数据库实训题_实训六 MySql数据库编程练习

    实训六MySql数据库编程练习 一.实训目的 1.掌握Mysql数据库.Navicat  for Mysql等软件的安装配置方法. 2.掌握使用JDBC驱动程序连接MySql数据库的使用方法. 3.掌 ...

  6. mysql 5.0 修改字符集_修改及查看mysql数据库的字符集

    Liunx下修改MySQL字符集: 1.查找MySQL的cnf文件的位置 find / -iname '*.cnf' -print /usr/share/mysql/my-innodb-heavy-4 ...

  7. mysql多线程使用一个链接_探索多线程使用同一个数据库connection的后果

    在项目中看到有用到数据库的连接池,心里就思考着为什么需要数据库连接池,只用一个连接会造成什么影响?(只用一个connection)? 1  猜想:jdbc的事务是基于connection的,如果多线程 ...

  8. mysql 如何按时间备份_如何定时备份mysql数据库

    第一步:编写mysqldump备份数据库脚本,先新建txt文档,编辑内容为 @echo off set "Ymd=%date:~,4%%date:~5,2%%date:~8,2%" ...

  9. mysql的表面sno大全_学生表学号sno数据库

    Microsoft SQL Server 2005习题汇总小结 先建student ,course,sc表: CREATE TABLE Student ( Sno     char(7)   PRIM ...

  10. 低版本mysql数据导入高版本_将高版本mysql数据库的数据导入低版本mysql中

    前言 最近做了个网站,准备放到虚拟主机上的时候,发现本地数据库是mysql5.6,服务器上的mysql是5.0的.于是尝试导出数据,结果,导入的数据不是出错,就是各种乱码.折腾了好久之后,终于找到了解 ...

最新文章

  1. python装饰器 property_python @property装饰器
  2. 使用hibernate实现树形结构无限级分类
  3. java 防止拷贝_[改善Java代码]避免对象的浅拷贝
  4. c遗传算法的终止条件一般_Matlab2 :Matlab遗传算法(GA)优4~-r-具箱是基于基本操作 联合开发网 - pudn.com...
  5. php 抓取 wordpress 文字内容,如何抓取WordPress文章
  6. 企业在推行流程管理过程中可能出现以下四个问题
  7. java编辑遗忘曲线代码,java8的新特性 - 天使broken的个人空间 - OSCHINA - 中文开源技术交流社区...
  8. linux系统中文乱码的问题
  9. 深度学习图片卷积输出大小计算公式
  10. Python之父Guido在最近一次采访的最后说了啥
  11. Word如何快速打出公式
  12. 鸿蒙os官方版下载,鸿蒙os2.0正式版
  13. DEV05 GBase 8a MPP Cluster 数据库性能优化
  14. iOS 15增加更多新的小组件
  15. 画论17 邓椿《画继》
  16. tplinkwr710n改无线打印服务器,【多图】TP-Link TL-WR710N 改8M Flash 刷OpenWrt
  17. Vue2切换生产环境、测试环境和开发环境
  18. Linux 音频路ucm和pulseaudio
  19. ANOMALY: meaningless REX prefix used
  20. 兼容性测试平台sonic搭建(Angent windows)

热门文章

  1. 子集生成-增量构造法||位向量法
  2. 响应式Web设计的9项基本原则
  3. webservice3
  4. 关于--在 System.Threading.ThreadAbortException 中第一次偶然出现的“mscorlib.dll”类型的异常(转)...
  5. Python稳基修炼的经典案例3(计算机二级、初学者必须掌握的例题)
  6. 泰坦尼克号python数据分析统计服_Titanic数据分析报告(Python)
  7. 1000道Python题库系列分享二(48道)
  8. Python+tkinter实现任意多层级关系的组合框
  9. 聚簇索引和非聚簇索引的区别_学习索引的一些总结
  10. 那些html编辑器有代码片段6,VS Code 折腾记 - (6) 基本配置/快捷键定义/代码片段的录入(snippet)...