pull/1/head
595208882@qq.com 3 years ago
parent f89a75889a
commit cb5c510dd7

@ -597,41 +597,54 @@ WHERE A.EMP_SUPV_ID = B.EMP_ID;
# 数据库锁
从粒度上来说就是**表锁、页锁、行锁**。表锁有意向共享锁、意向排他锁、自增锁等。行锁是在引擎层由各个引擎自己实现的。但并不是所有的引擎都支持行锁,比如 `MyISAM`引擎就`不支持行锁`。
按照锁的粒度进行分类MySQL主要包含三种类型锁
- **全局锁**:锁的是整个 `database`。由MySQL的**SQL layer**层实现的
- **表级锁**:锁的是某个 `table`。由MySQL的**SQL layer**层实现的
- **⾏级锁**:锁的是 `某⾏数据``⾏之间的间隙`。由某些**存储引擎**实现如InnoDB
按照锁的粒度进行分类MySQL主要包含三种类型级别的锁定机制
- **全局锁**锁的是整个database。由MySQL的SQL layer层实现的
- **表级锁**锁的是某个table。由MySQL的SQL layer层实现的
- **⾏级锁**锁的是某⾏数据也可能锁定⾏之间的间隙。由某些存储引擎实现⽐如InnoDB
根据不同的存储引擎MySQL中锁的特性可以大致归纳如下
| 存储引擎 | 行锁 | 表锁 | 页锁 |
| -------- | ---- | ---- | ---- |
| InnoDB | √ | √ | |
| MyISAM | | √ | |
| BDB | √ | √ | √ |
- **表锁** 开销小,加锁快;不会出现死锁;锁定力度大,发生锁冲突概率高,并发度最低
- **行锁** 开销大,加锁慢;会出现死锁;锁定粒度小,发生锁冲突的概率低,并发度高
- **页锁** 开销和加锁速度介于表锁和行锁之间;会出现死锁;锁定粒度介于表锁和行锁之间,并发度一般
在 InnoDB 存储引擎中:
- SELECT 操作的不可重复读问题通过`MVCC`得到了解决
- UPDATE、DELETE 的不可重复读问题通过`Record Lock`(记录锁)解决
- INSERT 的不可重复读问题是通过`Next-Key Lock`(临键锁)解决
- `SELECT` 操作的不可重复读问题通过 `MVCC` 得到了解决
- `UPDATE``DELETE` 的不可重复读问题通过 `Record Lock` (记录锁)解决
- `INSERT` 的不可重复读问题是通过 `Next-Key Lock` (临键锁)解决
按照对数据操作的锁粒度来分:
按照锁的共享策略来分:
- **行级锁**
- **表级锁**
- **页级锁**
- **间隙锁**
- **共享锁S锁Shared Locks**:读锁。针对同一份数据,多个读操作可以同时进行而不会互相影响
- **排它锁X锁Exclusive Locks**:写锁。当前写操作没有完成前,它会阻断其他写锁和读锁
为了允许行锁和表锁共存实现多粒度锁机制InnoDB还有两种内部使用的意向锁这两种意向锁都是表锁
- **意向共享锁IS锁Intention Shared Lock**当事务准备在某条记录上加S锁时需要先在表级别加一个IS锁
- **意向排他锁IX锁Intention Exclusive Lock**当事务准备在某条记录上加X锁时需要先在表级别加一个IX锁
按照锁的共享策略来分:
| 请求锁模式是否兼容当前锁模式 | X锁 | IX锁 | S锁 | IS锁 |
| ---------------------------- | ------ | ------ | ------ | ------ |
| X锁 | `冲突` | `冲突` | `冲突` | `冲突` |
| IX锁 | `冲突` | 兼容 | `冲突` | 兼容 |
| S锁 | `冲突` | `冲突` | 兼容 | 兼容 |
| IS锁 | `冲突` | 兼容 | 兼容 | 兼容 |
- **读锁(共享锁)**Shared LocksS锁。针对同一份数据多个读操作可以同时进行而不会互相影响
- **写锁(排它锁)**Exclusive LocksX锁。当前写操作没有完成前它会阻断其他写锁和读锁
- **IS锁**意向共享锁、Intention Shared Lock。当事务准备在某条记录上加S锁时需要先在表级别加一个IS锁
- **IX锁**意向排他锁、Intention Exclusive Lock。当事务准备在某条记录上加X锁时需要先在表级别加一个IX锁
若一个事务请求锁模式与当前锁兼容InnoDB就将请求锁授予该事务反之两者不兼容该事务就要等待锁释放。
@ -829,11 +842,11 @@ InnoDB 存储引擎提供了个`innodb_autoinc_lock_mode`的系统变量,是
- **Record Lock(记录锁)**
- **Gap Lock(间隙锁)**
- **Next-Key Lock(间隙锁)**
- **Next-Key Lock(临键锁)**
### Record Lock(记录锁)
记录锁就是为**某行**记录加锁,它封锁该行的索引记录:
记录锁就是为**某行**记录加锁,它封锁该行的**索引记录**
```sql
-- id 列为主键列或唯一索引列
@ -1130,6 +1143,8 @@ kill trx_mysql_thread_id;
![InnoDB存储引擎SQL隔离级别锁比较](images/Database/InnoDB存储引擎SQL隔离级别锁比较.png)
### Read Uncommitted(读未提交)
**即读取到了其它事务未提交的内容**。在该隔离级别,**所有事务都可以看到其他未提交事务的执行结果**。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为**脏读Dirty Read**。

@ -1262,7 +1262,7 @@ cluster_stats_messages_received:3021
## 常见问题
**分析题目**保证Redis 中的 20w 数据都是热点数据 说明是 被频繁访问的数据并且要保证Redis的内存能够存放20w数据要计算出Redis内存的大小。
**题目**保证Redis 中的 20w 数据都是热点数据 说明是 被频繁访问的数据并且要保证Redis的内存能够存放20w数据要计算出Redis内存的大小。
- **保留热点数据:**对于保留 Redis 热点数据来说,我们可以使用 Redis 的内存淘汰策略来实现,可以使用**allkeys-lru淘汰策略**该淘汰策略是从 Redis 的数据中挑选最近最少使用的数据删除,这样频繁被访问的数据就可以保留下来了
@ -1276,7 +1276,7 @@ cluster_stats_messages_received:3021
**题目:假如 Redis 里面有 1 亿个 key其中有 10w key 是以某个固定的已知的前缀开头的,如果将它们全部找出来?**
**题目假如Redis里面有1亿个key其中有10w个key是以某个固定的已知的前缀开头的如果将它们全部找出来**
使用 keys 指令可以扫出指定模式的 key 列表。对方接着追问:如果这个 Redis 正在给线上的业务提供服务,那使用 keys 指令会有什么问题?这个时候你要回答 Redis 关键的一个特性Redis 的单线程的。keys 指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。这个时候可以使用 scan 指令scan 指令可以无阻塞地提取出指定模式的 key 列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用 keys 指令长。

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

Loading…
Cancel
Save