Update 数据库系统原理.md

This commit is contained in:
Keqi Huang 2018-08-08 14:10:19 +08:00 committed by GitHub
parent 93a9fe11cb
commit 4b0db3f578
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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