MySQL 是如何处理死锁的
MySQL(InnoDB)是如何处理死锁的
一、什么是死锁
官方定义如下:两个事务都持有对方需要的锁,并且在等待对方释放,并且双方都不会释放自己的锁。
这个就好比你有一个人质,对方有一个人质,你们俩去谈判说换人。你让对面放人,对面让你放人。

二、为什么会形成死锁
看到这里,也许你会有这样的疑问,事务和谈判不一样,为什么事务不能使用完锁之后立马释放呢?居然还要操作完了之后一直持有锁?这就涉及到 MySQL 的并发控制了。
MySQL的并发控制有两种方式,一个是 MVCC,一个是两阶段锁协议。那么为什么要并发控制呢?是因为多个用户同时操作 MySQL 的时候,为了提高并发性能并且要求如同多个用户的请求过来之后如同串行执行的一样(可串行化调度)。具体的并发控制这里不再展开。咱们继续深入讨论两阶段锁协议。
两阶段锁协议(2PL)
官方定义:
两阶段锁协议是指所有事务必须分两个阶段对数据加锁和解锁,在对任何数据进行读、写操作之前,事务首先要获得对该数据的封锁;在释放一个封锁之后,事务不再申请和获得任何其他封锁。
对应到 MySQL 上分为两个阶段:
- 扩展阶段(事务开始后,commit 之前):获取锁
- 收缩阶段(commit 之后):释放锁
就是说呢,只有遵循两段锁协议,才能实现 可串行化调度。
但是两阶段锁协议不要求事务必须一次将所有需要使用的数据加锁,并且在加锁阶段没有顺序要求,所以这种并发控制方式会形成死锁。
三、MySQL 如何处理死锁?
MySQL有两种死锁处理方式:
- 等待,直到超时(innodb_lock_wait_timeout=50s)。
- 发起死锁检测,主动回滚一条事务,让其他事务继续执行(innodb_deadlock_detect=on)。
由于性能原因,一般都是使用死锁检测来进行处理死锁。
死锁检测
死锁检测的原理是构建一个以事务为顶点、锁为边的有向图,判断有向图是否存在环,存在即有死锁。
回滚
检测到死锁之后,选择插入更新或者删除的行数最少的事务回滚,基于 INFORMATION_SCHEMA.INNODB_TRX 表中的 trx_weight 字段来判断。
四、如何避免发生死锁
收集死锁信息:
- 利用命令
SHOW ENGINE INNODB STATUS查看死锁原因。 - 调试阶段开启 innodb_print_all_deadlocks,收集所有死锁日志。
减少死锁:
- 使用事务,不使用
lock tables。 - 保证没有长事务。
- 操作完之后立即提交事务,特别是在交互式命令行中。
- 如果在用
(SELECT ... FOR UPDATE or SELECT ... LOCK IN SHARE MODE),尝试降低隔离级别。 - 修改多个表或者多个行的时候,
将修改的顺序保持一致。 - 创建索引,可以使创建的锁更少。
- 最好不要用
(SELECT ... FOR UPDATE or SELECT ... LOCK IN SHARE MODE)。 - 如果上述都无法解决问题,那么尝试使用
lock tables t1, t2, t3锁多张表
MySQL 是如何处理死锁的的更多相关文章
- MySQL(InnoDB)是如何处理死锁的
MySQL(InnoDB)是如何处理死锁的 一.什么是死锁 官方定义如下:两个事务都持有对方需要的锁,并且在等待对方释放,并且双方都不会释放自己的锁. 这个就好比你有一个人质,对方有一个人质,你们俩去 ...
- 在SQL Server里如何处理死锁
在今天的文章里,我想谈下SQL Server里如何处理死锁.当2个查询彼此等待时会发生死锁,没有一个查询可以继续它们的操作.首先我想给你大致讲下SQL Server如何处理死锁.最后我会展示下SQL ...
- SQL Server里如何处理死锁
在今天的文章里,我想谈下SQL Server里如何处理死锁.当2个查询彼此等待时会发生死锁,没有一个查询可以继续它们的操作.首先我想给你大致讲下SQL Server如何处理死锁.最后我会展示下SQL ...
- MySql一个生产死锁案例分析
接到上级一个生产环境MySQL死锁日志信息文件,需要找出原因并解决问题.我将死锁日志部分贴出如下: 在mysql中使用命令:SHOW ENGINE INNODB STATUS;总能获取到最近一些问题信 ...
- SQL Server里如何处理死锁 (转)
http://www.cnblogs.com/woodytu/p/6437049.html 在今天的文章里,我想谈下SQL Server里如何处理死锁.当2个查询彼此等待时会发生死锁,没有一个查询可以 ...
- [转]MySQL批量更新死锁案例分析
文章出处:http://blog.csdn.net/aesop_wubo/article/details/8286215 问题描述 在做项目的过程中,由于写SQL太过随意,一不小心就抛了一个死锁异常, ...
- MySQL批量更新死锁案例分析--转载
问题描述 在做项目的过程中,由于写SQL太过随意,一不小心就抛了一个死锁异常,如下: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackE ...
- 一个项目中mysql数据库经常死锁的问题解决记录
1.问题描述 此项目为一个物流系统,需要使用PDA对货物进行入库.备货.出货等操作,在系统开发测试过程中,经常发现死锁问题. 有这样一种业务场景:仓库对备货单上货进行扫码备货后,点击"完成& ...
- 【mysql】MySQL知识整理-死锁分析-性能优化等
[[TOC]] 常用操作指令 show databases:显示所有的数据库: use dbName: 使用指定数据库 show tables: 显示所有的数据表: desc tableName: 查 ...
随机推荐
- uni-app之网络请求
uni-app之网络请求 一,介绍 uni.request(OBJECT),发起网络请求,以下主要是一些特殊的参数说明,详细的可查看uni-app官网. 1,method的有效值必须是大写,默认GET ...
- 一条数据的HBase之旅,简明HBase入门教程3:适用场景
[摘要] 这篇文章继HBase数据模型之后,介绍HBase的适用场景,以及与一些关键场景有关的周边技术生态,最后给出了本文的示例数据 华为云上的NoSQL数据库服务CloudTable,基于Apach ...
- 从自动化到智能化,网易杭研的AIOps探索与实践
在大数据时代下,我们借助机器学习.数据仓库.大数据平台等大数据技术手段,将运维产生的数据进行分析.处理,得出最佳运维策略,以期实现对故障的事先干预,将风险降低到最低,从而降低运维成本,提升运维效率,最 ...
- Redis Cluster 自动化安装,扩容和缩容
Redis Cluster 自动化安装,扩容和缩容 之前写过一篇基于python的redis集群自动化安装的实现,基于纯命令的集群实现还是相当繁琐的,因此官方提供了redis-trib.rb这个工具虽 ...
- NIO-Channel
目录 NIO-Channel 目录 前言 什么是Channel 通道类型 如何使用 ServerSocketChannel SocketChannel FileChannel 总结 相关文献 NIO- ...
- Python--glob模块
0.glob模块和通配符 glob模块最主要的方法有2个: 1.glob() 2.iglob() 以上2分方法一般和通配符一起使用,常用的通配符有3个: * :匹配零个或多个字符 ? :匹配任何单个的 ...
- 【解决】OCI runtime exec failed......executable file not found in $PATH": unknown
[问题]使用docker exec + sh进入容器时报错 [root@localhost home]# docker exec -it container-test bash OCI runtime ...
- 基于 Blazui 的 Blazor 后台管理模板 BlazAdmin 正式尝鲜
简介 BlazAdmin 是一个基于Blazui的后台管理模板,无JS,无TS,非 Silverlight,非 WebForm,一个标签即可使用. 我将在下一篇文章讨论 Blazor 服务器端渲染与客 ...
- 修改CentOS7网卡名字
需求:CentOS7网卡名字不像之前CentOS6版本的eth0,eth1这样的名字了,而是enoxxx比较长,不太容易记忆,操作也不方便!这时候就需要改网卡名字了. 1 :查看你的CentOS7 ...
- 开局一张图,学一学项目管理神器Maven!
Maven强大的Java工程构建工具,做Java开发时少了跟Maven打交道,之前在知乎上看到有人提问:"学Java开发需不需要学习Maven?",个人认为是必需要学的,这和工欲善 ...