未加星标

关于 MySQL InnoDB锁机制

字体大小 | |
[数据库(mysql) 所属分类 数据库(mysql) | 发布者 店小二04 | 时间 2017 | 作者 红领巾 ] 0人收藏点击收藏

一 背景

mysql锁机制是一个极其复杂的实现,为数据库并发访问和数据一致提供保障。这里仅仅针对MySQL访问数据的三种锁做介绍,加深自己对锁方面的掌握。

二 常见的锁机制

我们知道对于InnoDB存储引擎而言,MySQL 的行锁机制是通过在索引上加锁来锁定要目标数据行的。常见的有如下三种锁类型,本文未声明情况下都是在RR 事务隔离级别下的描述。

2.1 Record Locks

记录锁实际上是索引上的锁,锁定具体的一行或者多行记录。当表上没有创建索引时,InnoDB会创建一个隐含的聚族索引,并且使用该索引锁定数据。通常我们可以使用 show innodb status 看到行锁相关的信息。

2.2 Gap Locks

间隙锁是锁定具体的范围,但是不包含行锁本身。比如

select *from tab where id>10andid<20;

RR事务隔离级别下会锁定10-20之间的记录,不允许类似15这样的值插入到表里,以便消除“幻读”带来的影响。间隙锁的跨度可以是1条记录(Record low就可以认为是一个特殊的间隙锁 ,多行,或者为空。当访问的字段是唯一键/主键时,间隙锁会降级为Record lock。RR事务隔离级别下访问一个空行 ,也会有间隙锁,后续会举例子说明。

我们可以通过将事务隔离级别调整为RC 模式或者设置innodb_locks_unsafe_for_binlog=1 (该参数已经废弃)来禁用Gap锁。

2.3 Next-Key Locks

是Record Lock+Gap Locks,锁定一个范围并且包含索引本身。例如索引值包含 2,4,9,14 四个值,其gap锁的区间如下:

(-∞,2],(2,4],(4,9],(9,14],(14,+∞)

本文着重从主键,唯一键、非唯一索引,不存在值访问四个方面来阐述RR模式下锁的表现。

三 测试案例

3.1 主键/唯一键

CREATE TABLE `lck_primarkey` ( `id` int ( 11 ) NOT NULL , val int ( 11 ) not null default 0 , primary key ( ` id` ) , key idx_val ( val ) ) ENGINE = InnoDB DEFAULT CHARSET = utf8 ; insert into lck_primarkey values ( 2 , 3 ) , ( 4 , 5 ) , ( 9 , 8 ) , ( 14 , 13 )

会话1

[ session1 ] > select * from lck_primarkey ; + - - - - + - - - - - + | id | val | + - - - - + - - - - - + | 2 | 3 | | 4 | 5 | | 9 | 8 | | 14 | 13 | + - - - - + - - - - - + 4 rows in set ( 0 . 00 sec ) [ session1 ] > begin ; Query OK , 0 rows affected ( 0 . 00 sec ) [ session1 ] > select * from lck_primarkey where id = 9 for update ; + - - - - + - - - - - + | id | val | + - - - - + - - - - - + | 9 | 8 | + - - - - + - - - - - + 1 row in set ( 0 . 00 sec )

会话2

[ session2 ] > begin ; Query OK , 0 rows affected ( 0 . 00 sec ) [ session2 ] > insert into lck_primarkey values ( 7 , 6 ) ; Query OK , 1 row affected ( 0 . 00 sec ) [ session2 ] > insert into lck_primarkey values ( 5 , 5 ) ; Query OK , 1 row affected ( 0 . 00 sec ) [ session2 ] > insert into lck_primarkey values ( 13 , 13 ) ; Query OK , 1 row affected ( 0 . 00 sec ) [ session2 ] > insert into lck_primarkey values ( 10 , 9 ) ; Query OK , 1 row affected ( 0 . 00 sec )

分析

从例子看,当访问表的where字段是主键或者唯一键的时候,session2中的插入操作并未被 session1 中的id=8 影响。官方表述

“Gap locking is not needed for statements that lock rows using a unique index to search for a unique row . ( This does not include the case that the search condition includes only some columns of a multiple - column unique index ; in that case , gap locking does occur . ) For example , if the id column has a unique index , the following statement uses only an index

本文数据库(mysql)相关术语:navicat for mysql mysql workbench mysql数据库 mysql 存储过程 mysql安装图解 mysql教程 mysql 管理工具

主题: SQLInnoDBMySQL数据AU数据库
分页:12
转载请注明
本文标题:关于 MySQL InnoDB锁机制
本站链接:http://www.codesec.net/view/522587.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 数据库(mysql) | 评论(0) | 阅读(85)