死锁是事务处理型数据库系统的一个经典问题,但是它们并不是很危险的, 除非它们如此地频繁以至于你根本处理不了几个事务。 当因死锁而产生了回滚时,你通常可以在你的应用程序中重新发出一个事务即可。

InnoDB 使用自动地行级锁定。你可能恰好在插入或删除单一一条记录时产生死锁。 这是因为这些操作并不是真正“原子(atomic)”级的:他们会自动地在锁定 inserted/deleted 行的索引记录(可能有几个)。

可以通过下面所示的技巧来应付死锁或减少死锁的次数:

在 MySQL >=3.23.52 和 >= 4.0.3 的版本中使用 SHOW INNODB STATUS 来确定引起最后一个死锁的原因。这可以帮助你调整你的应用程序来避免死锁。

总是准备在因死锁而发生错误时重新发出一个事务。死锁并不危险。仅仅只需重试一遍。

经常提交你的事务。小的事务有较少的碰撞可能。

如果使用锁定读取 SELECT ... FOR UPDATE 或 ... LOCK IN SHARE MODE,尽量使用较低的隔离级 READ COMMITTED。

以一个固定秩序(a fixed order)访问你的表和记录。这样事务将形成一个较精细的队列,而避免死锁。

为你的表添加合适的索引。那么你的查询只需要扫描较少的索引,因而设置较少的锁定。使用 EXPLAIN SELECT 来确定 MySQL 为你的查询挑选的适当的索引。

尽量少用锁定:如果可以通过一个 SELECT 在一个较老的数据快照中获得所需数据,就不要再添加子句 FOR UPDATE 或 LOCK IN SHARE MODE 。在这时使用 READ COMMITTED 隔离级是较好的主意,因为在同一个事务中的每个 consistent read 只读取它最先确定的数据快照。

如果仍然没有什么补救效果,使用表级锁定连载你的事务(serialize transactions):LOCK TABLES t1 WRITE, t2 READ, ... ; [do something with tables t1 and t2 here]; UNLOCK TABLES。表级锁定可以使你的事务形成精细的队列。注意 LOCK TABLES 隐含地启动一个事务,就如同命令 BEGIN,UNLOCK TABLES 如同 COMMIT 一样隐含地结束一个事务。

连载事务(serialize transactions)的另一个解决办法就是建立一个仅有一行记录的辅助“信号量(semaphore)” 表。每一个事务在访问其它表之前均更新这个记录。通过这种方式所有的事务将持续执行。注意同时 InnoDB 实时死锁检测算法也在工作着,因为这个持续锁定(serializing lock)是一个行锁定。在 MySQL 中对于表级锁定我们必须采取超时方式。

死锁检测与回滚

InnoDB 会自动检测一个事务的死锁并回滚一个或多个事务来防止死锁。从 4.0.5 版开始,InnoDB 将设法提取小的事务来进行回滚。一个事务的大小由它所插入(insert)、更新(update)和删除(delete)的数据行数决定。 Previous to 4.0.5, InnoDB always rolled back the transaction whose lock request was the last one to build a deadlock, that is, a cycle in the waits-for graph of transactions.

InnoDB 不能检测出由 MySQL 的 LOCK TABLES 语句引起的死锁,或其它的表类型中的锁定所引起的死锁。你不得不通过在 my.cnf 中设置 innodb_lock_wait_timeout 参数来解决这些情形。

当 InnoDB 执行一个事务完整的回滚,这个事务所有所加的锁将被释放。然而,如果只一句的 SQL 语句因结果返回错误而进行回滚的,由这条 SQL 语句所设置的锁定可能会被保持。这是因为 InnoDB r的行锁存储格式无法知道锁定是由哪个 SQL 语句所设置。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/15498/viewspace-2138850/,如需转载,请注明出处,否则将追究法律责任。

mysql死锁检测算法_MySQL InnoDB如何应付死锁相关推荐

  1. mysql死锁检测算法_MySQL 8 死锁检测脚本

    MySQL 8 记录死锁关的几张表有所变化,重新写一个脚本,便于在出现问题的时候快速处置问题. 死锁示意图 死锁相关的表 information_schema.INNODB_TRX `performa ...

  2. mysql 表死锁_MySQL Innodb表导致死锁日志情况分析与归纳

    案例描述在定时脚本运行过程中,发现当备份表格的sql语句与删除该表部分数据的sql语句同时运行时,mysql会检测出死锁,并打印出日志. 两个sql语句如下:(1)insert into backup ...

  3. C语言描述死锁检测算法,天津科技大学计算机科学与信息工程学院2013考研复试考试大纲...

    010 计算机科学与信息工程学院 Ⅰ.考查目标 自命题计算机学科专业基础综合考试涵盖操作系统.计算机网络二门学科专业基础课程.要求考生系统地掌握上述专业基础课程的概念.基本原理和基本方法,能够运用所学 ...

  4. mysql索引排序算法_MySQL中利用索引对数据进行排序的基础教程

    MySQL中,有两种方式生成有序结果集:一是使用filesort,二是按索引顺序扫描.利用索引进行排序操作是非常快的,而且可以利用同一索引同时进行查找和排序操作.当索引的顺序与ORDER BY中的列顺 ...

  5. MySQL语言的算法_MySQL知识整理

    写在前面的话:秋招来临,博主对MySQL知识进行了整理,全文包括数据库优化和数据库基础两部分 数据库优化 1.优化的目的 [1]     避免页面访问的出错(5xx错误:慢查询无法加载:阻塞无法提交) ...

  6. mysql的join算法_mysql的Join算法-阿里云开发者社区

    实为吾之愚见,望诸君酌之!闻过则喜,与君共勉 测试数据 CREATE TABLE `dept_emp` ( `emp_no` int(11) NOT NULL, `dept_no` char(4) N ...

  7. mysql表空间权限_MySQL InnoDB表空间加密示例详解

    前言 从 MySQL5.7.11开始,MySQL对InnoDB支持存储在单独表空间中的表的数据加密 .此功能为物理表空间数据文件提供静态加密.该加密是在引擎内部数据页级别的加密手段,在数据页写入文件系 ...

  8. 操作系统之死锁检测算法:银行家算法

    一.银行家算法 银行家是用来检测进程是否会发送死锁的一种算法,这是死锁避免的一种提前预防的机制.可以利用银行家算法进行系统安全进行一个预估.下面我将用一个案例来详细介绍银行家算法的过程. 二.银行家算 ...

  9. mysql 散列查询_MySQL InnoDB中hash查找表的实现

    MySQL版本:5.7.14 源码位置为hash0hash.h hash0hash.cc 作为一种时间复杂度最优为O(1)的数据结构,但是最坏时间复杂对位O(n)的一种数据结构,但是在良好的设计has ...

最新文章

  1. Swift3字符串转换为其他数据类型
  2. python中打印二维列表数据
  3. Xp下的程序编译成linux,WinXP下打造自己的linux 0.11简易编译环境(原创)
  4. 设计类超实用的导航网站,一网包含1000+个行业内热门资讯灵感源!
  5. VB得到指定文件夹下的文件列表
  6. Asp.Net Core 项目实战之权限管理系统(0) 无中生有
  7. 讨论简书留言界面的设计
  8. 下载mysql的驱动包
  9. 菜鸟教程 Python100例答案
  10. 1、结构化、面向对象程序设计差别、类基本概念
  11. 机器学习基本 之 名词解释
  12. C#实现Modbus协议与PLC通信
  13. 产业安全专家谈丨数字经济高速发展,数据要素安全该如何保障?
  14. 【计算机组成原理】学了计组,CPU执行时间你肯定会算了吧
  15. 介绍计算机专业说明文,描述电脑说明文600字.doc
  16. SAS JAVA基础开发包下载
  17. 弘辽科技:拼多多商品限制推广多久解封?怎么申诉?
  18. 牛客BM99-顺时针旋转矩阵-C++
  19. PTA 7-80 打折促销*
  20. gp数据库和mysql数据库的区别_pg和gp数据库

热门文章

  1. 剑指offer 09变态跳台阶
  2. iOS App打包上架超详细流程1
  3. Mac终端使用技巧 切换到其他路径和目录
  4. jQuery实现锚点滑动定位
  5. 多线程上下文切换优化与注意
  6. 我的2008,专注而行
  7. django调用python脚本返回_Django使用HttpResponse返回图片并显示的方法
  8. python到底有什么用-Python中的闭包到底有什么用
  9. Ubuntu18.04设置DNS服务器(可用)
  10. Android pm命令(持续更新中...)