Mysql
MySql1. 事务的四大特性?
事务特性ACID:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。
1.原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚。
2.一致性是指一个事务执行之前和执行之后都必须处于一致性状态。比如a与b账户共有1000块,两人之间转账之后无论成功还是失败,
它们的账户总和还是1000。
3.隔离性。跟隔离级别相关,如read committed,一个事务只能读到已经提交的修改。
4.持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提 交事务的操作。
2. 事务隔离级别有哪些?
先了解下几个概念:脏读、不可重复读、幻读。
脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。
不可重复读是指在对于数据库中的某行记录,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,另一个事务修改了数据并提交了。
幻读是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行,就像产生幻觉一样,这就是发生了幻读。
不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。
幻读和不可重复读都是读取了另一条已经提交的事务,不同的是不可重复读的重点是修改,幻读的重点在于新增或者删除。
事务隔离就是为了解决上面提到的脏读、不可重复读、幻读这几个问题。
MySQL数据库为我们提供的四种隔离级别:
Serializable (串行化):通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。
Repeatable read (可重复读):MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读
取数据时,会看到同样的数据行,解决了不可重复读的问题。
Read committed (读已提交):一个事务只能看见已经提交事务所做的改变。可避免脏读的发生。
Read uncommitted (读未提交):所有事务都可以看到其他未提交事务的执行结果。
查看隔离级别:
select @@transaction_isolation;
设置隔离级别:
set session transaction isolation level read uncommitted;
3. 索引
3.1. 什么是索引?
索引是存储引擎用于提高数据库表的访问速度的一种数据结构。
3.2. 索引的优缺点?
优点:
加快数据查找的速度
为用来排序或者是分组的字段添加索引,可以加快分组和排序的速度
加速表与表之间的连接
缺点:
建立索引需要占用物理空间
会降低表的增删改的效率,因为每次对表记录进行增删改,需要进行动态维护索引,导致增删改时
间变长
3.3. 索引的作用?
数据是存储在磁盘上的,查询数据时,如果没有索引,会加载所有的数据到内存,依次进行检索,读取
磁盘次数较多。有了索引,就不需要加载所有数据,因为B+树的高度一般在2-4层,最多只需要读取2-4
次磁盘,查询速度大大提升。
select @@transaction_isolation;
set session transaction isolation level read uncommitted;
3.4. 什么情况下需要建索引?
[*]经常用于查询的字段
[*]经常用于连接的字段(如外键)建立索引,可以加快连接的速度
[*]经常需要排序的字段建立索引,因为索引已经排好序,可以加快排序查询速度
3.5. 什么情况下不建索引?
[*]where条件中用不到的字段不适合建立索引
[*]表记录较少
[*]需要经常增删改
[*]参与列计算的列不适合建索引
[*]区分度不高的字段不适合建立索引,性别等
3.6. 索引的数据结构
索引的数据结构主要有B+树和哈希表,对应的索引分别为B+树索引和哈希索引。InnoDB引擎的索引类
型有B+树索引和哈希索引,默认的索引类型为B+树索引。
B+****树索引
B+ 树是基于B 树和叶子节点顺序访问指针进行实现,它具有B树的平衡性,并且通过顺序访问指针来提
高区间查询的性能。
在 B+ 树中,节点中的 key 从左到右递增排列,如果某个指针的左右相邻 key 分别是 keyi 和 keyi+1,则
该指针指向节点的所有 key 大于等于 keyi 且小于等于 keyi+1。
进行查找操作时,首先在根节点进行二分查找,找到key所在的指针,然后递归地在指针所指向的节点进
行查找。直到查找到叶子节点,然后在叶子节点上进行二分查找,找出 key 所对应的数据项。
3.7. Hash索引和B+树索引的区别?
哈希索引不支持排序,因为哈希表是无序的。
哈希索引不支持范围查找。
哈希索引不支持模糊查询及多列索引的最左前缀匹配。
因为哈希表中会存在哈希冲突,所以哈希索引的性能是不稳定的,而B+树索引的性能是相对稳定
的,每次查询都是从根节点到叶子节点。
3.8. 为什么B+树比B树更适合实现数据库索引?
由于B+树的数据都存储在叶子结点中,叶子结点均为索引,方便扫库,只需要扫一遍叶子结点即
可,但是B树因为其分支结点同样存储着数据,我们要找到具体的数据,需要进行一次中序遍历按
序来扫,所以B+树更加适合在区间查询的情况,而在数据库中基于范围的查询是非常频繁的,所以
通常B+树用于数据库索引。
B+树的节点只存储索引key值,具体信息的地址存在于叶子节点的地址中。这就使以页为单位的索
引中可以存放更多的节点。减少更多的I/O支出。
B+树的查询效率更加稳定,任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查
询的路径长度相同,导致每一个数据的查询效率相当。
3.9. 索引有什么分类?
[*]主键索引:名为primary的唯一非空索引,不允许有空值。
[*]唯一索引:索引列中的值必须是唯一的,但是允许为空值。唯一索引和主键索引的区别是:
UNIQUE 约束的列可以为null且可以存在多个null值。UNIQUE KEY的用途:唯一标识数据库表中
的每条记录,主要是用来防止数据重复插入。创建唯一索引的SQL语句如下:
[*]组合索引:在表中的多个字段组合上创建的索引,只有在查询条件中使用了这些字段的左边字段
时,索引才会被使用,使用组合索引时遵循最左前缀原则。
[*]全文索引:只有在MyISAM引擎上才能使用,只能在CHAR,VARCHAR,TEXT类型字段上使用全文索
引。
3.10. 什么是最左匹配原则?
如果 SQL 语句中用到了组合索引中的最左边的索引,那么这条 SQL 语句就可以利用这个组合索引去进
行匹配。当遇到范围查询(>、 3 and d = 4 ,那么,a,b,c三个字段能
用到索引,而d就匹配不到。因为遇到了范围查询!
Index_comment:
Visible: YES
Expression: NULL
ALTER TABLE table_name
ADD CONSTRAINT constraint_name UNIQUE KEY(column_1,column_2,...);如下图,对(a, b) 建立索引,a 在索引树中是全局有序的,而 b 是全局无序,局部有序(当a相等时,会
对b进行比较排序)。直接执行 b = 2 这种查询条件没有办法利用索引。
从局部来看,当a的值确定的时候,b是有序的。例如a = 1时,b值为1,2是有序的状态。当a=2时候,b
的值为1,4也是有序状态。 因此,你执行 a = 1 and b = 2 是a,b字段能用到索引的。而你执行 a > 1
and b = 2 时,a字段能用到索引,b字段用不到索引。因为a的值此时是一个范围,不是固定的,在这
个范围内b值不是有序的,因此b字段用不上索引。
3.11. 什么是聚集索引?
InnoDB使用表的主键构造主键索引树,同时叶子节点中存放的即为整张表的记录数据。聚集索引叶子节
点的存储是逻辑上连续的,使用双向链表连接,叶子节点按照主键的顺序排序,因此对于主键的排序查
找和范围查找速度比较快。
聚集索引的叶子节点就是整张表的行记录。InnoDB 主键使用的是聚簇索引。聚集索引要比非聚集索引
查询效率高很多。
对于InnoDB来说,聚集索引一般是表中的主键索引,如果表中没有显示指定主键,则会选择表中的第一
个不允许为NULL的唯一索引。如果没有主键也没有合适的唯一索引,那么innodb内部会生成一个隐藏
的主键作为聚集索引,这个隐藏的主键长度为6个字节,它的值会随着数据的插入自增。
3.12. 什么是覆盖索引?
select的数据列只用从索引中就能够取得,不需要回表进行二次查询,换句话说查询列要被所使用的索
引覆盖。对于innodb表的二级索引,如果索引能覆盖到查询的列,那么就可以避免对主键索引的二次查
询。
不是所有类型的索引都可以成为覆盖索引。覆盖索引要存储索引列的值,而哈希索引、全文索引不存储
索引列的值,所以MySQL只能使用b+树索引做覆盖索引。
对于使用了覆盖索引的查询,在查询前面使用explain,输出的extra列会显示为 using index 。
比如 user_like 用户点赞表,组合索引为(user_id, blog_id),user_id和blog_id都不为null。
Extra中为 Using index ,查询的列被索引覆盖,并且where筛选条件符合最左前缀原则,通过索引查
找就能直接找到符合条件的数据,不需要回表查询数据。
Extra中为 Using where; Using index , 查询的列被索引覆盖,where筛选条件不符合最左前缀原
则,无法通过索引查找找到符合条件的数据,但可以通过索引扫描找到符合条件的数据,也不需要回表
查询数据。
3.13. 索引的设计原则?
索引列的区分度越高,索引的效果越好。比如使用性别这种区分度很低的列作为索引,效果就会很
差。
尽量使用短索引,对于较长的字符串进行索引时应该指定一个较短的前缀长度,因为较小的索引涉
及到的磁盘I/O较少,并且索引高速缓存中的块可以容纳更多的键值,会使得查询速度更快。
索引不是越多越好,每个索引都需要额外的物理空间,维护也需要花费时间。
利用最左前缀原则。
3.14. 索引什么时候会失效?
导致索引失效的情况:
对于组合索引,不是使用组合索引最左边的字段,则不会使用索引
以%开头的like查询如 %abc ,无法使用索引;非%开头的like查询如 abc% ,相当于范围查询,会使
用索引
查询条件中列类型是字符串,没有使用引号,可能会因为类型不同发生隐式转换,使索引失效
判断索引列是否不等于某个值时
explain select blog_id from user_like where user_id = 13;
explain select user_id from user_like where blog_id = 1;对索引列进行运算
查询条件使用or连接,也会导致索引失效
3.15. 什么是前缀索引?
有时需要在很长的字符列上创建索引,这会造成索引特别大且慢。使用前缀索引可以避免这个问题。
前缀索引是指对文本或者字符串的前几个字符建立索引,这样索引的长度更短,查询速度更快。
创建前缀索引的关键在于选择足够长的前缀以保证较高的索引选择性。索引选择性越高查询效率就越
高,因为选择性高的索引可以让MySQL在查找时过滤掉更多的数据行。
// email列创建前缀索引
ALTER TABLE table_name ADD KEY(column_name(prefix_length));4.常见的存储引擎
MySQL中常用的四种存储引擎分别是: MyISAM存储引擎、innoDB存储引擎、MEMORY存储引擎、
ARCHIVE存储引擎。MySQL 5.5版本后默认的存储引擎为InnoDB。
InnoDB****存储引擎
InnoDB是MySQL默认的事务型存储引擎,使用最广泛,基于聚簇索引建立的。InnoDB内部做了很多优
化,如能够自动在内存中创建自适应hash索引,以加速读操作。
优点:支持事务和崩溃修复能力。InnoDB引入了行级锁和外键约束。
缺点:占用的数据空间相对较大。
适用场景:需要事务支持,并且有较高的并发读写频率。
MyISAM****存储引擎
数据以紧密格式存储。对于只读数据,或者表比较小、可以容忍修复操作,可以使用MyISAM引擎。
MyISAM会将表存储在两个文件中,数据文件.MYD和索引文件.MYI。
优点:访问速度快。
缺点:MyISAM不支持事务和行级锁,不支持崩溃后的安全恢复,也不支持外键。
适用场景:对事务完整性没有要求;只读的数据,或者表比较小,可以忍受修复repair操作。
MyISAM特性:
[*]MyISAM对整张表加锁,而不是针对行。读取数据时会对需要读到的所有表加共享锁,写入时则对
表加排它锁。但在读取表记录的同时,可以往表中插入新的记录(并发插入)。
[*]对于MyISAM表,MySQL可以手动或者自动执行检查和修复操作。执行表的修复可能会导致数据丢
失,而且修复操作非常慢。可以通过 CHECK TABLE tablename 检查表的错误,如果有错误执行
REPAIR TABLE tablename 进行修复。
MEMORY****存储引擎
MEMORY引擎将数据全部放在内存中,访问速度较快,但是一旦系统奔溃的话,数据都会丢失。
MEMORY引擎默认使用哈希索引,将键的哈希值和指向数据行的指针保存在哈希索引中。
优点:访问速度较快。
缺点:
// email列创建前缀索引
ALTER TABLE table_name ADD KEY(column_name(prefix_length));
[*]哈希索引数据不是按照索引值顺序存储,无法用于排序。
[*]不支持部分索引匹配查找,因为哈希索引是使用索引列的全部内容来计算哈希值的。
[*]只支持等值比较,不支持范围查询。
[*]当出现哈希冲突时,存储引擎需要遍历链表中所有的行指针,逐行进行比较,直到找到符合条件的
行。
ARCHIVE****存储引擎
该存储引擎非常适合存储大量独立的、作为历史记录的数据。ARCHIVE提供了压缩功能,拥有高效的插
入速度,但是这种引擎不支持索引,所以查询性能较差。
5. MyISAM和InnoDB的区别?
[*]是否支持行级锁 : MyISAM 只有表级锁,而 InnoDB 支持行级锁和表级锁,默认为行级锁。
[*]是否支持事务和崩溃后的安全恢复: MyISAM 注重性能,每次查询具有原子性,其执行速度比
InnoDB 类型更快,但是不提供事务支持。而 InnoDB 提供事务支持,具有事务、回滚和崩溃修复
能力。
[*]是否支持外键: MyISAM 不支持,而 InnoDB 支持。
[*]是否支持MVCC : MyISAM 不支持, InnoDB 支持。应对高并发事务,MVCC比单纯的加锁更高
效。
[*]MyISAM 不支持聚集索引, InnoDB 支持聚集索引。
MyISAM 引擎主键索引和其他索引区别不大,叶子节点都包含索引值和行指针。
innoDB 引擎二级索引叶子存储的是索引值和主键值(不是行指针),这样可以减少行移动和
数据页分裂时二级索引的维护工作。
6.MVCC实现原理
MVCC( Multiversion concurrency control ) 就是同一份数据保留多版本的一种方式,进而实现并发
控制。在查询的时候,通过read view和版本链找到对应版本的数据。作用:提升并发性能。对于高并发场景,MVCC比行级锁更有效、开销更小。
MVCC 实现原理如下:
MVCC 的实现依赖于版本链,版本链是通过表的三个隐藏字段实现。
DB_TRX_ID :当前事务id,通过事务id的大小判断事务的时间顺序。
DB_ROLL_PRT :回滚指针,指向当前行记录的上一个版本,通过这个指针将数据的多个版本连接
在一起构成undo log版本链。
DB_ROLL_ID :主键,如果数据表没有主键,InnoDB会自动生成主键。
每条表记录大概是这样的:
使用事务更新行记录的时候,就会生成版本链,执行过程如下:
[*]用排他锁锁住该行;
[*]将该行原本的值拷贝到 undo log,作为旧版本用于回滚;
[*]修改当前行的值,生成一个新版本,更新事务id,使回滚指针指向旧版本的记录,这样就形成一条
版本链。
下面举个例子方便大家理解。
[*]初始数据如下,其中DB_ROW_ID和DB_ROLL_PTR为空。
[*]事务A对该行数据做了修改,将age修改为12,效果如下:
[*]之后事务B也对该行记录做了修改,将age修改为8,效果如下:
[*]此时undo log有两行记录,并且通过回滚指针连在一起。
接下来了解下read view的概念。
read view 可以理解成对数据在每个时刻的状态拍成“照片”记录下来。这样获取某时刻的数据时就还是
原来的”照片“上的数据,是不会变的。
在 read view 内部维护一个活跃事务链表,表示生成 read view 的时候还在活跃的事务。这个链表包
含在创建 read view 之前还未提交的事务,不包含创建 read view 之后提交的事务。
不同隔离级别创建read view的时机不同。
read committed:每次执行select都会创建新的read_view,保证能读取到其他事务已经提交的修
改。
repeatable read:在一个事务范围内,第一次select时更新这个read_view,以后不会再更新,后
续所有的select都是复用之前的read_view。这样可以保证事务范围内每次读取的内容都一样,即
可重复读。
read view的记录筛选方式
前提: DATA_TRX_ID 表示每个数据行的最新的事务ID; up_limit_id 表示当前快照中的最先开始的事
务; low_limit_id 表示当前快照中的最慢开始的事务,即最后一个事务。
如果 DATA_TRX_ID < up_limit_id :说明在创建 read view 时,修改该数据行的事务已提交,该
版本的记录可被当前事务读取到。
如果 DATA_TRX_ID >= low_limit_id :说明当前版本的记录的事务是在创建 read view 之后生
成的,该版本的数据行不可以被当前事务访问。此时需要通过版本链找到上一个版本,然后重新判
断该版本的记录对当前事务的可见性。
如果 up_limit_iddelete。</ol>23. having和where区别?
二者作用的对象不同,where子句作用于表和视图,having作用于组。
WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。
24. 什么是MySQL主从同步?
主从同步使得数据可以从一个数据库服务器复制到其他服务器上,在复制数据时,一个服务器充当主服
务器(master),其余的服务器充当从服务器(slave)。
因为复制是异步进行的,所以从服务器不需要一直连接着主服务器,从服务器甚至可以通过拨号断断续
续地连接主服务器。通过配置文件,可以指定复制所有的数据库,某个数据库,甚至是某个数据库上的
某个表。
25. 为什么要做主从同步?
[*]读写分离,使数据库能支撑更大的并发。
[*]在主服务器上生成实时数据,而在从服务器上分析这些数据,从而提高主服务器的性能。
[*]数据备份,保证数据的安全。
26. 乐观锁和悲观锁是什么?
数据库中的并发控制是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及
数据库的统一性。乐观锁和悲观锁是并发控制主要采用的技术手段。
悲观锁:假定会发生并发冲突,在查询完数据的时候就把事务锁起来,直到提交事务。实现方式:
使用数据库中的锁机制。
乐观锁:假设不会发生并发冲突,只在提交操作时检查是否数据是否被修改过。给表增加version
字段,在修改提交之前检查version与原来取到的version值是否相等,若相等,表示数据没有被修
改,可以更新,否则,数据为脏数据,不能更新。实现方式:乐观锁一般使用版本号机制或CAS算
法实现。
27. 用过processlist吗?
show processlist 或 show full processlist 可以查看当前 MySQL 是否有压力,正在运行的
sql,有没有慢 SQL 正在执行。返回参数如下:
id - 线程ID,可以用: kill id; 杀死一个线程,很有用
db - 数据库
user - 用户host - 连库的主机IP
command - 当前执行的命令,比如最常见的:Sleep,Query,Connect 等
time - 消耗时间,单位秒,很有用
state - 执行状态
sleep,线程正在等待客户端发送新的请求
query,线程正在查询或者正在将结果发送到客户端
Sorting result,线程正在对结果集进行排序
Locked,线程正在等待锁
info - 执行的SQL语句,很有用
28.锁
锁是计算机为了协调多个进程或线程并发访问某个资源的机制。
按照锁的粒度分为三类:
[*]全局锁:锁定数据库中的所有表,做全库的逻辑备份,对所有表进行锁定
[*]表级锁:锁住整张表
[*]行级锁:锁住对应的行数据
28.1表级锁
28.1.1表锁
表锁分为两类:
[*]共享锁(读锁):允许不同事务加入共享锁读取,阻止其他事务修改或加入排他锁。
[*]排他锁(写锁):允许获取排他锁的事务更新数据,阻止其他事务共享读锁和排他写锁。
读锁不会阻塞其他客户端的读,但是会阻塞写;写锁既会阻塞其他客户端的读,又会阻塞其他客户端的写。
SELECT... FOR UPDATE 使用注意事项:
insert into user(user_name, user_password, user_mail, user_state)
values('tyson', 'a', 'a', 0);
update user set user_name = 'a';
select * from table where id<6 lock in share mode;--共享锁
select * from table where id<6 for update;--排他锁28.1.2元数据锁(MDL)
MDL加锁过程是系统自动控制,不需要显式使用,访问一张表时会自动加上。MDL锁主要作用时维护表元数据(表结构)的数据一致性,在表上有活动事务的时候,不可以对元数据进行写操作。简单来说,表存在未提交的事务,不可以去修改表的结构。为了避免DML与DDL冲突,保证读写的正确性。
在MySQL5.5中引入了MDL,当对一个表做 增删改查操作 的时候,加MDL 读锁;当 要对表做结构变更操作的时候,加MDL写锁,会阻塞全部。
CREATE TABLE test_range_partition(
id INT auto_increment,
createdate DATETIME,
primary key (id,createdate)
)
PARTITION BY RANGE (TO_DAYS(createdate) ) (
PARTITION p201801 VALUES LESS THAN ( TO_DAYS('20180201') ),
PARTITION p201802 VALUES LESS THAN ( TO_DAYS('20180301') ),
PARTITION p201803 VALUES LESS THAN ( TO_DAYS('20180401') ),
PARTITION p201804 VALUES LESS THAN ( TO_DAYS('20180501') ),
PARTITION p201805 VALUES LESS THAN ( TO_DAYS('20180601') ),
PARTITION p201806 VALUES LESS THAN ( TO_DAYS('20180701') ),在 /var/lib/mysql/data/ 可以找到对应的数据文件,每个分区表都有一个使用#分隔命名的表文
件:28.1.3意向锁
举个例子,线程A先开启事务,执行update操作,然后它会对这一行加上行锁,紧接着它会对这整张表加上意向锁。之后,线程B来对这张表进行加表锁,此时它检查这张表意向锁的情况,如果当前加的锁与意向锁兼容就会成功,不兼容就会处于阻塞状态,阻塞到线程A的事务提交,释放行锁和意向锁。
[*]意向共享锁(IS):事务有意向对表中的某些行加共享锁,必须先取得该表的IS锁。
[*]意向排它锁(IX):事务有意向对表中的某些行加排他锁,必须先取得该表的IX锁。
意向共享锁(IS)意向排他锁(IX)表共享锁(S)兼容互斥表排它锁(X)互斥互斥
[*]意向锁不会与行锁互斥。
PARTITION p201807 VALUES LESS THAN ( TO_DAYS('20180801') ),
PARTITION p201808 VALUES LESS THAN ( TO_DAYS('20180901') ),
PARTITION p201809 VALUES LESS THAN ( TO_DAYS('20181001') ),
PARTITION p201810 VALUES LESS THAN ( TO_DAYS('20181101') ),
PARTITION p201811 VALUES LESS THAN ( TO_DAYS('20181201') ),
PARTITION p201812 VALUES LESS THAN ( TO_DAYS('20190101') )
);
-rw-r----- 1 MySQL MySQL 65 Mar 14 21:47 db.opt
-rw-r----- 1 MySQL MySQL 8598 Mar 14 21:50 test_range_partition.frm
-rw-r----- 1 MySQL MySQL 98304 Mar 14 21:50
test_range_partition#P#p201801.ibd
-rw-r----- 1 MySQL MySQL 98304 Mar 14 21:50
test_range_partition#P#p201802.ibd
-rw-r----- 1 MySQL MySQL 98304 Mar 14 21:50
test_range_partition#P#p201803.ibd
...
create table test_list_partiotion
(
id int auto_increment,
data_type tinyint,
primary key(id,data_type)
)partition by list(data_type)
(
partition p0 values in (0,1,2,3,4,5,6),
partition p1 values in (7,8,9,10,11,12),
partition p2 values in (13,14,15,16,17)
);
create table test_hash_partiotion
(
id int auto_increment,
create_date datetime,
primary key(id,create_date)
)partition by hash(year(create_date)) partitions 10;
[*]意向锁解决的问题:意向锁是由InnoDB引擎来完成的,意向锁的存在使得在加表锁的过程中,不再需要去对每行数据检查是否加锁,使用意向锁来减少表锁的检查。为了避免DML在执行时,加的行锁与表锁的冲突。
28.2行级锁
InnoDB的数据是基于索引组织的,行锁是通过对索引上的索引项加锁来实现的,而不是对记录加的锁。InnoDB行锁分为3种情形。
[*]行锁(Record Lock):对索引项加锁,防止其他事务的update、delete,在RC、RR的隔离级别下支持。
[*]间隙锁(Gap Lock):对索引项之间的“间隙”、第一条记录前的“间隙”或最后一条记录后的“间隙”加锁。
[*]临键锁(Next-Key Lock):行锁和间隙锁组合,对记录及前面的间隙加锁,在RR隔离级别下支持。
Gap锁/Next-key锁
默认情况下,InnoDB在RR隔离级别下运行,InnoDB使用next-key锁进行搜索和索引扫描,以防止幻读。
[*]索引上的等值查询(唯一查询),给不存在的记录加锁时,优化为间隙锁。
[*]索引上的等值查询(普通索引),向右遍历时最后一个值不满足查询需求时,next-key lock退化为间隙锁。
[*]索引上的范围查询(唯一索引),会访问到不满足条件的第一个值为止。
使用间隙锁的目的时防止其他事务插入间隙。间隙锁可以共存,一个事务采用的间隙锁不会阻止另一个事务在同一间隙上采用间隙锁。
来源:https://www.cnblogs.com/xw-01/p/18288970
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页:
[1]