这一篇主要是通过一个实验来进行描述,过程是比较枯燥的.
实验准备
create table test_lock(id int auto_increment primary key ,stock int) engine=innodb;
insert into test_lock(id,stock) value(1,50);
这里我把堆栈信息尽可能的简化,25个主要函数的名称和入参
后面为了突出主题,我对事务相关的函数加上这个开头死锁检测函数列表,一共10个函数
死锁检测函数列表A row_search_for_mysql(搜索行)
死锁检测函数列表B sel_set_rec_lock(判断是二级索引还是主键,然后对行加锁)
死锁检测函数列表C lock_clust_rec_read_check_and_lock(检查有锁堵塞)
死锁检测函数列表D lock_rec_lock 处理逻辑(检测锁的兼容性)
死锁检测函数列表E lock_rec_lock_slow处理逻辑(确认申请不到锁)
死锁检测函数列表F lock_rec_enqueue_waiting
死锁检测函数列表G lock_deadlock_check_and_resolve处理逻辑
死锁检测函数列表H lock_deadlock_search函数代码处理逻辑
死锁检测函数列表I lock_get_first_lock处理逻辑(第一个锁比较)
死锁检测函数列表J lock_get_next_lock函数代码处理逻辑(获取锁继续比较)
我们一个个来看这些函数的主要作用
死锁检测函数列表A row_search_for_mysql处理逻辑
作用:对数据库进行行的寻找
传入的参数是:
1.buf 缓存区,用于获取MySQl格式的行
2.mode 搜索的方式
3.prebuilt 预构表结构的相关信息
4.搜索的方向
返回结果:
@return DB_SUCCESS, DB_RECORD_NOT_FOUND, DB_END_OF_INDEX, DB_DEADLOCK,
DB_LOCK_TABLE_FULL, DB_CORRUPTION, or DB_TOO_BIG_RECORD */
在row_search_for_mysql搜索到行后,会对行进行加锁处理,也就是调用函数列表B sel_set_rec_lock处理逻辑
死锁检测函数列表B sel_set_rec_lock处理逻辑
作用:对一条记录进行加锁,返回结果为(DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code)
参数列表和备注
1.btr_pcur_get_block(pcur),记录对应的page的指针地址
2.rec:rec = btr_pcur_get_rec(pcur)对于的行的指针地址
3.index:prebuilt->index,表的索引
4.offsets:offsets是一个数组,默认100个元素,offsets = rec_get_offsets(next_rec, index, offsets,ULINT_UNDEFINED, &heap);
5.prebuilt->select_lock_type 表锁的类型(LOCK_NONE,LOCK_S, or LOCK_X)
6.lock_type:这里指的是行级锁(LOCK_REC_NOT_GAP,LOCK_GAP,LOCK_ORDINARY(Next-Key Lock))
7.thr:查询图查询线程节点 赋值thr = que_fork_get_first_thr(prebuilt->sel_graph);
死锁检测函数列表C lock_clust_rec_read_check_and_lock处理逻辑
作用:
检查其他事务的锁是否阻止立即读取或传递通过读取游标读取聚簇索引记录.
这个函数的作用主要是检查其他事务的锁是否堵塞了当前读,或者通过传递一个读取游标来读取主键索引记录。
如果他们这样做,首先测试
如果查询线程应该由于某种原因暂停;
如果没有,那么将事务和查询线程置于锁等待状态,并插入一个等待对锁队列的记录锁请求。
设置请求的模式锁定在记录上
死锁检测函数列表D 函数 lock_rec_lock 处理逻辑
作用:
尝试去对指定的行进行加锁,如果不能进行加锁,则进入lock_rec_lock_slow函数里面的处理逻辑
死锁检测函数列表E函数 lock_rec_lock_slow处理逻辑
作用:事务所请求的锁和别的事务有冲突(别人已经持有),进入lock_rec_enqueue_waiting进行处理
死锁检测函数列表F 函数 lock_rec_enqueue_waiting处理逻辑
作用:进入死锁检测函数lock_deadlock_check_and_resolve
死锁检测函数列表G 函数 lock_deadlock_check_and_resolve处理逻辑
作用:构造锁竞争的信息,然后把锁竞争的信息带入到lock_deadlock_search函数
死锁检测函数列表H函数 lock_deadlock_search函数代码处理逻辑
作用:通过锁竞争信息,对比两个事务对于的记录的heap_no,看两个事务所持有的锁是否为对方所需要的,进入到lock_get_first_lock来进行遍历
死锁检测函数列表I 函数lock_get_first_lock处理逻辑
作用:把参与锁竞争的事务的第一个锁来和另外一个事务等待的锁进行比较,如果检测到等值的锁则返回锁信息。
返回值:返回第一个锁或者NULL
死锁检测函数列表J lock_get_next_lock函数代码处理逻辑
作用:返回值,返回事务锁持有的下一个锁或者NULL
动态代理学习(二)JDK动态代理源码分析
上篇文章我们学习了如何自己实现一个动态代理,这篇文章我们从源码角度来分析下JDK的动态代理 先看一个Demo: public class MyInvocationHandler implements ...
MySQL主从复制配置指导及PHP读写分离源码分析
开发环境 master环境:ubuntu16.04.5LTS/i5/8G/500G/64位/mysql5.7.23/php7/apache2 slave环境:kvm虚拟机/ubuntu14.04.01 ...
Java I/O系列(二)ByteArrayInputStream与ByteArrayOutputStream源码分析及理解
1. ByteArrayInputStream 定义 继承了InputStream,数据源是内置的byte数组buf,那read ()方法的使命(读取一个个字节出来),在ByteArrayInputS ...
equals和==方法比较(二)--Long中equals源码分析
接上篇,分析equals方法在Long包装类中的重写,其他类及我们自定义的类,同样可以根据需要重新equals方法. equals方法定义 equals方法是Object类中的方法,java中所有的对 ...
目标检测之yolo源码分析
三.配置文件详解(config.py) import os # 数据集路径,和模型检查点路径 # # path and dataset parameter # DATA_PATH = 'data' # ...
scrapy 源码解析 (二):启动流程源码分析(二) CrawlerProcess主进程
CrawlerProcess主进程 它控制了twisted的reactor,也就是整个事件循环.它负责配置reactor并启动事件循环,最后在所有爬取结束后停止reactor.另外还控制了一些信号操作 ...
Solr4.8.0源码分析(19)之缓存机制(二)
Solr4.8.0源码分析(19)之缓存机制(二) 前文介绍了Solr缓存的生命周期,重点介绍了Solr缓存的warn过程.本节将更深 ...
ConcurrenHashMap源码分析(二)
本篇博客的目录: 一:put方法源码 二:get方法源码 三:rehash的过程 四:总结 一:put方法的源码 首先,我们来看一下segment内部类中put方法的源码,这个方法它是segment片 ...
谈谈MySQL死锁 一
数据越来越和我们的生活离不开,数据在生命周期的各个阶段有着不同的痛点和需求以及特殊场景. CURD是数据的四大基本需求:写入,更新,读取,删除. 今天,来谈一谈死锁问题 死锁是高并发下MySQL不可回 ...
随机推荐
KALI Linux problems &; Study Red Hat | Ubuntu
Problem When you ask some website with https head.you may met the problem secure connection failed ...
轻松3步实现c#windowsform窗体美化
1.需要下载IrisSkin4.dll或者IrisSkin2.dll和ssk皮肤文件. 2.添加引用IrisSkin4.dll或者IrisSkin2.dll到项目中,将下载好的ssk皮肤文件复制到项目 ...
QTabWidget 使用方法
QTabWidget是Qt中的标签类,由于可切换到标签存在,大大的提高了软件可容纳的控件的数量,通过增加标签,我们几乎有用之不尽的空间,那么我们来看看这个类的一些基本用法: 声明控件: QTabWid ...
Scala HelloWorld
1) 使用MVN创建项目 mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtif ...
简单了解Flux,注意这是一个设计思想,是一个架构!!!!!
在RN开发中,我们总是需要去更改一个组件个数据(也就是所谓的状态),我们一般是采用是在初始化的函数constror()(好像拼错了) 在这个函数里面申明我们的初始化数据(状态)eg:this.stat ...
github进行修改
1)git status:可以让我们时刻掌握仓库当前的状态. 2)git diff [文件名]:查看改变的详细信息,显示的结果是Unix通用的diff格式. 步骤: 1.修改文件 2.通过git ad ...
Mac下截图快捷键
Cmd+Shift+3:全屏截图:截取整个屏幕,保存截图至桌面文件夹.Cmd+Shift+4:区域截图:鼠标光标变成带坐标的小十字,通过拖拽截取特定区域,保存截图至桌面文件夹.Cmd+Shift+4 ...
Java 适配器(Adapter)模式
一.什么是适配器模式: 把一个接口变成另外一个接口,使得原本因接口不匹配无法一起工作的两个类一起工作. 二.适配器模式的分类和结构: 适配器模式有类的适配器模式和对象的适配器模式两种. 1.类的适配器 ...
Java基本数据类型总结、类型转换、常量的声明规范,final关键字的用法
1 Java 基本数据类型 变量就是申请内存来存储值.也就是说,当创建变量的时候,需要在内存中申请空间. 内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据. 因此,通过 ...
react Immutability 理解
在开发过程中经常会遇到state里有数组和对象的情况,比如当用splice去改变数组再调用setState更新的时候,会发现并没有生效,这是因为react里的state是Immutability(不可 ...