Mysql查看死锁与解除死锁的深入讲解

Mysql查看死锁与解除死锁的深入讲解

什么是死锁

在多个并发事务中,每个事务都需要访问其他事务持有的资源时,如果某个事务因为等待资源而被阻塞,同时它又持有其他事务需要的资源,就会发生死锁现象。

查看死锁

可以使用以下命令查看Mysql中的死锁信息:

SHOW ENGINE INNODB STATUS;

该命令会返回一个INNODB STATUS的输出,其中包含有关当前事务和锁定状态的信息,包括死锁信息。

在输出中找到“LATEST DETECTED DEADLOCK”这一行,它将提供有关最新检测到的死锁的信息。例如:

LATEST DETECTED DEADLOCK
------------------------
2020-07-14 12:00:00 0x7f0f4b909700
*** (1) TRANSACTION:
TRANSACTION 21387481, ACTIVE 0 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 10 lock struct(s), heap size 1136, 3 row lock(s)
MySQL thread id 1234567, OS thread handle 47151658949888, 

*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 134463 page no 51 n bits 288 index ux_id of table `db`.`test` trx id 21387481 lock_mode X waiting
Record lock, heap no 8 PHYSICAL RECORD: n_fields 9; compact format; info bits 32

*** (2) TRANSACTION:
TRANSACTION 21387485, ACTIVE 0 sec fetching rows
mysql tables in use 1, locked 1
6 lock struct(s), heap size 1136, 8 row lock(s), undo log entries 6
MySQL thread id 1234568, OS thread handle 47131778237296, 

*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 134463 page no 51 n bits 288 index ux_id of table `db`.`test` trx id 21387485 lock_mode X
Record lock, heap no 8 PHYSICAL REDO n_fields 9; compact format; info bits 32

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 134463 page no 51 n bits 288 index ux_id of table `db`.`test` trx id 21387485 lock_mode X locks rec but not gap waiting
Record lock, heap no 4 PHYSICAL RECORD: n_fields 9; compact format; info bits 32

*** WE ROLL BACK TRANSACTION (2)

解除死锁

当发生死锁时,需要手动解除死锁。可以在Mysql客户端使用以下语句来解除死锁:

KILL <thread_id>;

其中<thread_id>为发生死锁的线程ID。

同时,也可以将innodb_lock_wait_timeout设置为一个较小的值,以尽快检测和解除死锁。例如:

SET innodb_lock_wait_timeout = 120;

当等待锁定时间超过120秒时,将自动解除死锁。

示例说明

下面是两个关于Mysql死锁的示例:

示例一

假设表t1t2中都有数据,执行以下事务:

-- 事务一
START TRANSACTION;
UPDATE t1 SET c1 = c1 + 1 WHERE id = 1;
UPDATE t2 SET c2 = c2 + 1 WHERE id = 1;
COMMIT;

-- 事务二
START TRANSACTION;
UPDATE t2 SET c2 = c2 + 1 WHERE id = 1;
UPDATE t1 SET c1 = c1 + 1 WHERE id = 1;
COMMIT;

如果以上两个事务同时进行,就会陷入死锁现象。可以通过查看死锁信息来找到故障源并解除死锁。假设输出如下:

LATEST DETECTED DEADLOCK
------------------------
2020-07-14 12:00:00 0x7f0f4b909700
*** (1) TRANSACTION:
TRANSACTION 21387481, ACTIVE 0 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 10 lock struct(s), heap size 1136, 3 row lock(s)
MySQL thread id 1234567, OS thread handle 47151658949888, 

*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 134463 page no 51 n bits 288 index ux_id of table `db`.`t1` trx id 21387481 lock_mode X waiting
Record lock, heap no 8 PHYSICAL RECORD: n_fields 9; compact format; info bits 32

*** (2) TRANSACTION:
TRANSACTION 21387485, ACTIVE 0 sec fetching rows
mysql tables in use 1, locked 1
6 lock struct(s), heap size 1136, 8 row lock(s), undo log entries 6
MySQL thread id 1234568, OS thread handle 47131778237296, 

*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 134463 page no 51 n bits 288 index ux_id of table `db`.`t1` trx id 21387485 lock_mode X
Record lock, heap no 8 PHYSICAL REDO n_fields 9; compact format; info bits 32

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 134463 page no 51 n bits 416 index PRIMARY of table `db`.`t2` trx id 21387485 lock_mode X locks rec but not gap waiting
Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0

*** WE ROLL BACK TRANSACTION (2)

第一个事务(线程ID为21387481)正在等待表t1的锁,而第二个事务(线程ID为21387485)则正在持有表t1的锁,并在等待表t2的锁。因此,第二个事务被回滚以解除死锁。

示例二

假设表t中有数据,执行以下单个事务:

START TRANSACTION;
UPDATE t SET c = c + 1 WHERE id = 1;
UPDATE t SET c = c + 1 WHERE id = 2; -- 将where条件改为id = 1
COMMIT;

在第二个UPDATE语句中,将WHERE条件从id = 2更改为id = 1,这会导致在更新表之前发生死锁。

当执行该事务时,Mysql可能会输出以下消息:

ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

此时可以使用SHOW ENGINE INNODB STATUS来查看死锁信息,然后手动解除死锁。需要注意的是,Mysql在发生死锁时会自动回滚修改,因此不需要手动恢复数据。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Mysql查看死锁与解除死锁的深入讲解 - Python技术站

(0)
上一篇 2023年5月21日
下一篇 2023年5月21日

相关文章

  • SQL Server统计信息更新时采样百分比对数据预估准确性的影响详解

    SQL Server统计信息更新时采样百分比对数据预估准确性的影响详解 什么是SQL Server统计信息? SQL Server统计信息指的是存储在系统中的数据库对象的统计信息。这些统计信息给查询优化器提供了有关如何访问数据的信息,以便优化查询计划和执行时间。在SQL Server中,查询优化器使用这些统计信息来估算查询中每个操作的代价和行数,以便选择最佳…

    database 2023年5月21日
    00
  • Springboot mybais配置多数据源过程解析

    下面就详细讲解“Springboot mybais配置多数据源过程解析”的完整攻略。 一、引入依赖 首先,我们需要在pom.xml文件中引入相关的依赖,具体如下: <dependencies> <!–SpringBoot启动器–> <dependency> <groupId>org.springframew…

    database 2023年5月18日
    00
  • SpringBoot整合Mybatis,解决TypeAliases配置失败的问题

    下面我将为你详细讲解SpringBoot整合Mybatis时,解决TypeAliases配置失败的问题的完整攻略。 问题分析 在SpringBoot整合Mybatis时,我们可能会遇到TypeAliases配置失败的问题。这是因为在SpringBoot中,MyBatis使用的xml配置文件和实体类不在同一个包下,导致Mybatis无法自动扫描路径下的类。 解…

    database 2023年5月22日
    00
  • 如何在SQL Server 2008下轻松调试T-SQL语句和存储过程

    下面是详细讲解如何在SQL Server 2008下轻松调试T-SQL语句和存储过程的完整攻略: 1. 在SQL Server Management Studio中启用调试功能 首先,我们需要确认SQL Server Management Studio是否已经启用了调试功能。可以在菜单栏中依次点击 “工具” -> “选项” -> “调试” 来查看…

    database 2023年5月21日
    00
  • 解决python写入mysql中datetime类型遇到的问题

    下面我为你介绍解决Python写入MySQL中datetime类型遇到的问题的完整攻略。 问题背景 MySQL数据库中的datetime类型在Python中的写入与读取操作中常常会遇到一些问题,如写入的时间与MySQL数据库中实际存储的时间不一致、读取的时间格式不正确等等,这些问题都是由于datetime类型在不同的环境中使用时格式的不同所引起的。 解决步骤…

    database 2023年5月22日
    00
  • 快速安装openshift的步骤详解

    快速安装 OpenShift 步骤详解 前置条件 在安装 OpenShift 前,你需要先准备好以下内容: 安装并配置好 Docker 安装并配置好 Kubernetes 安装并配置好 etcd 安装并配置好 OpenShift CLI 工具 oc 步骤一:下载并安装 OpenShift 打开 OpenShift 官网 https://www.openshi…

    database 2023年5月22日
    00
  • VPS自动备份数据库到FTP的脚本代码

    首先,我们需要明确什么是VPS、FTP和数据库自动备份脚本。VPS指的是Virtual Private Server,即虚拟专用服务器,是一种虚拟化技术,能够在一台物理机器上划分出多个独立的虚拟服务器。FTP指的是文件传输协议,是一种用于文件传输的网络协议。数据库自动备份脚本则是一段自动化脚本代码,能够在设定时间内自动备份VPS服务器上的数据库,并将备份文件…

    database 2023年5月22日
    00
  • SQL设置SQL Server最大连接数及查询语句

    针对SQL Server最大连接数及查询语句的问题,这里提供一份完整攻略,分为以下几个步骤: 1. 查看当前的最大连接数 首先,我们需要查看当前SQL Server的最大连接数设置,以便后续的修改。使用以下SQL语句即可查看: SELECT @@MAX_CONNECTIONS; 执行成功后,可以在结果中看到当前最大连接数的值。 2. 修改最大连接数 接下来,…

    database 2023年5月21日
    00
合作推广
合作推广
分享本页
返回顶部