38
厦厦厦厦厦厦厦厦厦厦 http://dblab.xmu.edu.cn 厦厦厦 2014 厦 5 厦 17 厦 MySQL 厦厦厦厦厦厦

厦门大学数据库实验室 dblab.xmu

  • Upload
    kawena

  • View
    645

  • Download
    0

Embed Size (px)

DESCRIPTION

厦门大学数据库实验室 http://dblab.xmu.edu.cn. MySQL 加锁处理分析. 赖明星 2014 年 5 月 17 日. 目录. 学习目标. 背景知识. 简单 SQL 语句加锁分析. 复杂 SQL 语句加锁分析. 总结. 学习目标. 1. 理解锁的概念与锁的类型 理解加锁操作涉及到的考虑因素 理解 lock 与 latch 的区别 能够分析简单的 SQL 语句的加锁情况. 目录. 学习目标. 背景知识. 简单 SQL 语句加锁分析. 复杂 SQL 语句加锁分析. 总结. 背景知识. 2. 事务的 ACID 特性 - PowerPoint PPT Presentation

Citation preview

Page 1: 厦门大学数据库实验室 dblab.xmu

厦门大学数据库实验室http://dblab.xmu.edu.cn

赖明星2014 年 5 月 17 日

MySQL 加锁处理分析

Page 2: 厦门大学数据库实验室 dblab.xmu

目录

学习目标 学习目标

背景知识 背景知识

简单 SQL 语句加锁分析 简单 SQL 语句加锁分析

复杂 SQL 语句加锁分析 复杂 SQL 语句加锁分析

总结 总结

Page 3: 厦门大学数据库实验室 dblab.xmu

学习目标 1• 理解锁的概念与锁的类型• 理解加锁操作涉及到的考虑因素• 理解 lock与 latch的区别• 能够分析简单的 SQL语句的加锁情况

Page 4: 厦门大学数据库实验室 dblab.xmu

目录

学习目标 学习目标

背景知识 背景知识

简单 SQL 语句加锁分析 简单 SQL 语句加锁分析

复杂 SQL 语句加锁分析 复杂 SQL 语句加锁分析

总结 总结

Page 5: 厦门大学数据库实验室 dblab.xmu

背景知识 21. 事务的 ACID特性2. 事务的隔离级别3. 2PL

4. MVCC

5. 聚簇索引6. 锁类型与锁算法

Page 6: 厦门大学数据库实验室 dblab.xmu

背景知识 2.1

Page 7: 厦门大学数据库实验室 dblab.xmu

背景知识 2.1

Page 8: 厦门大学数据库实验室 dblab.xmu

事务的隔离级别 2.2•READ UNCOMMITTED(未提交读)事务在这个级别下,事务所做的修改,即使没有提交,对其他事务也是可见的。

•READ COMMITTED(提交读) READ COMMITTED 下,只能“看见”已提交事务所做的修改,但是 RC 会出现一个问题,即同一事务两次读可能得到不一样的结果,因此, READ COMMITTED 又称为不可重复读。

•REPEATABLE READ(可重复读) REPEATABLE READ 级别保证在同一个事务中多次读取同样的记录结果是一致的。但是理论上,可重复读隔离级别还是无法解决另外一个幻读的问题。

•SERIALIZABLE(可串行化)最高的隔离级别,强制事务串行执行。

提交读

解决不可重复读未提交读

解决脏读可重复读

解决幻读可串行化

Page 9: 厦门大学数据库实验室 dblab.xmu

2PL协议 2.3

Page 10: 厦门大学数据库实验室 dblab.xmu

MVCC 2.41. MySQL InnoDB 存储引擎,实现的是基于多版本的并发控制协议——

MVCC , MVCC 最大的好处是“读不加锁,读写不冲突”。

2. 在 MVCC 并发控制中,读操作可以分成两类:快照读 (snapshot read) 与当前读 (current read) 。快照读,读取的是记录的可见版本 ,不用加锁。当前读,读取的是记录的最新版本,并且,当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录。

下面的 SQL语句哪些是快照读,哪些是当前读?

1. select * from table where ?;2. select * from table where ? lock in share mode;3. select * from table where ? for update;4. insert into table values (…);5. update table set ? where ?;6. delete from table where ?;

Page 11: 厦门大学数据库实验室 dblab.xmu

MVCC 2.4以 MySQL InnoDB 为例:• 快照读:简单的 select 操作,属于快照读,不加锁。

– select * from table where ?;

• 当前读:特殊的读操作,插入 / 更新 / 删除操作,属于当前读,需要加锁– select * from table where ? lock in share mode;– select * from table where ? for update;– insert into table values (…);– update table set ? where ?;– delete from table where ?;

所有以上的语句,都属于当前读,读取记录的最新版本。并且,读取之后,还需要保证其他并发事务不能修改当前记录,对读取记录加锁。其中,除了第一条语句,对读取记录加 S 锁 (共享锁 ) 外,其他的操作,都加的是 X 锁 ( 排它锁 ) 。

Page 12: 厦门大学数据库实验室 dblab.xmu

聚簇索引 2.5• 在聚集索引中,叶结点也即数据结点,所有数据行的存储顺序与索引的

存储顺序一致, innodb 就是聚集索引(注意:一个表只能有一个聚集索引)

• 非聚集索引即为从属索引,索引在物理上与它描述的表文件分离

Page 13: 厦门大学数据库实验室 dblab.xmu

锁的类型 2.6从资源竞争的角度理解锁的类型

X S

X 不兼容 不兼容S 不兼容 兼容

Page 14: 厦门大学数据库实验室 dblab.xmu

锁的类型 2.6从保护资源的角度理解锁的类型

lock latch

对象 事务 线程保护 数据库内容 内存数据结构持续时间 整个事务过程 临界资源模式 行锁、表锁、意向锁 读写锁、互斥量死锁 通过 waits-for

graph 、 time out 等机制进行死锁检测

无死锁检测机制,如果出现死锁,则说明数据库存在 bug

存在于 Lock Manager 的哈希表中 每个数据结构的对象中

Page 15: 厦门大学数据库实验室 dblab.xmu

锁的类型 2.6从数据库设计者的角度理解锁的类型• 表锁• 行锁• 意向共享锁( IS)和意向排他锁( IX)

Page 16: 厦门大学数据库实验室 dblab.xmu

目录

学习目标 学习目标

背景知识 背景知识

简单 SQL 语句加锁分析 简单 SQL 语句加锁分析

复杂 SQL 语句加锁分析 复杂 SQL 语句加锁分析

总结 总结

Page 17: 厦门大学数据库实验室 dblab.xmu

简单 SQL语句加锁分析 3下面的 SQL语句加什么锁? SQL1 : select * from t1 where id = 10;

SQL2 : delete from t1 where id = 10;

加锁涉及到的因素: 前提一: id列是不是主键? 前提二:当前系统的隔离级别是什么? 前提三: id列如果不是主键,那么 id列上有索引吗? 前提四: id列上如果有二级索引,那么这个索引是唯一索引吗? 前提五:两个 SQL 的执行计划是什么?索引扫描?全表扫描?

Page 18: 厦门大学数据库实验室 dblab.xmu

简单 SQL语句加锁分析 3不同前提与不同的隔离级别的组合:

组合一: id列是主键, RC 隔离级别 组合二: id列是二级唯一索引, RC 隔离级别 组合三: id列是二级非唯一索引, RC 隔离级别 组合四: id列上没有索引, RC 隔离级别 组合五: id列是主键, RR 隔离级别 组合六: id列是二级唯一索引, RR 隔离级别 组合七: id列是二级非唯一索引, RR 隔离级别 组合八: id列上没有索引, RR 隔离级别 组合九: Serializable 隔离级别

Page 19: 厦门大学数据库实验室 dblab.xmu

简单 SQL语句加锁分析 3SQL1 : select * from t1 where id = 10;

组合一: id列是主键, RC 隔离级别 组合二: id列是二级唯一索引, RC 隔离级别 组合三: id列是二级非唯一索引, RC 隔离级别 组合四: id列上没有索引, RC 隔离级别 组合五: id列是主键, RR 隔离级别 组合六: id列是二级唯一索引, RR 隔离级别 组合七: id列是二级非唯一索引, RR 隔离级别 组合八: id列上没有索引, RR 隔离级别 组合九: Serializable 隔离级别

Page 20: 厦门大学数据库实验室 dblab.xmu

简单 SQL语句加锁分析 3SQL2 : delete from t1 where id = 10;

组合一: id列是主键, RC 隔离级别 组合二: id列是二级唯一索引, RC 隔离级别 组合三: id列是二级非唯一索引, RC 隔离级别 组合四: id列上没有索引, RC 隔离级别 组合五: id列是主键, RR 隔离级别 组合六: id列是二级唯一索引, RR 隔离级别 组合七: id列是二级非唯一索引, RR 隔离级别 组合八: id列上没有索引, RR 隔离级别 组合九: Serializable 隔离级别

Page 21: 厦门大学数据库实验室 dblab.xmu

简单 SQL语句加锁分析 3SQL2 : delete from t1 where id = 10; 组合一: id列是主键, RC 隔离级别

Page 22: 厦门大学数据库实验室 dblab.xmu

简单 SQL语句加锁分析 3SQL2 : delete from t1 where id = 10; 组合二: id列是二级唯一索引, RC 隔离级别

Page 23: 厦门大学数据库实验室 dblab.xmu

简单 SQL语句加锁分析 3SQL2 : delete from t1 where id = 10; 组合三: id列是二级非唯一索引, RC 隔离级别

Page 24: 厦门大学数据库实验室 dblab.xmu

简单 SQL语句加锁分析 3SQL2 : delete from t1 where id = 10; 组合四: id列上没有索引, RC 隔离级别

Page 25: 厦门大学数据库实验室 dblab.xmu

简单 SQL语句加锁分析 3SQL2 : delete from t1 where id = 10; 组合五: id列是主键, RR 隔离级别

与组合一类似

组合六: id列是二级唯一索引, RR 隔离级别 与组合二类似

Page 26: 厦门大学数据库实验室 dblab.xmu

简单 SQL语句加锁分析 3SQL2 : delete from t1 where id = 10; 组合七: id列是二级非唯一索引, RR 隔离级别RC 隔离级别允许幻读,而 RR 隔离级别,不允许存在幻读。但是在组合五、组合六中,加锁行为又是与 RC 下的加锁行为完全一致。那么 RR 隔离级别下,如何防止幻读呢

Page 27: 厦门大学数据库实验室 dblab.xmu

简单 SQL语句加锁分析 3SQL2 : delete from t1 where id = 10; 组合五: id列是主键, RR 隔离级别 组合六: id列是二级唯一索引, RR 隔离级别

为什么组合五、组合六,也是 RR 隔离级别,却不需要加GAP 锁呢?

对于组合五, id 是主键;对于组合六, id 是 unique键,都能够保证唯一性。一个等值查询,最多只能返回一条记录,而且新的相同取值的记录,一定不会在新插入进来,因此也就避免了 GAP 锁的使用。

Page 28: 厦门大学数据库实验室 dblab.xmu

简单 SQL语句加锁分析 3SQL2 : delete from t1 where id = 10; 组合八: id列上没有索引, RR 隔离级别

Page 29: 厦门大学数据库实验室 dblab.xmu

简单 SQL语句加锁分析 3SQL2 : delete from t1 where id = 10; 组合九: Serializable 隔离级别

• 对于 SQL2 : delete from t1 where id = 10; 来说, Serializable 隔离级别与Repeatable Read 隔离级别完全一致。

• 对于 SQL1 : select * from t1 where id = 10; 这条 SQL ,在 RC , RR 隔离级别下,都是快照读,不加锁。但是在 Serializable 隔离级别, SQL1 会加读锁,也就是说快照读不复存在, MVCC 并发控制降级为 Lock-Based CC 。

• 结论:在 MySQL/InnoDB 中,所谓的读不加锁,并不适用于所有的情况,而是隔离级别相关的。 Serializable 隔离级别,读不加锁就不再成立,所有的读操作,都是当前读。

Page 30: 厦门大学数据库实验室 dblab.xmu

目录

学习目标 学习目标

背景知识 背景知识

简单 SQL 语句加锁分析 简单 SQL 语句加锁分析

复杂 SQL 语句加锁分析 复杂 SQL 语句加锁分析

总结 总结

Page 31: 厦门大学数据库实验室 dblab.xmu

复杂 SQL语句加锁分析 4加什么锁?

SQL语句的三个阶段:1. Index key : pubtime > 1 and puptime < 202. Index Filter : userid = ‘hdc’3. Table Filter : comment is not NULL

Page 32: 厦门大学数据库实验室 dblab.xmu

复杂 SQL语句加锁分析 4Index Condition Pushdown 是 MySQL 5.6 开始支持的一种根据索引进行查询的优化方式。之前的 MySQL 数据库版本不支持 Index Condition Pushdown ,当进行索引查询时,首先根据索引记录来查找记录,然后再根据 WHEREguol4记录,在支持 Index Condition Pushdown 后, MySQL 数据库会在取出索引的同时,判断是否可以进行 WHERE 条件的过滤,也就是将WHERE 的部分过滤操作放到了存储引擎层。在某些查询下,可以大大减少上层 SQL层对记录的索取( fetch ),从而提高数据库的整体性能。

Index Condition Pushdown 是 MySQL 5.6 开始支持的一种根据索引进行查询的优化方式。之前的 MySQL 数据库版本不支持 Index Condition Pushdown ,当进行索引查询时,首先根据索引记录来查找记录,然后再根据 WHEREguol4记录,在支持 Index Condition Pushdown 后, MySQL 数据库会在取出索引的同时,判断是否可以进行 WHERE 条件的过滤,也就是将WHERE 的部分过滤操作放到了存储引擎层。在某些查询下,可以大大减少上层 SQL层对记录的索取( fetch ),从而提高数据库的整体性能。

Page 33: 厦门大学数据库实验室 dblab.xmu

目录

学习目标 学习目标

背景知识 背景知识

简单 SQL 语句加锁分析 简单 SQL 语句加锁分析

复杂 SQL 语句加锁分析 复杂 SQL 语句加锁分析

总结 总结

Page 34: 厦门大学数据库实验室 dblab.xmu

死锁分析与总结 5

Page 35: 厦门大学数据库实验室 dblab.xmu

死锁分析与总结 5

Page 36: 厦门大学数据库实验室 dblab.xmu

死锁分析与总结 5

结论:死锁的发生与否,并不在于事务中有多少条 SQL 语句,死锁的关键在于:两个 (或以上 )

的 Session加锁的顺序不一致。

Page 37: 厦门大学数据库实验室 dblab.xmu

死锁分析与总结 5

总结:1.MVCC

2.事务隔离级别3.加锁操作的考虑因素4.加锁的详细过程5.死锁分析

Page 38: 厦门大学数据库实验室 dblab.xmu

THANKS