关于InnoDB的读写锁类型以及加锁方式
(本文为了方便,英文关键词都都采用小写方式,相关知识点会简单介绍,争取做到可以独立阅读)
文章开始我会先介绍本文需要的知识点如下:
- innodb的聚簇索引(聚集索引)和非聚簇索引(二级索引、非聚集索引)的知识
- innodb的隔离级别(isolation level)
- 简单的sql知识(能读懂sql语句)
- MVCC(Multi-Version Concurrent Control)多版本并发控制
- 数据的脏读、幻读(如果有时间会详细讲一下脏读如果没时间,网上讲这个地方的也很多)
问题1:读有几种模式、加锁有几种方式
1. select * from my_table where id = 1;
2. select * from my_table where id = 1 lock in share mode;
3. select * from my_table where id = 1 for update;
4. update my_table set address = 'tianjin' where id = 1;
读的模式分为两种:
- 快照读(snapshot read)
- 当前读(current read)
加锁的方式:(未涉及意向锁)
update my_table set name ='zhang' where id = 1;
假设id为主键:此条sql执行的时候会给此行数据加x锁,如下图
1. select * from my_table where id = 1;
2. select * from my_table where id = 1 lock in share mode;
我们上面说过,语句1为快照读,对其他的读或者写没有影响。所以这两条语句并行时,1读快照,2为语句加s锁。
select * from my_table where id = 1 lock in share mode;
2. select * from my_table where id = 1 lock in share mode;
3. select * from my_table where id = 1 for update;
其中语句2加s锁,3加x锁(在数据被加s锁的时候,其他的给这条想要读取这条记录也需要给这条记录加s锁,这就是为什么s锁是共享锁。此时是不允许再给这条记录加x锁的)两种锁是不能同时存在在一条记录上的。所以两条语句不能并发执行。
3. select * from my_table where id = 1 for update;
4. update my_table set address = 'tianjin' where id = 1;
下面我们来讨论一下id不为主键的情况
- 二级唯一索引
- 二级不唯一索引
- 没有索引
4. update my_table set address = 'tianjin' where id = 1;
这个时候我们需要对索引知识有一定的了解,上面说过二级索引中的叶子节点存储的除了索引信息还有到实际数据的逻辑指针,也就是说我们需要现在二级唯一索引中查找到这条记录的逻辑指针,然后通过指针去查找到数据实际的存储位置并给这条数据加锁。注意,这里的加锁应该是加在了索引上和数据本身上(或者说是聚簇索引上也可以,因为两者是存储在一个结构中的,而innodb中二级索引叶子中的逻辑指针并不是数据存储的物理地址,而是主键值)而不只是二级唯一索引上。如果想用好innodb,他的索引结构是必须要学习的,如果以后有时间会详细介绍。
5. update my_table set address = 'tianjin' where age = 25;
此种情况比前一种情况更特殊,因为情况3和4都只能找到一条记录,只需要对这条记录加锁,则不会发生结果集被修改的情况。但是如果age为二级非唯一索引,我们看到如下表格中有两条记录age=25
update my_table set age=25 where id=2;
则发生幻读现象。gap锁可以防止在语句或者事务执行过程中有满足条件的记录插入进来造成幻读。所以说在此种情况下,除了给满足条件的二级索引和数据(或聚簇索引)加x锁之外还要给相关的间隙加锁。可以理解为这个加gap锁是在二级索引的范围内防止新的索引项加入,因为二级索引本身也是有序的。
5. update my_table set address = 'tianjin' where age = 25;
关于InnoDB的读写锁类型以及加锁方式的更多相关文章
- Linux程序设计学习笔记----多线程编程线程同步机制之相互排斥量(锁)与读写锁
相互排斥锁通信机制 基本原理 相互排斥锁以排他方式防止共享数据被并发訪问,相互排斥锁是一个二元变量,状态为开(0)和关(1),将某个共享资源与某个相互排斥锁逻辑上绑定之后,对该资源的訪问操作例如以下: ...
- pthread中读写锁
读写锁很像一个互斥量,他阻止多个线程同时修改共享数据的另一种方法,区分不同互斥量的是他是分读数据和写数据,一个读写锁允许同时多个线程读数据,只要他们不修改数据. 只要没有写模式下的加锁,任意线程都可以 ...
- C基础 读写锁中级剖析
引言 读写锁 是为了 解决, 大量 ''读'' 和 少量 ''写'' 的业务而设计的. 读写锁有3个特征: 1.当读写锁是写加锁状态时,在这个锁被解锁之前,所有试图对这个锁加锁的线程都会被阻塞 2.当 ...
- Linux 自旋锁,互斥量(互斥锁),读写锁
自旋锁(Spin Lock) 自旋锁类似于互斥量,不过自旋锁不是通过休眠阻塞进程,而是在取得锁之前一直处于忙等待的阻塞状态.这个忙等的阻塞状态,也叫做自旋. 自旋锁通常作为底层原语实现其他类型的锁. ...
- 嵌入式 Linux线程同步读写锁rwlock示例
读写锁比mutex有更高的适用性,可以多个线程同时占用读模式的读写锁,但是只能一个线程占用写模式的读写锁.1. 当读写锁是写加锁状态时,在这个锁被解锁之前,所有试图对这个锁加锁的线程都会被阻塞:2. ...
- Linux的线程同步对象:互斥量Mutex,读写锁,条件变量
进程是Linux资源分配的对象,Linux会为进程分配虚拟内存(4G)和文件句柄等 资源,是一个静态的概念.线程是CPU调度的对象,是一个动态的概念.一个进程之中至少包含有一个或者多个线程.这 ...
- Java 并发包中的读写锁及其实现分析
1. 前言 在Java并发包中常用的锁(如:ReentrantLock),基本上都是排他锁,这些锁在同一时刻只允许一个线程进行访问,而读写锁在同一时 刻可以允许多个读线程访问,但是在写线程访问时,所有 ...
- linux中读写锁的rwlock介绍-nk_ysg-ChinaUnix博客
linux中读写锁的rwlock介绍-nk_ysg-ChinaUnix博客 linux中读写锁的rwlock介绍 2013-02-26 13:59:35 分类: C/C++ http://yaro ...
- UNIX环境高级编程——线程同步之读写锁以及属性
读写锁和互斥量(互斥锁)很类似,是另一种线程同步机制,但不属于POSIX标准,可以用来同步同一进程中的各个线程.当然如果一个读写锁存放在多个进程共享的某个内存区中,那么还可以用来进行进程间的同步, 互 ...
随机推荐
- 【转】Python处理wave文件
#本文PDF版下载 Python解析Wav文件并绘制波形的方法 #本文代码下载 Wav波形绘图代码 #本文实例音频文件night.wav下载 音频文件下载 (石进-夜的钢琴曲) 前言 在现在繁忙的生活 ...
- JAVA_SE基础——16.方法
接触过C语言的同学,这小章节很容易接受.Java中的方法是类似与C语言中的函数 功能和调用方法都类似 只不过叫法不一样 因为java是面向对象 c是面向过程 仅仅是叫法不同.. . 看到 ...
- HTTP请求到爬虫代码的终南捷径
前阵子在做爬虫的时候学会了各种抓包,看到http请求的时候硬拼代码实在有点累. 后来发现Postman工具是直接可以把Postman请求直接生成对应的代码,这样一下来就美滋滋了. 那么最后的问题就成了 ...
- Linux背景知识(1)RedHat和Centos
Redhat有收费的商业版和免费的开源版,商业版的业内称之为RHEL(Red Hat Enterprise Linux)系列, 而这个CentOS(Community ENTerprise Opera ...
- Linux知识积累(1)awk的使用方法
参见:http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html 简介 awk是一个强大的文本分析工具,相对于grep的查找,se ...
- JsonCPP库使用
1.使用环境DevC++ a.建立C++工程,并添加.\JsonCPP\jsoncpp-master\jsoncpp-master\src\lib_json中源文件到工程中. b.添加头文件路径 2. ...
- VCS使用学习笔记(0)——写在前面的话
由于毕业设计做的是数字IC相关,虽然不是纯设计,但是也有设计相关.有设计就要有仿真验证,我就趁此机会来学习一下VCS的使用吧.当然,这里只是学习其简单的逻辑仿真功能,从波形仿真到覆盖率等,基本上不涉其 ...
- 阿里云下Linux服务器安装Mysql、mongodb
阿里云下Linux服务器安装Mysql.mongodb 一.MySQL的安装和配置 1.安装rpm包 rpm -Uvh http://dev.mysql.com/get/mysql-community ...
- Linux:日期用法,及格式定义
在shell脚本中经常会需要获取当前日期的地方,linux的系统时间在shell里是可以直接调用系统变量: 获取今天时期---`date +%Y%m%d` 或 `date +%F` 或 $(date ...
- Resource 的 IsSealed 问题
WFP 的 Generic.xaml ,App.xaml 等中的资源会被调用 Freezable. 在后台对该资源进行修改等操作会被提示.资源为密封对象. 如果,确定需要在后台对资源进行修改. 则需要 ...