MySQL(InnoDB)是如何处理死锁的

一、什么是死锁

官方定义如下:两个事务都持有对方需要的锁,并且在等待对方释放,并且双方都不会释放自己的锁。

这个就好比你有一个人质,对方有一个人质,你们俩去谈判说换人。你让对面放人,对面让你放人。

二、为什么会形成死锁

看到这里,也许你会有这样的疑问,事务和谈判不一样,为什么事务不能使用完锁之后立马释放呢?居然还要操作完了之后一直持有锁?这就涉及到 MySQL 的并发控制了。

MySQL的并发控制有两种方式,一个是 MVCC,一个是两阶段锁协议。那么为什么要并发控制呢?是因为多个用户同时操作 MySQL 的时候,为了提高并发性能并且要求如同多个用户的请求过来之后如同串行执行的一样(可串行化调度)。具体的并发控制这里不再展开。咱们继续深入讨论两阶段锁协议。

两阶段锁协议(2PL)

官方定义:

两阶段锁协议是指所有事务必须分两个阶段对数据加锁和解锁,在对任何数据进行读、写操作之前,事务首先要获得对该数据的封锁;在释放一个封锁之后,事务不再申请和获得任何其他封锁。

对应到 MySQL 上分为两个阶段:

  1. 扩展阶段(事务开始后,commit 之前):获取锁
  2. 收缩阶段(commit 之后):释放锁

就是说呢,只有遵循两段锁协议,才能实现 可串行化调度

但是两阶段锁协议不要求事务必须一次将所有需要使用的数据加锁,并且在加锁阶段没有顺序要求,所以这种并发控制方式会形成死锁。

三、MySQL 如何处理死锁?

MySQL有两种死锁处理方式:

  1. 等待,直到超时(innodb_lock_wait_timeout=50s)。
  2. 发起死锁检测,主动回滚一条事务,让其他事务继续执行(innodb_deadlock_detect=on)。

由于性能原因,一般都是使用死锁检测来进行处理死锁。

死锁检测

死锁检测的原理是构建一个以事务为顶点、锁为边的有向图,判断有向图是否存在环,存在即有死锁。

回滚

检测到死锁之后,选择插入更新或者删除的行数最少的事务回滚,基于 INFORMATION_SCHEMA.INNODB_TRX 表中的 trx_weight 字段来判断。

四、如何避免发生死锁

收集死锁信息:

  1. 利用命令 SHOW ENGINE INNODB STATUS查看死锁原因。
  2. 调试阶段开启 innodb_print_all_deadlocks,收集所有死锁日志。

减少死锁:

  1. 使用事务,不使用 lock tables
  2. 保证没有长事务。
  3. 操作完之后立即提交事务,特别是在交互式命令行中。
  4. 如果在用 (SELECT ... FOR UPDATE or SELECT ... LOCK IN SHARE MODE),尝试降低隔离级别。
  5. 修改多个表或者多个行的时候,将修改的顺序保持一致
  6. 创建索引,可以使创建的锁更少。
  7. 最好不要用 (SELECT ... FOR UPDATE or SELECT ... LOCK IN SHARE MODE)
  8. 如果上述都无法解决问题,那么尝试使用 lock tables t1, t2, t3 锁多张表

MySQL 是如何处理死锁的的更多相关文章

  1. MySQL(InnoDB)是如何处理死锁的

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

  2. 在SQL Server里如何处理死锁

    在今天的文章里,我想谈下SQL Server里如何处理死锁.当2个查询彼此等待时会发生死锁,没有一个查询可以继续它们的操作.首先我想给你大致讲下SQL Server如何处理死锁.最后我会展示下SQL ...

  3. SQL Server里如何处理死锁

    在今天的文章里,我想谈下SQL Server里如何处理死锁.当2个查询彼此等待时会发生死锁,没有一个查询可以继续它们的操作.首先我想给你大致讲下SQL Server如何处理死锁.最后我会展示下SQL ...

  4. MySql一个生产死锁案例分析

    接到上级一个生产环境MySQL死锁日志信息文件,需要找出原因并解决问题.我将死锁日志部分贴出如下: 在mysql中使用命令:SHOW ENGINE INNODB STATUS;总能获取到最近一些问题信 ...

  5. SQL Server里如何处理死锁 (转)

    http://www.cnblogs.com/woodytu/p/6437049.html 在今天的文章里,我想谈下SQL Server里如何处理死锁.当2个查询彼此等待时会发生死锁,没有一个查询可以 ...

  6. [转]MySQL批量更新死锁案例分析

    文章出处:http://blog.csdn.net/aesop_wubo/article/details/8286215 问题描述 在做项目的过程中,由于写SQL太过随意,一不小心就抛了一个死锁异常, ...

  7. MySQL批量更新死锁案例分析--转载

    问题描述 在做项目的过程中,由于写SQL太过随意,一不小心就抛了一个死锁异常,如下: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackE ...

  8. 一个项目中mysql数据库经常死锁的问题解决记录

    1.问题描述 此项目为一个物流系统,需要使用PDA对货物进行入库.备货.出货等操作,在系统开发测试过程中,经常发现死锁问题. 有这样一种业务场景:仓库对备货单上货进行扫码备货后,点击"完成& ...

  9. 【mysql】MySQL知识整理-死锁分析-性能优化等

    [[TOC]] 常用操作指令 show databases:显示所有的数据库: use dbName: 使用指定数据库 show tables: 显示所有的数据表: desc tableName: 查 ...

随机推荐

  1. node.js入门安装过程

    本次随笔的目的是教大家如何安装 node.js安装 第一步:安装node环境 下载地址:https://nodejs.org/en/download/ 下载好后 对应一下你的node版本 ,傻瓜式安装 ...

  2. Anticancer Effect of Deuterium Depleted Water - Redox Disbalance Leads to Oxidative Stress(低氘水的抗癌作用-氧化还原失衡导致了氧化应激)-解读人:范徉

    期刊名:Molecular & Cellular Proteomics 发表时间:(2019年12月) IF:4.828 单位:瑞典卡罗林斯卡学院 物种:人 技术:标记定量蛋白质组学,氧化还原 ...

  3. 漫谈LiteOS之开发板-串口(基于GD32450i-EVAL)

    [摘要] ​主要讲解物联网的技术积累,本期我们先带领大家学习漫谈LiteOS之漫谈开发板第一集-串口,本文基于GD32450i-EVAL对串口以及其通信做了一个简要的分析,以及开发过程中遇到的一些技术 ...

  4. 大型情感剧集Selenium:3_元素定位 #华为云·寻找黑马程序员#

    关于昨天的文章 今天有朋友反馈,代码运行的时候,selenium提示警告 DeprecationWarning: use options instead of chrome_options drive ...

  5. Modelarts与无感识别技术生态总结(浅出版)

    [摘要] Modelarts技术及相关产业已成为未来AI与大数据重点发展行业模式之一,为了促进人工智能领域科学技术快速发展,modelarts现状及生态前景成为研究热点.笔者首先总结modelarts ...

  6. Forrester:华为云容器是容器混合云最佳选择

    近日,国际权威咨询机构Forrester发布<The Forrester New WaveTM: Public Cloud Enterprise Container Platforms, Q3 ...

  7. ios instancetype与id区别

    我们都知道未知类型的的对象可以用id关键字表示,那为什么还会再有一个instancetype呢? instancetype能返回相关联的类型(使那些非关联返回类型的方法返回所在类的类型):而id 返回 ...

  8. Codeforces 题解 CF863A 【Quasi-palindrome】

    此题本质上是:求一个数去掉后缀零后是否是回文串 因此,代码分为: >>> 读入 >>> 删除后缀0 >>> 判断回文 >>> 转 ...

  9. Linux 怎么清理缓存

    linux清理缓存的命令   查看缓存的命令 free -m 清理缓存的命令  echo 1 > /proc/sys/vm/drop_caches echo 2 > /proc/sys/v ...

  10. CCF-CSP题解 201609-3 炉石传说

    模拟. 注意随从的编号在\(summon\)和\(attack\)随从死亡时都可能改变. #include <bits/stdc++.h> using namespace std; str ...