mysql-不恰当的update语句使用主键和索引导致mysql死锁
背景知识:
MySQL有三种锁的级别:页级、表级、行级。
MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking);BDB存储引擎采用的是页面锁(page-level locking),但也支持表级锁;InnoDB存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁。
MySQL这3种锁的特性可大致归纳如下:
表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。
行级锁并不是直接锁记录,而是锁索引,如果一条SQL语句用到了主键索引,mysql会锁住主键索引;如果一条语句操作了非主键索引,mysql会先锁住非主键索引,再锁定主键索引。
问题现象:
线上出现错误日志:mysql死锁问题。
排查过程:
请DBA协助查看mysql错误日志,发现确实存在死锁问题。
发生死锁的就是以上两条sql,两次请求时间仅间隔1毫秒。
涉及到的数据库表如下:
根据背景知识里的红色描述:如果用到了主键索引,mysql会锁定主键索引,如果用到了非主键索引,msyql会先锁定非主键索引,再锁定主键索引。因此,在SQL(1)中先锁定了next_consume_time这个非主键索引,还需要锁定主键索引,此时SQL(2)直接锁定了主键索引,而其update语句中set使用了next_consume_time,同时还需要next_consume_time这个非主键索引。因此两条SQL就出现了对索引资源的竞争,造成死锁。
从业务方面考虑:两条SQL是从两台机器发起的请求,而这两条SQL在业务上是存在了先后顺序的,先执行SQL(1)占用需要执行的表记录,在执行SQL(2)进行业务操作。从日志中发现,54机器执行的是SQL(2),那么54机器肯定已经执行过了SQL(1),此时该条记录已经是被占用状态了,55机器又怎么会执行SQL(2)呢?难道是没被占用吗?
DBA又查看mysql的binlog,发现queue_id为283410的记录,确实正常执行过SQL(1),那55机器为什么还要再次执行SQL(1)呢?
又查看开放平台日志,54机器线程启动时间为:
2016-09-25 11:12:40,463] [dbMsgConsumer-3] [INFO] [taskLogger] [////] - [QueueConsumeTask started]
55机器线程启动时间为:
2016-09-25 11:12:40,583] [dbMsgConsumer-2] [INFO] [taskLogger] [////] - [QueueConsumeTask started]
两者仅相差120毫秒。
目前咱们mysql默认的事务隔离级别是REPETABLE READ(可重复读),即在同一个事务内,多次查询结果是一致的。
当54机器开启事务,执行SQL(1)时,事务还未提交,55机器也执行SQL(1),此时55机器查询到的记录是更新前的,54机器提交事务,再去执行SQL(2),此时由于SQL(1)是范围查询,SQL(2)是主键查询,SQL(2)的执行时间要远远少于SQL(1),会造成54机器执行SQL(2)时,55机器还未执行完成SQL(1),造成两条机器互相抢占资源,造成死锁。54和55两台机器执行示意图如下:
解决办法:
修改SQL(1)为两步操作,首先通过条件查询出符合条件的记录,然后根据查询出的结果的主键id再进行update操作。
修改后sql,先执行查询操作:
再执行修改操作,使用获取到的主键ID
代码修改如下:
经验教训:
电商无论前台后台的程序,都不应该存在仅根据非主键的几个字段一查就要update/delete的场景。即使有,也应该改为先把要更新的记录查出来然后逐条按主键id更新。
原文blog:http://blog.csdn.net/lzy_lizhiyang/article/details/52678446
mysql-不恰当的update语句使用主键和索引导致mysql死锁的更多相关文章
- 不恰当的update语句使用主键和索引导致mysql死锁
背景知识: 截至目前,MySQL一共向用户提供了包括DBD.HEAP.ISAM.MERGE.MyIAS.InnoDB以及Gemeni这7种Mysql表类型.其中DBD.InnoDB属于事务安全类表,而 ...
- 【转载】mysql主键的缺少导致备库hang
最近线上频繁的出现slave延时的情况,经排查发现为用户在删除数据的时候,由于表主键的主键的缺少,同时删除条件没有索引,或或者删除的条件过滤性极差,导致slave出现hang住,严重的影响了生产环境的 ...
- mysql主键的缺少导致备库hang
最近线上频繁的出现slave延时的情况,经排查发现为用户在删除数据的时候,由于表主键的主键的缺少,同时删除条件没有索引,或或者删除的条件过滤性极差,导致slave出现hang住,严重的影响了生产环境的 ...
- Mybatis笔记 – insert语句中主键的返回
在DBMS中可以使用insert语句显示指定自增主键值,但Mybatis中不可,即使指定了也无效,可以使用特殊的方式返回主键. 一.自增主键返回 mysql自增主键执行insert提交 ...
- mysql 插入数据失败防止自增长主键增长的方法
mysql设置了自增长主键ID,插入失败的那个自增长ID也加一的,比如失败5个,下一个成功的不是在原来最后成功数据加1,而是直接变成加6了,失败次数一次就自动增长1了,能不能让失败的不增长的? 或者说 ...
- SQL语句新建表,同时添加主键、索引、约束
SQL语句新建数据表 主键,索引,约束 CREATE TABLE [dbo].[T_SendInsideMessageRec]( [SendInsideMID] [uniqueidentifier ...
- MySQL主键和索引的联系及区别
转载自:http://www.nowamagic.net/librarys/veda/detail/1954 关系数据库依赖于主键,它是数据库物理模式的基石.主键在物理层面上只有两个用途: 惟一地标识 ...
- MySQL主键与索引的区别和联系
MySQL主键与索引的区别和联系 关系数据库依赖于主键,它是数据库物理模式的基石.主键在物理层面上只有两个用途: 惟一地标识一行. 作为一个可以被外键有效引用的对象. 索引是一种特殊的文件(Inn ...
- mysql,主键与索引的区别和联系
关系数据库依赖于主键,它是数据库物理模式的基石.主键在物理层面上只有两个用途: 惟一地标识一行. 作为一个可以被外键有效引用的对象. 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成 ...
随机推荐
- webservice 简单实例
C# 创建.部署和调用WebService的简单示例 webservice 可以用于分布式应用程序之间的交互,和不同程序之间的交互. 概念性的东西就不说太多,下面开始创建一个简单的webservi ...
- 记录下laravel 5.2的auth/logout路由工作不正常的问题
- zabbix-3.4-服务监控
服务监控 总览 服务监控(services monitoring)旨在帮助那些想要高级(业务)基础设施的监控的人.在许多情况下,我们关注的不是底层细节,比如磁盘空间不足.CPU 负载高等.我们关注的是 ...
- LeetCode Unique Binary Search Trees (DP)
题意: 一棵BST有n个节点,每个节点的key刚好为1-n.问此树有多少种不同形态? 思路: 提示是动态规划. 考虑一颗有n个节点的BST和有n-1个节点的BST.从n-1到n只是增加了一个点n,那么 ...
- Coursera 算法二 week 3 Baseball Elimination
这周的作业不需要自己写算法,只需要调用库函数就行,但是有些难以理解,因此用了不少时间. import edu.princeton.cs.algs4.FlowEdge; import edu.princ ...
- tensorflow构建CNN模型时的常用接口函数
(1)tf.nn.max_pool()函数 解释: tf.nn.max_pool(value, ksize, strides, padding, data_format='NHWC', name=No ...
- 三种序列化方式存取redis的方法
常见的的序列化反序列方式的效率: protoBuf(PB) > fastjson > jackson > hessian > xstream > java 数据来自于:h ...
- THinkPHP 5.0 域名路由
ThinkPHP支持完整域名.子域名和IP部署的路由和绑定功能 要启用域名部署路由功能,首先需要开启: 'url_domain_deploy' => true 定义域名部署规则支持两种方式:动态 ...
- 什么是SAD,SAE,SATD,SSD,SSE,MAD,MAE,MSD,MSE?
SAD(Sum of Absolute Difference)=SAE(Sum of Absolute Error)即绝对误差和 SATD(Sum of Absolute Transformed Di ...
- 【luogu P3608 [USACO17JAN]Balanced Photo平衡的照片】 题解
题目链接:https://www.luogu.org/problemnew/show/P3608 乍一看很容易想到O(N^2)的暴力. 对于每个H[i]从i~i-1找L[i]再从i+1~n找R[i], ...