sql自学笔记(二十四)——MySQL8.0版本的新特性(十四)

死锁检查控制

MySQL8.0(MySQL5.7.15)增加了一个新的动态变量,用于控制系统是否执行InnoDB死锁检查。

innodb _ deadlock_delect

对于高并发的系统禁用死锁检查可能带来性能的提高。

接下来我们看一下这个参数对我们系统的影响

首先我们显示一下参数的默认值

show varables like 'innodb _ deadlock _ detect';

默认情况下这个参数是打开的

接下来再两个事务中修改一些数据,然后让个事务相互锁定一些等待对方的一些锁,让他形成一个死锁,让后看一下这个参数默认打开情况下的一个行为。

创建一张表

create table t(i int);//创建一个字段
insert into t(i) values(1);//插入一条记录

首先在第一个会话当中,创建一个事物

start transaction;

然后获取记录上的一个锁

select * from t where i=1 for share;

接着启动第二个窗口
创建一个事物

start transaction;

删除这条记录

delete from t where i=1;

对于这个情况由于前面一个会话,已经占用了一个共享锁,所以这个语句他会进行一个等待,等待前面的会话进行资源的释放。
我们可以看到他会等待在这里



这个时候我们回到第一个窗口。同样执行一个删除
删除的时候也是需要一个排他锁
这个时候它也会等待第二个会话,释放相应的锁,他才能够继续进行下去,形成一个死锁、



我们可以看到当前窗口第一个窗口可以被执行,第二个窗口出现了一个错误,也就是这个死锁被发现了,所以系统把这个事务回转掉了,让第一个事务能够继续进行下去,这样就是这个参数‘inndb _ deadlock _ delect’默认打开情况下的一个行为。
接下来把这个参数先关掉
set global innodb _ deadlock _ detect = off;

在看一下是否已经关掉

show variables like 'innodb _ deadlock _ detect';

我们再重复刚才的实验,看一下再关掉的情况下,它的行为是什么样的

首先看一下锁等待超时的一个参数

show variables like 'innodb _ lock _ wait%';

它默认是50,我们可以改一下等待时间

set global innodb _ lock _ wait _ timeout = 5;

把刚才删掉的数据加回来

insert into into t(i) values(1);

同样启动一个事务

start transaction;

获取共享锁

select * from t where i =1 for share;

这时启动第二个窗口
启动一个事务

start transaction

然后执行这个删除操作

sekect * from t where i=1 for share;

看到他们仍然会等待
等待一段时间后,它会出现锁等待超时,它会以这种方式让事务回转失败。
再回到前面的事务



这个事务它由于等待时间没有这么长它能够继续执行下去,完成这个事务。


说明:
虽然这个死锁检测是我们可以关闭掉的,那么前提是我们要确保我们的应用不会发生或者是特别少的情况下发生这种死锁,那么我们要非常小心的写sql
语句或者我们的业务相应的代码,并且进行相应的测试,同时我们需要注意就是把刚才锁等待超时让它尽量小一点。

你可能感兴趣的:(sql自学笔记(二十四)——MySQL8.0版本的新特性(十四))