[MySQL学习]Innodb锁相关描述翻译
以下翻译自lock0lock.c的文件头部注释,翻译的比较凌乱…
几个hardcode的宏:
LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECK |
1000000 |
该宏用于控制在事务的waits-for-graph中的查找深度 |
LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK |
200 |
用于控制死锁递归检测深度 |
LOCK_RELEASE_KERNEL_INTERVAL |
1000 |
在释放锁的过程中(lock_release_off_kernel),每隔这么多次循环释放kernel mutex |
LOCK_PAGE_BITMAP_MARGIN |
64 |
创建锁的bitmap至少有这么多个比特位 |
一个显式锁同时影响记录和记录前面的gap。一个隐式x锁不影响gap,只会锁住读活更新的索引记录。
如果一个事务修改或插入了一个索引记录,它拥有在该就上的隐式x锁。如果事务修改了聚集索引记录,会在二级索引记录上也有一个隐式x锁,二级索引记录所在的page上的事务id>=当前事务的trx id, 并且没有二级索引记录上的显式 非gap锁请求
这种对二级索引的相容性定义是根据其实现决定的:我们希望通过查看聚集索引记录来判断一个二级索引记录是否有一个隐式x锁,而不是根据二级索引记录的历史版本。
不同的事务可能同时在同一个GAP上产生冲突锁。在gap上的锁被单纯的禁止:无法插入,或者如果一个不同的事务在gap上有一个冲突的锁,一个select cutsor可能需要等待。GAP上的x锁并不意味着有权力向GAP中插入记录。
一个显式锁可以设置在一个用户记录或者supremum记录上。在supremum记录上的锁通常被认为是一个GAP锁,尽管GAP位没有设置。当我们修改一条记录并且修改了记录的大小时,可能会临时的将它的显式锁存储到infimum记录上,除此之外,不会在infimum记录上加锁。
一个正在等待的记录锁也可以是GAP类型;当在显式锁队列中,一个锁请求的前面没有另外一个冲突模式锁对象时,就可以获得锁。
RULE1:如果在记录上有一个隐式X锁,并且有一个non-gap锁请求在队列中等待,这时候持有隐式x锁的事务同样也会有一个显式的Non-gap记录X锁。这样当锁被释放时,我们只需要通过查看队列中的显式锁请求来为等待锁请求赋予锁
RULE3:不同的事务不可以在同一个记录上同时拥有冲突的NON-GAP锁。但是,他们可以拥有冲突的GAP锁。
RULE4:如果在队列中有一个等待的锁请求。没有锁请求,gap或者not-gap锁可以插入到队列中该等待锁请求前面。在记录删除和page分裂时,数据库管理者可以为一个事务创建新的gap类型的锁。如果没有RULE4,事务waits-for graph可能变成循环而数据库无法注意到这一点,因为死锁检测只有在一个事务本身请求一个锁时才发生。
当在下一个记录上没有其他事务持有的显式锁时,允许在GAP中插入记录。这些锁请求被赋予或等待,gap位是否被设置都无所谓,除了另外一个事务的gap类型请求,并且正在等待轮到他去插入时,会被忽略掉。换句话说,一个其他事务持有的隐式X锁不会阻止一次写入,这允许在是用类似ORACLE序列生成器为许多事务并发产生主键,这会允许更大的并发度。
如果事务在记录上有X锁,或者其他事务没有在该记录上任何non-gap锁时,则允许该事务修改记录
如果事务有一个Non-gap显式、或者隐式锁在记录上,或者其他事务有在该记录上的非X锁请求,则允许是用一个cursor读取一个用户记录。在一个page上supremum总是允许被读。
总的来说,一个隐式锁看起来仅仅像是在一个记录上被赋予的X锁,而不是在GAP上。一个没有设置GAP位的显示锁是一个同时在记录和GAP上的锁。如果设置了GAP位,则表明锁只在GAP上。不同的事务不可以在同一时间拥有相互冲突的锁。但可以在GAP上拥有冲突的锁。被赋予的记录锁允许操作记录的权限,但gap类型的锁仅仅禁止操作。
注意:如果一些事务在一个二级索引记录上拥有隐式x锁,这种情况比较难处理。我们可能需要查看对应聚集索引记录的前面的版本,以查找一个被标记删除的二级索引记录是否是被一个活跃的事务标记删除的,而不是一个已经提交的事务。
FACT A:如果一个事务已经插入了一条记录,它可以在任何时候删除它,无需等待任何锁。
PROOF:事务拥有插入记录在每个索引记录上的隐式X锁,并且可以修改每个索引记录而无需等待。
FACTB:如果一个事务通过一个cursor产生结果集,它可以再次读取,并获取一些结果集合,如果它没有同事修改他们的话。因此没有幻读问题。如果被cursor访问到的按照字母序的最大记录被移除,一次锁等待可能会发生,其他情况则不会。
PROOF:当一次读cursor执行时,它会对扫描过的用户记录设置S锁,以及每个page supremum上一个gap类型的S锁。cursor必须等待直到它拥有了这些锁。这样其他事务就不可以在这些用户记录上加任何X锁,也不能修改用户记录。甚至其他事务不可以插入到cursor扫奥的GAP中。Page分裂和合并,或者移除废弃版本的记录不会受此影响,因为当一个用户记录或一个Page上的supremum被移除时,下一个记录继承 了其锁作为GAP类型,因此会阻塞插入到相同的GAP中。同样的,如果一个page supremum被插入,它从成功的记录那继承它的锁。当cursor被重新放置到结果集的起始位置时,它将查看到的记录是上次查看到的或者新插入的page supremums.它能够立刻获取这些记录,当到达最大的记录时,它注意到结果集已经完成。如果最大的记录被移除,可能需要等待锁,因此下一个记录只继承了GAP类型的锁,这时候需要等待。
如果一个索引记录可以被修改或者新的插入,我们必须检查该记录和下一个记录上的锁。当一个read cusor开始读数据时,我们会在每个经过的记录上设置一个记录级别的s锁,除了在开始获取记录之前cursor所在的初始化记录。我们的索引树查找约定B-TREE上的cursor在查询时被防止在第一个可能匹配的记录前面,这里可能会有一些优化:如果记录是通过唯一索引上的等值条件查找的,我们实际上设置了一个特殊的锁在记录上,这个锁不会阻止任何在该记录之前的插入。而一个记录上的next-key x Lock同样会阻止该记录之前的插入。
每个Page上有特殊的infimum和supremum记录。一个supremum记录可以被一个read curosr锁住。这个记录无法被更新,但这个锁可以阻止将用户记录插入到该Page的用户记录尾部(也就是最大的那个记录之后)
next-key锁也可以防止幻读,防止两次select的结果集不同,防止幻读保证了事务的串行化。
当需要插入一条新记录时,我们需要检查什么呢?只需要检查同一个Page上的下一条记录,因为supremum记录也会持有一个锁。一个S锁会阻止插入,但一个X锁呢?如果是由一个查询更新(searched update)加上的锁,这时候同样有一个隐式的s锁,插入会被阻止。但如果我们的事务拥有下一个记录的X锁,但在下一个记录上有一个等待的S锁请求呢?如果这个S锁是被一个在索引上升序移动的read cursor锁设置的,我们无法立刻做插入操作,因为当我们最终提交事务时,read cursor应该可以看到新插入的记录。所以我们应该跳到新插入记录的下一个记录。这种向后移动可能太难处理。如果我们正处于将在下一个记录上第二个x锁请求入队列的过程中,这时候死锁检测机制会发现我们的事务和其他持有s锁请求事务之间的死锁。这种解决方案看起来是Ok的。
我们可以约定赋予的显式记录锁,锁住对应的记录以避免修改,同时锁住记录前面的gap以避免插入。隐式记录x锁,根据聚集索引记录推导而来,只锁住记录本身,避免其被修改。而不会锁住记录前面GAP中的插入。
我们如何存储更新锁呢?如果查找是通过唯一键来完成的,我们仅仅修改对应记录的事务id。否则,我们可能在记录上放置一个x锁。如果update修改了聚集索引记录的顺序,新插入的新记录无需记录锁,事务Id已经足够了。对于一个二级索引记录而言同样如此。查找删除(searched delete)和update类似。
PROBLEM:
等待锁请求会怎么样呢?如果一个事务正在等待去更新其他事务已经修改的记录,其他事务如何发送一个end-lock-wait信号给他呢?如果我们约定一个事务每次只会等一个锁,在锁等待结束时如何进行保护呢?
PROBLEM:
检查一个二级索引记录的事务id。在做修改而非插入的时候,这是必要的吗?一个二级索引记录通过设置或充值删除标记来进行修改。一个二级索引记录包含了唯一标示对应聚集索引记录的列。因此一个二级索引记录被修改,同时聚集索引记录也被修改,在我们修改二级索引记录之前,在聚集索引记录上已经检查了 事务Id。所以在对一个二级索引设置删除标记位这样的操作,我们无需关系事务Id,只需要关心锁表中必须检查的锁。在从二级索引查询记录的情况,事务id是有用的,这种情况下我们还需要回查聚集索引记录。
PROBLEM:
在Page分裂、合并或者记录被删除/更新时。如何更新记录锁呢?如果一个记录的大小发生了变化,我们通过先删除再插入的方式来执行UPDATE。我们如何保持记录上的锁设置或锁等待呢。因为一个记录锁是通过记录的heap no在锁对象的bitmap中标记的,当我们从记录链表中移除记录时。可能仍然需要保持对应的锁Bit位。如果Page被重新组织了,我们可以生产一个用新记录和旧记录的heap no表,然后交换在锁对象中对应的bit。我们可以向表中增加一行来告诉更新的记录在哪里结束。如果更新无需重组织Page,我们就可以简单的把更新记录的锁bit转移到新的新的heap no上。
一种更复杂的情况是,重插入的更新记录是一种悲观操作,因为索引树的结构可能已经发生了变化。
PROBLEM:
如果一个supremum记录在一次page合并或者Purge被移除时,正在等待的锁请求该做什么呢?当把记录分裂到右边时,我们仅仅将锁请求移动到新的supremum上。如果一个记录被移除,我们可以将等待锁请求转移到它的继承者身上,也就是索引上的下一个记录。但是下一个记录本身可能在它的队列里已经有了锁请求。这时候会有新的死锁检测。可能释放等待的事务会更简单,他们会随后将锁请求设置到更合适的记录上,并加入到队列中。
PROBLEM:
当插入一个记录时,它应该从它上面的邻居继承什么样的锁呢?插入一个新的supremum记录,分裂总是可能发生的,但如果插入一个新的用户记录要求其上面的邻居没有其他任何事务的锁请求。解决办法:我们可以将锁作为GAP类型拷贝,这样所有等待锁被转换为已经赋予的在插入记录上的GAP类型锁。
[MySQL学习]Innodb锁相关描述翻译相关推荐
- mysql学习-Innodb行格式compact行记录解析
前言 了解行结构的意义: 知道设置好的主键可以节省空间 知道char的大小设置错误还不如varchar 知道字符集对变长字段类型的影响 知道null 和 空串的区别 还有一些-我还没发现 Compac ...
- mysql 锁设置_MySQL锁之二:锁相关的配置参数
锁相关的配置参数: mysql> SHOW VARIABLES LIKE '%timeout%';+-----------------------------+----------+ | Var ...
- MySQL锁相关面试题
对MySQL的锁了解吗? 当数据库有并发事务的时候,可能会产生数据的不一致,这时候需要一些机制来保证访问的次序,锁机制就是这样的一个机制. 例子:就像酒店的房间,如果大家随意进出,就会出现多人抢夺一个 ...
- mysql 聊聊InnoDB七种锁
前言 本文将跟大家聊聊InnoDB的锁.本文比较长,包括一条SQL是如何加锁的,一些加锁规则.如何分析和解决死锁问题等内容,建议耐心读完,肯定对大家有帮助的. 为什么需要加锁呢? InnoDB的七种锁 ...
- B站 MySQL学习随手记 全是满满的干货!
业务级别的MySQL学习与使用 1.数据库分类 1. 关系型数据库(SQL) MySQL,Oracle,SQL Server,DB2,SQLlite 通过表和表之间的,行与列之间的关系进行数据的存储. ...
- MySQL学习手册(第一部分)
Mysql学习手册(第一部分) (一)Mysql查询语法和执行顺序 1.1 查询语法顺序 1.2 查询执行顺序 1.3 WHERE条件顺序 (二)Mysql架构介绍 2.1 逻辑架构 2.1.1 Co ...
- MySQL学习笔记 04、MySQL进阶(索引、事务、锁)
文章目录 前言 一.MySQL的目录结构 1.1.认识目录文件 1.2.配置文件设置 windows平台下设置 linux环境下设置 二.MySQL的系统架构 2.1.MySQL系统的逻辑架构: 2. ...
- mysql 学习笔记
1 二.mysql操作 Day01 1.1 mysql 数据库的概述 1.1.1 数据库 Oracle(付费的,市场占有份额高,学习用不付费),DB2 MS Sql Server(微软开发的) MyS ...
- 『浅入浅出』MySQL 和 InnoDB
点击上方"方志朋",选择"置顶或者星标" 你的关注意义重大! 本文转载于公众号:真没什么逻辑 作为一名开发人员,在日常的工作中会难以避免地接触到数据库,无论是基 ...
- 数据库MYSQL学习系列三
数据库MYSQL学习系列三 三.MYSQL事务与存储引擎 3.1-数据库事务 什么是事务 一系列有序的数据库操作: o要么全部成功 o要么全部回退到操作前的状态 o中间状态对其他连接不可见 事务的 ...
最新文章
- html5+原生js画的瀑布,果然程序员不适合做设计吗?
- s7-200与计算机modbus通讯案例,【案例】S7-200SMART MODBUS通信介绍与实例编程
- shell中使用echo命令改变输出显示样式
- Python3引号创建字符串
- LINQ to Tree - A Generic Technique for Querying Tree-like Structures,包含遍历WPF VisualTree
- CSS3-多列布局-伸缩盒布局-伸缩项目
- 扫地机器人开机充电还是关机充电器_新手机是开机充电好,还是关机充电好,老司机告诉你...
- C++---之Arraylist
- python_四元数q转旋转矩阵R(已验证)
- 摘要算法、对称加密、非对称加密、数字签名、数字证书浅析
- 常用的API函数汇总
- OC 获取view相对位置_正版OC渲染器常见问题与解决方法
- HDU1166 敌兵布阵【线段树】题解
- 基于FPGA的正弦信号发生器设计
- android屏幕录制功能,Android利用ADB进行屏幕录制
- 如何查看linux系统版本
- 呱呱视频技术难点分享:遇到和填上的那些坑
- win10 mmdetection3d环境搭建
- ERP学习之路BOM篇
- 实验05 状态图与活动图
热门文章
- Atitit.软件开发的几大规则,法则,与原则。。。attilax总结
- paip. sip module implements API v10.0 to v10.1 but the PyQt4.QtCore module requires API v9.2
- Julia: feather格式和hdf5格式比较
- 2017:社保再选管理人基金公司争“主力”
- 进阶之路:Java 日志框架全画传(下)
- 5G时代下的移动边缘计算(MEC)探索系列之四
- OpenStack Queens版本Security项目介绍
- 【优化算法】气味代理优化算法(SAO)【含Matlab源码 1131期】
- 【声源定位】基于matlab阵列流形矩阵信号显示【含Matlab源码 549期】
- 【人脸识别】基于matlab GUI SVM和PCA人脸识别【含Matlab源码 369期】