当前位置:伍佰目录 » 站长资讯 » 免费资源 » 技术文章 » 文章详细

这个不可思议的死锁你会解吗?

来源:本站原创 浏览:188次 时间:2021-05-07

昌珉宋茜吃火锅照片,南京影楼,白癜风手拉手

  | 作者王起帆,腾讯CSIG数据库产品中心后台开发工程师,目前主要参与DBbrain开发工作,热爱技术,欢迎留言进行交流。

  我们都知道,数据库系统中,不同线程并发访问数据,为了保护数据,在执行SQL语句时候需要对数据加锁。而死锁是一个经常遇到问题,SQL语句加锁和事物隔离级别,访问的索引是不是唯一,访问数据是否存在都有关系,往往死锁分析非常复杂。这篇文章将介绍一个“简单的死锁”,这个死锁产生的事物中SQL语句都只有一条,而且业务非常简单就是删除一条记录。两个事物同时执行以下两个SQL语句就有可能死锁。

  DELETE FROM dept_manager WHERE num = 0;DELETE FROM dept_manager WHERE dept_no = 'd001';

  一、死锁模拟

  死锁模拟

  首先介绍下表结构,这个表除了主键索引 PRIMARY,还有一个唯一索引 num 和一个非唯一索引 dept_no ,建表语句如下:

  CREATE TABLE `dept_manager` (`emp_no` int(11) NOT ,`dept_no` char NOT ,`num` int(11) NOT ,`to_date` date NOT ,PRIMARY KEY (`emp_no`),unique index(`num`),KEY `dept_no` (`dept_no`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;

  然后再准备下数据:

  INSERT INTO `dept_manager` VALUES (1001,'d001',0,'1991-10-01'),(1002,'d005',,'9999-01-01'),(1005,'d002',,'1989-12-17'),(1007,'d002',,'9999-01-01'),(1008,'d004',,'1988-09-09'),(1009,'d004',,'1992-08-02'),(1010,'d005',9,'1996-08-30');

  使用执行两个sql很难,使用 mysqlslap 来高并发碰碰运气:

  # mysqlslap --create-schema dldb -q "begin;DELETE FROM dept_manager WHERE num = 0; rollback;" --number-of-queries=100000 -uroot -p123456 &# mysqlslap --create-schema dldb -q "begin;DELETE FROM dept_manager WHERE dept_no = 'd001'; rollback;" --number-of-queries=100000 -uroot -p123456 &

  这两个事物非常都是删除一行相同的数据 (1001,'d001',0,'1991-10-01')只不过一个https://www.3tt.net/?mod=artinfo&aid=415根据索引 num ,一个根据索引 dept_no 。

  二、原因分析

  1. 数据是怎么找到的?

  要说清楚死锁产生原因,就要先理清楚这条SQL是怎么执行的,会在那些地方加锁。在此之前先说说数据库是怎么找到我们要删除的这行数据的。下面两幅图展示根据年龄为30来查记录的示意图。首先根据 name 为 seven, 在 name 这个辅助索引查找,但是只能拿到主键的 id。随后再根据主键id 去主键查找,这个过程称为回表。访问数据是要通过索引的,而且数据就在主键索引上面,所以加锁就是加在索引上面的。

  

  2. Delete 是怎么执行的

  Delete 删除数据其实并不是把数据删除了,只是把数据标记一下,表示这里可以复用的,如果下次这里有数据要插入就可以直接复用原来空间里。所以Delete 和 Update 操作比较类似。Delete 和 Update 是根据条件找到第一条数据,进行修改,然后找到第二条数据,以此类推直到再也查不到符合条件的数据。

本文地址:http://www.reviewcode.cn/youxikaifa/207311.html 转载请注明出处!


伍佰目录声明:本站部分文章来源于网络,版权属于原作者所有。如有转载或引用文章/图片涉及版权问题,请联系我们处理.我们将在第一时间删除! 联系邮箱:tsk@qq.com

快速链接

最新收录

最新点入