Innodb 锁系列2 事务锁
上一篇介绍了Innodb的同步机制锁:Innodb锁系列1
这一篇介绍一下Innodb的事务锁,只所以称为事务锁,是因为Innodb为实现事务的ACID特性,而添加的表锁或者行级锁。
这一部分分两篇来介绍,先来介绍下事务锁相关的数据结构
事务锁数据结构
1. 锁模式
/* Basic lock modes */
enum lock_mode {
LOCK_IS = , /* intention shared */
LOCK_IX, /* intention exclusive */
LOCK_S, /* shared */
LOCK_X, /* exclusive */
LOCK_AUTO_INC, /* locks the auto-inc counter of a table in an exclusive mode */
LOCK_NONE, /* this is used elsewhere to note consistent read */
LOCK_NUM = LOCK_NONE/* number of lock modes */
};
锁的模式包括两大类,共享锁(S)和互斥锁(X),s/x锁可以加在表上或者行记录上,
比如:
session1:alter table: table类型的X锁
session2:select * from table where id =1 for update: record类型的X锁
因为session1和session2互斥,为了实现在table表上阻塞,所以session2增加了表锁(IS),这样session2无法获取IS锁而阻塞。
LOCK_AUTO_INC:自增锁,为了保证在多行插入的时候,自增键值是连续的。
2. 表锁和记录锁数据结构
--表锁
struct lock_table_struct {
dict_table_t* table; /*!< database table in dictionary cache */
UT_LIST_NODE_T(lock_t) locks; /*!< list of locks on the same table */
};
--行锁
struct lock_rec_struct {
ulint space; /*!< space id */
ulint page_no; /*!< page number */
ulint n_bits; /*!< number of bits in the lock
bitmap; NOTE: the lock bitmap is
placed immediately after the
lock struct */
};
--锁记录
struct lock_struct {
trx_t* trx; /*!< transaction owning the lock */
UT_LIST_NODE_T(lock_t)
trx_locks; /*!< list of the locks of the transaction */
ulint type_mode; /*!< lock type, mode, LOCK_GAP or
LOCK_REC_NOT_GAP,
LOCK_INSERT_INTENTION,
wait flag, ORed */
hash_node_t hash; /*!< hash chain node for a record lock */
dict_index_t* index; /*!< index for a record lock */
union {
lock_table_t tab_lock;/*!< table lock */
lock_rec_t rec_lock;/*!< record lock */
} un_member; /*!< lock details */
};
表锁:使用表的数据字典进行标示,并保持一个链表,记录table上的所有锁记录。
记录锁:记录锁使用space+page_no唯一进行标示一个page页,n_bits标示这个页的记录,1表示加锁。
锁记录:lock_t表示一个锁记录,事务锁永远都和trx关联,trx_locks表示这个事务的所有锁记录。
3. 全局结构
/** The lock system struct */
struct lock_sys_struct{
hash_table_t* rec_hash; /*!< hash table of the record locks */
ulint rec_num;
}; /** The lock system */
extern lock_sys_t* lock_sys;
Innodb建立了一个全局的hash表,所有事务添加的锁,都记录在全局的事务表中,并使用record的space+page_no进行hash bucket的计算。入下图所示:

对于不同的space+page_no,通过hash key计算,映射到不同的bucket上,对于比如两条不同的update语句更新同一条记录的时候,不同的session,分别创建lock_t并加入到node1和node2中。这样就实现了所有的事务锁维护在hash+link的结构中。
不同的bucket互不影响,所有的wait,signal都通过相同的bucket下的链表来实现。
我们可以看一个函数就比较清楚了:
通过扫描hash结构+link结构来计算当前系统上有多少lock_t.
lock_get_n_rec_locks(void)
{
lock_t* lock;
ulint n_locks = ;
ulint i;
ut_ad(mutex_own(&kernel_mutex));
for (i = ; i < hash_get_n_cells(lock_sys->rec_hash); i++) {
lock = HASH_GET_FIRST(lock_sys->rec_hash, i);
while (lock) {
n_locks++;
lock = HASH_GET_NEXT(hash, lock);
}
}
return(n_locks);
}
注:所有的lock_t统计信息,以及锁的相容性测试对象,wait和signal的操作,都是通过这个全局结构进行实现的。
4. 锁的gap模式
#define LOCK_ORDINARY 0
#define LOCK_GAP 512
#define LOCK_REC_NOT_GAP 1024
行级锁实现的gap模式:
1. record lock:记录锁,根据索引记录锁主单行记录
2. gap lock:gap锁,锁住一个记录的区间
3. next-gap lock:包含了记录锁和gap锁
锁的gap模式主要为了实现以下:
1. 丢失更新:对于多事务更新相同的记录,需要记录锁保证事务间的互斥,防止丢失更新。
2. 可重复读:在read repeatable的事务隔离级别下,需要锁住记录的gap,来保证可重复读。
5. 隐式锁和显式锁
对于cluster index的记录锁而言,如select * from table where id=1 for update而言,会显示的在id=1的聚簇索引上添加行级锁。
如果是update语句,除了在cluster_index上添加锁以为,还需要在二级索引上添加锁。
但cluster index添加的是显示的锁,而二级索引使用隐式锁。
隐式锁: 是一种延迟的加锁方式,毕竟加锁是有开销的,所以使用一种乐观的方式,因为主键索引记录上有trx_id,如果判断主键记录上的trx_id是活动的事务,那么才加显示的锁。
这样,最大化的减少记录加锁的机会。
下一篇介绍具体的加锁过程:
Innodb 锁系列2 事务锁的更多相关文章
- MySQL锁系列2 表锁
http://www.cnblogs.com/xpchild/p/3789068.html 上一篇介绍了MySQL源码中保护内存结构或变量的锁,这里开始介绍下MySQL事务中的表锁. 注1: 在表 ...
- MySQL锁系列3 MDL锁
http://www.cnblogs.com/xpchild/p/3790139.html MySQL为了保护数据字典元数据,使用了metadata lock,即MDL锁,保证在并发的情况下,结构 ...
- MySQL · 引擎特性 · InnoDB 事务锁简介
https://yq.aliyun.com/articles/4270# zhaiwx_yinfeng 2016-02-02 19:00:43 浏览2194 评论0 mysql innodb lock ...
- mysql 开发进阶篇系列 7 锁问题(innodb锁争用情况及锁模式)
1 .获取innodb行锁争用情况 1.1 通过检查innodb_row_lock状态变量来分析系统上的行锁的争夺情况 SHOW STATUS LIKE 'innodb_row_lock%' 通过in ...
- InnoDB锁问题 & DB事务隔离级别
<参考:http://www.cnblogs.com/jack204/archive/2012/06/09/2542940.html>InnoDB行锁实现方式InnoDB行锁是通过给索引上 ...
- 高并发场景系列(一) 利用redis实现分布式事务锁,解决高并发环境下减库存
原文:http://blog.csdn.net/heyewu4107/article/details/71009712 高并发场景系列(一) 利用redis实现分布式事务锁,解决高并发环境下减库存 问 ...
- innodb事务锁
计算机程序锁 控制对共享资源进行并发访问 保护数据的完整性和一致性 lock 主要是事务,数据库逻辑内容,事务过程 latch/mutex 内存底层锁: 更新丢失 原因: B的更改还没有 ...
- innodb事务锁的一些常见数据结构
lock_sys_t 整个innodb的锁系统管理结构体,定义在lock0lock.h中.在lock0lock.cc中有一个lock_sys_t的全局指针lock_sys, 由lock_sys_cre ...
- (转)MySQL优化笔记(八)--锁机制超详细解析(锁分类、事务并发、引擎并发控制)
当一个系统访问量上来的时候,不只是数据库性能瓶颈问题了,数据库数据安全也会浮现,这时候合理使用数据库锁机制就显得异常重要了. 原文:http://www.jianshu.com/p/163c96983 ...
随机推荐
- mac下安装pcntl
Now you need to find out what version of PHP is installed on OSX $ php -vPHP 5.3.10 with Suhosin-Pa ...
- 51nod1212无向图最小生成树
1212 无向图最小生成树 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树. Inpu ...
- aliexpress 上传图
首先,图片转化为字节流 public byte[] ImagefileToByte(string srcImagePath) { System.IO.MemoryStream m = new Syst ...
- hdu 5343 MZL's Circle Zhou SAM
MZL's Circle Zhou 题意:给定两个长度不超过a,b(1 <= |a|,|b| <= 90000),x为a的连续子串,b为y的连续子串(x和y均可以是空串):问x+y形成的不 ...
- PS 颜色表大全-CMYK颜色表(2)
CMYK颜色表 编号 C M Y K R G B 16进制值 1 0 100 100 45 139 0 22 8B0016 2 0 100 100 25 178 0 31 B2001F 3 0 100 ...
- 过滤菜鸟的iOS面试题-b
网上已经有很多针对各种知识点的面试题,面试时有些人未必真正理解也能通过背题看上去很懂.我自己总结了4道面试题,好快速的判断这个人是否是一个合格的工程师,欢迎大家点评. 1.struct和class的区 ...
- iOS 支付宝应用(备用参考)
1:先与支付宝签约,获得商户ID(partner)和账号ID(seller) 2:下载相应的公钥私钥文件(加密签名用) 3:下载支付宝SDK 4:生成订单信息5:调用支付宝客户端,由支付宝客户端跟支付 ...
- kindeditor-4.1.10 结合 Asp.Net MVC 添加图片功能
KindEditor是一套开源的HTML可视化编辑器,现在我要结合Asp.Net MVC4 上传图片功能,做相应的配置和修改, 其实网上也有人写过类似的文章了,我写出来是以防以后使用的时候出现这样的问 ...
- MySQL 主主同步配置和主从配置步骤
★预备知识 : 1.双机热备 对于双机热备这一概念,我搜索了很多资料,最后,还是按照大多数资料所讲分成广义与狭义两种意义来说. 从广义上讲,就是对于重要的服务,使用两台服务器,互相备份,共同执行同一服 ...
- 汇编之FS段寄存器
FS寄存器指向当前活动线程的TEB结构(线程结构) 偏移 说明 000 指向SEH链指针 004 线程堆栈顶部 008 线程堆栈底部 00C SubSystemTib 010 FiberD ...