Preface
 
    As we know,InnoDB is index organized table.InnoDB engine supports row-level lock base on indexes,if there're no indexes on a certain table the record locks will upgrade to "table-level"(not really table lock,just locks all the records in the table) locks.Furthe more,in RR transaction isolation mode,It's more complicated.'cause there're gap locks(together with record locks,we call them next key locks) to prevent phantom read between multiple tansactions.Let's do some test watch the locking conflicts.
 
Procedure
 
Crete a test table as below.
 zlm@192.168.56.100: [zlm]>create table t1(
-> c1 int unsigned not null default '',
-> c2 int unsigned not null default '',
-> c3 int unsigned not null default '',
-> c4 int unsigned not null default '',
-> primary key(c1),
-> key(c2)
-> ) engine=innodb;
Query OK, rows affected (0.02 sec) zlm@192.168.56.100: [zlm]>insert into t1(c1,c2,c3,c4) values(,,,),(,,,),(,,,),(,,,),(,,,),(,,,),(,,,);
Query OK, rows affected (0.01 sec)
Records: Duplicates: Warnings: zlm@192.168.56.100: [zlm]>select * from t1;
+----+----+----+----+
| c1 | c2 | c3 | c4 |
+----+----+----+----+
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
+----+----+----+----+
rows in set (0.01 sec) zlm@192.168.56.100: [(none)]>select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| REPEATABLE-READ | //Make surej in RR transaction isolation level.
+-------------------------+
row in set (0.00 sec) zlm@192.168.56.100: [(none)]>show variables like 'innodb_status_output_locks';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| innodb_status_output_locks | ON |
+----------------------------+-------+
row in set (0.00 sec)
Test 1. session1 executes "select ...  for update" and session2 executes "select ... lock in share mode".(conflict)
 //Session1:
zlm@192.168.56.100: [zlm]>begin;select * from t1 where c1= for update;
Query OK, rows affected (0.00 sec) +----+----+----+----+
| c1 | c2 | c3 | c4 |
+----+----+----+----+
| | | | |
+----+----+----+----+
row in set (0.00 sec) //Session2:
monitor@192.168.56.100: [zlm]>begin;select * from t1 where c1= lock in share mode;
Query OK, rows affected (0.00 sec) ERROR (HY000): Lock wait timeout exceeded; try restarting transaction //Session2 requested a "S" record lock on the primary key column where c1=3 while session1 has holded the "X" record lock on the same position,so session2 was blocked util lock timeout.
Test 2. session1 executes "select ...  for update" and session2 executes ordinary query.(compatible)
 //Session1:
zlm@192.168.56.100: [zlm]>begin;select * from t1 where c1= for update;
Query OK, rows affected (0.00 sec) +----+----+----+----+
| c1 | c2 | c3 | c4 |
+----+----+----+----+
| | | | |
+----+----+----+----+
row in set (0.00 sec) //Session2:
monitor@192.168.56.100: [zlm]>select * from t1 where c1=;
+----+----+----+----+
| c1 | c2 | c3 | c4 |
+----+----+----+----+
| | | | |
+----+----+----+----+
row in set (0.00 sec) //Session1 didn't change this time and session2 request for non-lock consistent read.It read records from a consistent snapshop without locking.
Test 3. session1 executes "select ...  lock in share mode" and session2 executes "select ... for update".(conflict)
 //Session1:
zlm@192.168.56.100: [zlm]>begin;select * from t1 where c3= lock in share mode;
Query OK, rows affected (0.01 sec) Empty set (0.00 sec) //Session2:
monitor@192.168.56.100: [zlm]>begin;select * from t1 where c3= for update;
Query OK, rows affected (0.00 sec) ERROR (HY000): Lock wait timeout exceeded; try restarting transaction //Although there's no record satisfied with c3=7 but notice that there's no index on c3 column.Therefore,the session1 has holded a "S" record for all the records on column c1 in table t1.Then session2 asked for the "X" record lock for "c3=10"(even it does not exixt),it was blocked.
Test 4. session1 executes "select ...  lock in share mode" and session2 executes "select ... for update".(conflict)
 //Session1:
zlm@192.168.56.100: [zlm]>begin;select * from t1 where c3= lock in share mode;
Query OK, rows affected (0.00 sec) Empty set (0.00 sec) //Session2:
monitor@192.168.56.100: [zlm]>begin;select * from t1 where c1= for update;
Query OK, rows affected (0.00 sec) ERROR (HY000): Lock wait timeout exceeded; try restarting transaction //This is similar with "test 3".Session1 has holded a "S" record lock of all records on column c3.The record where c1=6 means c3=5,it's also in the range of all records.So session2 was blocked.
Test 5. session1 executes "select ...  for update" and session2 executes "select ... for update".(conflict)
 
 //Session1:
zlm@192.168.56.100: [zlm]>begin;select * from t1 where c2= and c3= for update;
Query OK, rows affected (0.00 sec) +----+----+----+----+
| c1 | c2 | c3 | c4 |
+----+----+----+----+
| | | | |
+----+----+----+----+
row in set (0.00 sec) //Session2:
monitor@192.168.56.100: [zlm]>begin;select * from t1 where c2= and c3= for update;
Query OK, rows affected (0.00 sec) ERROR (HY000): Lock wait timeout exceeded; try restarting transaction //Because of the secondary index key on column c2,it generated a "X" record lock and a gap lock(record + gap = next key lock).Although the gap lock between two sessions can be coexistent,but record locks do not.So session2 was blocked.
Test 6. session1 executes "select ...  for update" and session2 executes "select ... for update".(compatible)
 //Session1:
zlm@192.168.56.100: [zlm]>begin;select * from t1 where c2= and c3= for update;
Query OK, rows affected (0.00 sec) +----+----+----+----+
| c1 | c2 | c3 | c4 |
+----+----+----+----+
| | | | |
+----+----+----+----+
row in set (0.00 sec) //Session2:
monitor@192.168.56.100: [zlm]>begin;select * from t1 where c2= and c3= for update;
Query OK, rows affected (0.00 sec) Empty set (0.00 sec) //This time session2 was not blocked.They've requested a different "X" record lock individually even they still hold the gap lock.
Test 7. session1 executes "select ...  for update" and session2 executes "select ... for update".(conflict)
 //Session1:
zlm@192.168.56.100: [zlm]>begin;select * from t1 where c2= and c3= for update;
Query OK, rows affected (0.00 sec) +----+----+----+----+
| c1 | c2 | c3 | c4 |
+----+----+----+----+
| | | | |
+----+----+----+----+
row in set (0.00 sec) //Session2:
monitor@192.168.56.100: [zlm]>begin;select * from t1 where c1= and c3= for update;
Query OK, rows affected (0.00 sec) ERROR (HY000): Lock wait timeout exceeded; try restarting transaction //The query condition in session2 is c1=4.It means c2=2,this is similar with test 5(asked for the equal line).
Test 8. session1 executes "select ...  for update" and session2 executes "select ... for update".(compatible)
 //Session1:
zlm@192.168.56.100: [zlm]>begin;update t1 set c4= where c2>=;
Query OK, rows affected (0.00 sec) Query OK, rows affected (0.00 sec)
Rows matched: Changed: Warnings: //Session2:
monitor@192.168.56.100: [zlm]>begin;select * from t1 where c1= for update;
Query OK, rows affected (0.00 sec) Empty set (0.00 sec) //The records according to the query condition c2>=4 were c1=8 and c1=10.
//Even though there's a index key on c1 but it's a primary key which doesn't generate gap lock.So session2 's asking for "X" record lock of c1=7 was not blocked.
Summary
  • We should pay more attention to innodb row-level locks.If there's no key on the relevant column,the locks will be escalated to "table-level"(all records will be locked) locks.
  • In the RR transaction isolation level,Secondary index generates gap locks(LOCK_ORDINARY) to prevent phantom read while primary index and unique index do not.They only hold record locks(LOCK_REC_NOT_GAP).
  • In the RC transaction isolation level,there're no gap locks.Therefore,it's concurrency is better than that in RR mode,but the consistency is poor as well.
  • As for which transaction isolation level we should choose is depend on your purpose:for more consistency or for more concurrency.
 

InnoDB锁冲突案例演示的更多相关文章

  1. InnoDB锁冲突案例演示(续)

      Preface       I've demontstrated several InnoDB locking cases in my previous blog.I'm gonna do the ...

  2. MySQL记录锁、间隙锁、临键锁小案例演示

    生成间隙(gap)锁.临键(next-key)锁的前提条件 是在 RR 隔离级别下. 有关Mysql记录锁.间隙(gap)锁.临键锁(next-key)锁的一些理论知识之前有写过,详细内容可以看这篇文 ...

  3. KingbaseES R6 集群主机锁冲突导致的主备切换案例

    ​ 案例说明: 主库在业务高峰期间,客户执行建表等DDL操作,主库产生"AccessExclusiveLock "锁,导致大量的事务产生锁冲突,大量的会话堆积,客户端session ...

  4. InnoDB锁机制分析

    InnoDB锁机制常常困扰大家,不同的条件下往往表现出不同的锁竞争,在实际工作中经常要分析各种锁超时.死锁的问题.本文通过不同条件下的实验,利用InnoDB系统给出的各种信息,分析了锁的工作机制.通过 ...

  5. [转载] 数据库分析手记 —— InnoDB锁机制分析

    作者:倪煜 InnoDB锁机制常常困扰大家,不同的条件下往往表现出不同的锁竞争,在实际工作中经常要分析各种锁超时.死锁的问题.本文通过不同条件下的实验,利用InnoDB系统给出的各种信息,分析了锁的工 ...

  6. MySQL- InnoDB锁机制

    InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION):二是采用了行级锁.行级锁与表级锁本来就有许多不同之处,另外,事务的引入也带来了一些新问题.下面我们先介绍一点背景知识 ...

  7. MySQL InnoDB锁机制

    概述: 锁机制在程序中是最常用的机制之一,当一个程序需要多线程并行访问同一资源时,为了避免一致性问题,通常采用锁机制来处理.在数据库的操作中也有相同的问题,当两个线程同时对一条数据进行操作,为了保证数 ...

  8. 【锁】Innodb锁

    InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION):二是采用了行级锁.行级锁与表级锁本来就有许多不同之处,另外,事务的引入也带来了一些新问题.下面我们先介绍一点背景知识 ...

  9. MySQL基础篇(06):事务管理,锁机制案例详解

    本文源码:GitHub·点这里 || GitEE·点这里 一.锁概念简介 1.基础描述 锁机制核心功能是用来协调多个会话中多线程并发访问相同资源时,资源的占用问题.锁机制是一个非常大的模块,贯彻MyS ...

随机推荐

  1. iOS一个很好的内存检测工具

    虽然Xcode提供了instrument来检测内存,但是使用起来怎么看都很麻烦.然后有一个很不错的内存泄露的检测工具MLeaksFinder,使用的话不需要注入任何代码,直接导入库就行了.出现泄露的时 ...

  2. Objective-C中,ARC下的 strong和weak指针原理解释

    Objective-C中,ARC下的 strong和weak指针原理解释 提示:本文中所说的"实例变量"即是"成员变量","局部变量"即是& ...

  3. Winodws SNMP服务安装和配置(Windows 2003 & 2008 R2)

    简单网络管理协议SNMP服务起着代理的作用,它会收集可以向SNMP管理站或控制台报告的信息.您可以使用SNMP服务来收集数据,并且在整个公司网络范围内管理基于Windows Server 2003.M ...

  4. 【memcached启动报错】

    #前台启动不了 #指定-u root #后台启动 #扩展选项: #利用telnet连接memcached 的端口登录memcached服务 #error表示有语法错误 #store表示正确

  5. windows10下“sqlplus / as sysdba”执行提示无权限解决办法

    ORA_DBA:是ORACLE 的特有用户,是超级管理员权限,建成DBA 它具有管理数据库的最高权限. 注明:需要以管理员身份运行cmd,不然第4步会失败(点开始,输入cmd,右键以管理员身份运行) ...

  6. thinkphp5访问sql2000数据库

    大家都知道php跟mysql是绝配,但是因为有时候工作需要,要求php访问操作sql2000,怎么办呢? 一般来说有两种方式: 1. sqlsrv驱动方式 2. odbc方式 sqlsrv驱动方式,因 ...

  7. Laravel 开发支付宝支付与提现转账问题小结

    由于项目需要,所以需要开发支付宝支付与微信支付,支付部分采用了 yansongda/pay    https://packagist.org/packages/yansongda/pay  https ...

  8. 7、Linux应用程序地址布局

    程序构成 在学习Linux应用程序开发时,经常会遇到如下概念: 代码段.数据段.BSS段(Block Started by Symbol,又名:未始化数据段) .堆(heap)和栈(stack).始化 ...

  9. 『Python基础-3』变量、定义变量、变量类型、关键字Python基础-3』变量、定义变量、变量类型、关键字

    『Python基础-3』变量.定义变量.变量类型.关键字 目录: 1.Python变量.变量的命名 2.变量的类型(Python数据类型) 3.Python关键字 1. Python 变量.变量的命名 ...

  10. SublimeText配置Python3运行环境

    1.查看python3安装路径which python3 2.打开sublime text 3,点击上部菜单栏Tools->Build System->new Build System 3 ...