rc mysql common_RR与RC隔离级别下MySQL不同的加锁解锁方式

作者   韩杰·沃趣科技MySQL数据库工程师

出品   沃趣科技

|  RC与RR隔离级别下MySQL不同的加锁解锁方式

MySQL5.7.21

数据准备

root@localhost : pxs 05:26:27> show create table dots\G

*************************** 1. row ***************************

Table: dots

Create Table: CREATE TABLE `dots` (

`id` int(11) NOT NULL,

`color` varchar(20) COLLATE utf8_bin NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin

1 row in set (0.00 sec)

root@localhost : pxs 05:27:34> select * from dots;

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

| id | color |

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

|  1 | black |

|  2 | white |

|  3 | black |

|  4 | white |

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

4 rows in set (0.00 sec)

root@localhost : pxs 01:57:02> show variables like 'innodb_locks_unsafe_for_binlog';

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

| Variable_name                  | Value |

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

| innodb_locks_unsafe_for_binlog | OFF  |

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

1 row in set (0.00 sec)

1.RC隔离级别

确认隔离级别

root@localhost : pxs 05:27:35> show variables like '%iso%';

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

| Variable_name        | Value          |

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

| transaction_isolation | READ-COMMITTED |

| tx_isolation          | READ-COMMITTED |

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

2 rows in set (0.01 sec)

同时开启两个会话,按下图的流程开始操作。

2ff2d79104b42591788ec0f75fcc5b8b.png

2.RR隔离级别

确认隔离级别

root@localhost : pxs 05:24:41> show variables like '%iso%';

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

| Variable_name        | Value          |

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

| transaction_isolation | REPEATABLE-READ |

| tx_isolation          | REPEATABLE-READ |

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

2 rows in set (0.01 sec)

同时开启两个会话,按下图的流程开始操作。

ff64ecd3ad1c9d6b8cb7dddb1a0fa805.png

3.半一致读semi-consistent read

3.1 半一致读发生条件

RC隔离级别

RR隔离级别,且innodb_locks_unsafe_for_binlog=true

3.2 innodb_locks_unsafe_for_binlog

innodb_locks_unsafe_for_binlog默认为off。

如果设置为1,会禁用gap锁,但对于外键冲突检测(foreign-key constraint checking)或者重复键检测(duplicate-key checking)还是会用到gap锁。

启用innodb_locks_unsafe_for_binlog产生的影响等同于将隔离级别设置为RC,不同之处是:

1)innodb_locks_unsafe_for_binlog是全局参数,影响所有session;但隔离级别可以是全局也可以是会话级别。

2)innodb_locks_unsafe_for_binlog只能在数据库启动的时候设置;但隔离级别可以随时更改。

基于上述原因,RC相比于innodb_locks_unsafe_for_binlog会更好更灵活。

启用innodb_locks_unsafe_for_binlog还有以下作用:

对于update或者delete语句,InnoDB只会持有匹配条件的记录的锁。在MySQL Server过滤where条件,发现不满足后,会把不满足条件的记录释放锁。这可以大幅降低死锁发生的概率。

简单来说,semi-consistent read是read committed与consistent read两者的结合。一个update语句,如果读到一行已经加锁的记录,此时InnoDB返回记录最近提交的版本,由MySQL上层判断此版本是否满足update的where条件。若满足(需要更新),则MySQL会重新发起一次读操作,此时会读取行的最新版本(并加锁)。

来看下面这个例子:

CREATE TABLE t (a INT NOT NULL, b INT) ENGINE = InnoDB;

INSERT INTO t VALUES (1,2),(2,3),(3,2),(4,3),(5,2);

COMMIT;

这个例子中,表上没有索引,所以对于记录锁会用到隐藏主键。

假设某个client开启了一个update:

SET autocommit = 0;

UPDATE t SET b = 5 WHERE b = 3;

假设另一个client紧接着也开启一个update:

SET autocommit = 0;

UPDATE t SET b = 4 WHERE b = 2;

每当InnoDB发起update,会先对每一行记录加上排它锁,然后再决定记录是否满足条件。如果不匹配,则innodb_locks_unsafe_for_binlog开启,InnoDB就会把记录上的锁释放掉。否则,InnoDB会一直持有锁直到事务结束。具体如下:

如果innodb_locks_unsafe_for_binlog没有开启,第一个update会一直持有x锁

x-lock(1,2); retain x-lock

x-lock(2,3); update(2,3) to (2,5); retain x-lock

x-lock(3,2); retain x-lock

x-lock(4,3); update(4,3) to (4,5); retain x-lock

x-lock(5,2); retain x-lock

第二个update会阻塞住直到第一个update提交或者回滚

x-lock(1,2); block and wait for first UPDATE to commit or roll back

如果innodb_locks_unsafe_for_binlog开启,第一个update先持有x锁,然后会释放不匹配的记录上面的x锁

x-lock(1,2); unlock(1,2)

x-lock(2,3); update(2,3) to (2,5); retain x-lock

x-lock(3,2); unlock(3,2)

x-lock(4,3); update(4,3) to (4,5); retain x-lock

x-lock(5,2); unlock(5,2)

对于第二个update,InnoDB会开启半一致读,此时InnoDB返回记录最近提交的版本,由MySQL上层判断此版本是否满足update的where条件。

x-lock(1,2); update(1,2) to (1,4); retain x-lock

x-lock(2,3); unlock(2,3)

x-lock(3,2); update(3,2) to (3,4); retain x-lock

x-lock(4,3); unlock(4,3)

x-lock(5,2); update(5,2) to (5,4); retain x-lock

4.一开始的例子

4.1 RC隔离级别

session 1

session 1执行:

update dots set color = 'black' where color = 'white';

由于color列无索引,因此只能走聚簇索引,进行全部扫描。加锁如下:

fd6b4d62f1e0a7f44e9017b96ff5891f.png

注:如果一个条件无法通过索引快速过滤,那么存储引擎层面就会将所有记录加锁后返回,然后由MySQL Server层进行过滤。因此也就把所有的记录,都锁上了。

但在实际中,MySQL做了优化,如同前面作用1所提到的。在MySQL Server过滤条件,发现不满足后,会调用unlock_row方法,把不满足条件的记录放锁 (违背了2PL的约束)。这样做,保证了最后只会持有满足条件记录上的锁,但是每条记录的加锁操作还是不能省略的。

实际加锁如下:

860d71528edb593e9805754b24e02418.png

session 2

session 2执行:

update dots set color = 'white' where color = 'black';

session 2尝试加锁的时候,发现行上已经存在锁,InnoDB会开启semi-consistent read,返回最新的committed版本(1,black),(2,white),(3,black),(4,white)。MySQL会重新发起一次读操作,此时会读取行的最新版本(并加锁)。如同前面作用2所提到的。

加锁如下:

fd6b4d62f1e0a7f44e9017b96ff5891f.png

MySQL优化后实际加锁如下:

3dd5e3ccda81d39ccdf62433b26f03d8.png

4.2 RR隔离级别

session 1

session 1执行:

update dots set color = 'black' where color = 'white';

由于color列无索引,因此只能走聚簇索引,进行全部扫描。加锁如下:

7552d8953fe751436f18988c76f4a530.png

session 2

session 2执行:

update dots set color = 'white' where color = 'black';

更新被阻塞。 等session 1提交commit之后,session 2update才会成功。

引申:RR隔离级别,且开启innodb_locks_unsafe_for_binlog=ON

环境准备

root@localhost : (none) 04:57:46> show  variables like '%iso%';

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

| Variable_name        | Value          |

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

| transaction_isolation | REPEATABLE-READ |

| tx_isolation          | REPEATABLE-READ |

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

2 rows in set (0.01 sec)

root@localhost : (none) 04:55:25> show variables like 'innodb_locks_unsafe_for_binlog';

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

| Variable_name                  | Value |

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

| innodb_locks_unsafe_for_binlog | ON    |

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

1 row in set (0.00 sec)

root@localhost : pxs 05:00:54> select * from dots;

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

| id | color |

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

|  1 | black |

|  2 | white |

|  3 | black |

|  4 | white |

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

4 rows in set (0.00 sec)

开始操作

注:过程现象满足RR隔离级别,也符合设置innodb_locks_unsafe_for_binlog=ON的情况。因为前面所讲的启用innodb_locks_unsafe_for_binlog会产生作用1与作用2,所以整个加锁与解锁情况与RC隔离级别类似。

参考:

《数据库事务处理的艺术:事务管理与并发控制》https://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_locks_unsafe_for_binloghttp://hedengcheng.com/?p=771http://hedengcheng.com/?p=220

|  作者简介

韩杰  沃趣科技MySQL数据库工程师

熟悉mysql体系架构、主从复制,熟悉问题定位与解决。

相关链接

更多干货,欢迎来撩~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/399248.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Javascript_库编写]创建自己的“JavaScript库”

一.编写JavaScript库要注意的问题 为了让自己的JS库构建的更加优雅、合理,我们编写JS库时要注意两方面的内容: 1.不要使用版本检测,而要使用能力检测 由于浏览器的类型和版本太多,以及不断的新的浏览器出现,我们不可能…

mysql5.6.24怎么打开_mysql 5.6.24 安装配置方法图文教程

由于工作需要,开始使用mysql数据库,已经好久没有使用了。基本已经忘了差不多。今天重新安装配置了一下,写个随笔记录一下,以免自己以后需要的时候翻看,如有不正确或需要补充的,希望大家多多留言。首先下载m…

sublime text 3安装及使用

安装配置 安装: 安装环境:Ubuntu 16.04 官网下载sublime text 3 https://www.sublimetext.com/3 解压: tar xvf 文件名 进入 sublime_text_3文件夹,运行 ./sublime_text 注册码:我用的时候有用 —– BEGIN LICENSE —–TwitterInc…

微信公众号新功能-原创声明、赞赏功能、评论管理、页面模版

原文:http://www.shichangbu.com/portal.php?modview&aid25931 公众号如何申请这些功能? 在微信公众号后台和QQ经常都有人问我诸如此类的问题:”微信公众平台原创声明怎么开通?“、”微信赞赏等功能是怎么回事…

为什么闹钟设置了却不响_又被iPhone闹钟坑了?解决闹钟不响问题看这里!

原标题:又被iPhone闹钟坑了?解决闹钟不响问题看这里!你有没有过这样的体验,早上醒来,闹钟还没响,内心想:真好,还可以再睡会。拿起手机想看看还能再睡多久,结果……我的天…

CSS3实现纸张边角卷起效果

html代码 1 <body>2 <div class"page">3 <div class"page-box">4 <h1>5 兔子先生6 </h1>7 <p>8 这几…

fzu 1894 单调队列

http://acm.fzu.edu.cn/problem.php?pid1894 Problem 1894 志愿者选拔Accept: 1328 Submit: 4200Time Limit: 1500 mSec Memory Limit : 32768 KB Problem Description 世博会马上就要开幕了&#xff0c;福州大学组织了一次志愿者选拔活动。参加志愿者选拔的同学们排队接…

均线带角度的指标_选股指标:均线角度并列向上,量能倍增飞扬趋势明显,短线操作可考虑...

今天要讲的是量能飞扬的选股指标&#xff0c;这个指标是按照20日、30日、60日、120日均线反正切角度原理为基础设计的公式&#xff0c;这4条均线角度排列向上&#xff0c;股价呈现向上的趋势&#xff0c;选出的股票有大概率上涨的空间&#xff0c;完整的公式如下&#xff1a;A2…

将链表中m-n范围内的数进行倒序

Reverse a linked list from position m to n. Do it in-place and in one-pass. For example:Given 1->2->3->4->5->NULL, m 2 and n 4, return 1->4->3->2->5->NULL. Note:Given m, n satisfy the following condition:1 ≤ m ≤ n ≤ lengt…

win10下安装ubuntu14.04双系统(UEFI固件)

2019独角兽企业重金招聘Python工程师标准>>> 在windows10环境下安装双系统&#xff0c;遇到了很多坑。作为一个用惯了虚拟机的人&#xff0c;本想通过安装双系统来充分利用计算机本身的硬件资源&#xff0c;结果失败了n次&#xff0c;摸索了整整一天&#xff0c;看了…

扫雷游戏制作学习过程

1. 扫雷游戏的构思&#xff1a; 设计为初级&#xff0c;中级&#xff0c;高级三个级别。 因此不妨设置为如下规格&#xff1a; 9x9 16x15和30x16 &#xff08;行&#xff0c;列&#xff09;规格不同地雷的数量也不同&#xff0c;分别为 10&#xff0c;40 &#xff0c;99 2.在…

201621123080《Java程序设计》第十一周学习总结

201621123080《Java程序设计》第十一周学习总结 1. 本周学习总结 1.1 以你喜欢的方式&#xff08;思维导图或其他&#xff09;归纳总结多线程相关内容。 2. 书面作业 本次PTA作业题集多线程 1. 源代码阅读&#xff1a;多线程程序BounceThread 1.1 BallRunnable类有什么用&#…

Unix/Linux环境C编程入门教程(27) 内存那些事儿

calloc() free() getpagesize() malloc() mmap() munmap()函数介绍calloc&#xff08;配置内存空间&#xff09; 相关函数 malloc&#xff0c;free&#xff0c;realloc&#xff0c;brk表头文件 #include <stdlib.h>定义函数 void *calloc(size_t nmemb&#xff0c;size_t…

Fix an “Unapproved Caller” SecurityAgent Message in Mac OS X

上午一进公司就被日本分公司的美女呼叫&#xff0c;说mac硬盘加密经常开机后需要输入硬盘加密密码才可以登录&#xff0c;我想应该是硬盘加密后没有给用户添加许可证&#xff0c;所以每次登录系统都要进行验证。于是远程到用户电脑上后&#xff0c;准备在硬盘加密的设置里添加用…

ue 清理缓存_【PM项目管理系统】PM安装更新客户端、删除UE及清理IE缓存操作手册...

第 1 页 共 9 页 PM 安装更新客户端、删除UE 及清理IE 缓存操作手册1、登录地址⑴登陆地址http://www.doczj.com/doc/45b822bf0c22590103029d30.html⑵安装或更新客户端安装客户端如果之前电脑上没有安装过客户端&#xff0c;需要下载并安装客户端。 打开IE 浏览器&#xff0c;…

这绝对是有史以来最详细的web前端学习路线

定要善用开发者工具。firefox的firebug和Chrome的F12都是很好的选择&#xff0c;用好了这个必会发现他带给你的帮助比看一本书更多。你把firebug摸透了你还担心对DOM理解不够&#xff1f;考虑到未来&#xff0c;html5和css3是必须学习的。看这篇总结的最全学习资料&#xff0c;…

cocos2d 走动椭圆

1.效果图艺术与规划说他想与我合作在全国率先主角光环加&#xff0c;椭圆形走动。cocos2d自带没有&#xff0c;參考网上的写了一个。2.椭圆数学知识有关椭圆的数学知识我已经忘光了。网上找了点资料&#xff1a;a是椭圆的长半轴&#xff0c;b是椭圆的短半轴。o是角度&#xff0…

深度学习中用来训练的train.py 探究学习2.0( 数据预处理)

数据预处理 下列代码为train.py中常见的一些数据处理方法 train_transform transforms.Compose([transforms.Resize((224, 224)),transforms.RandomVerticalFlip(),# 随机旋转&#xff0c;-45度到45度之间随机选transforms.RandomRotation(45),# 从中心开始裁剪transforms.C…

go语言入门(三)

条件语句 go语言的条件语句结构如下&#xff1a; go语言的条件语句和其他语言类似。简单列举下&#xff1a; 1、if 语句&#xff0c;布尔表达式不需要括号 if 布尔表达式 {   /* 在布尔表达式为 true 时执行 */   } 2、if...else语句 if 布尔表达式 { /* 在布尔表达式为 tr…

HDU 1950 Bridging signals

那么一大篇的题目描述还真是吓人。 仔细一读其实就是一个LIS&#xff0c;还无任何变形。 刚刚学会了个二分优化的DP&#xff0c;1A无压力。 1 //#define LOCAL2 #include <iostream>3 #include <cstdio>4 #include <cstring>5 using namespace std;6 7 const…