From 4b0db3f578c0414fe29847a7e70d56f557789745 Mon Sep 17 00:00:00 2001 From: Keqi Huang Date: Wed, 8 Aug 2018 14:10:19 +0800 Subject: [PATCH] =?UTF-8?q?Update=20=E6=95=B0=E6=8D=AE=E5=BA=93=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E5=8E=9F=E7=90=86.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- notes/数据库系统原理.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/notes/数据库系统原理.md b/notes/数据库系统原理.md index 151ffc0f..6b8fcd86 100644 --- a/notes/数据库系统原理.md +++ b/notes/数据库系统原理.md @@ -389,11 +389,11 @@ MVCC 不能解决幻读的问题,Next-Key Locks 就是为了解决这个问题 ## Gap Locks -锁定一个范围内的索引,例如当一个事务执行以下语句,其它事务就不能在 t.c 中插入 15。 +间隙锁锁住的是多行,是一个数据范围。间隙锁主要是为了防止出现幻读,但是它会把锁定范围扩大,有时候也会给我们带来麻烦。在数据库参数中,控制间隙锁的参数是 ```innodb_locks_unsafe_for_binlog```, 这个参数默认值是 OFF,也就是启用间隙锁,它是一个bool值,当值为 true 时表示 disable 间隙锁。那为了防止间隙锁是不是直接将 ```innodb_locaks_unsafe_for_binlog``` 设置为 ```true``` 就可以了呢?不一定!而且这个参数会影响到主从复制及灾难恢复,这个方法还尚待商量。 -```sql -SELECT c FROM t WHERE c BETWEEN 10 and 20 FOR UPDATE; -``` +间隙锁的出现主要集中在同一个事务中先 delete 后 insert 的情况下,当我们通过一个参数去删除一条记录的时候,如果参数在数据库中存在,那么这个时候产生的是普通行锁,锁住这个记录,然后删除,最后释放锁。如果这条记录不存在,问题就来了,数据库会扫描索引,发现这个记录不存在,这个时候的 delete 语句获取到的就是一个间隙锁,然后数据库会向左扫描扫到第一个比给定参数小的值,向右扫描扫描到第一个比给定参数大的值,然后以此为上下界限构建一个区间,进而锁住整个区间内的数据,一个特别容易出现死锁的间隙锁诞生了。 + +通过修改 ```innodb_locaks_unsafe_for_binlog``` 参数来取消间隙锁从而达到避免这种情况的死锁的方式尚待商量,那就只有修改代码逻辑,存在才删除,尽量避免去删除不存在的记录。 ## Next-Key Locks