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日

相关文章

  • 解决Linux下php-fpm进程过多导致内存耗尽问题

    当Linux下的php-fpm进程过多时,可能会导致服务器的内存耗尽,从而使得服务器的性能下降,网站无法正常访问。解决此问题的攻略有以下几步: 步骤一:调整php-fpm配置 要解决php-fpm进程过多导致内存耗尽的问题,首先需要调整php-fpm的配置。具体操作如下: 编辑php-fpm的配置文件php-fpm.conf: $ sudo vim /etc…

    database 2023年5月22日
    00
  • MySQL高级开发中视图的详细教程

    MySQL高级开发中视图的详细教程 一、视图是什么? 视图(View)是一种虚拟存在的表,具有表的特性,使用时与表完全相同,但与表不同的是,它没有实际的数据存储。 其中,视图是使用SQL语句查询语句产生的结果集并进行存储的,也可以是其他视图的基础上进行定义 二、视图的类型 MySQL中视图分为以下两种: 普通视图(Non-updatable Views):只…

    database 2023年5月22日
    00
  • linux中了minerd之后的完全清理过程(详解)

    Linux中清理MinerD的完整攻略 在Linux系统中,MinerD是一个常见的恶意软件,它会利用计算机的CPU或GPU来进行挖矿操作,导致计算机性能下降,甚至造成硬件损坏。以下是完整的清理攻略。 1. 停止MinerD进程 首先需要停止MinerD进程,以释放CPU或GPU资源。可以通过以下命令查看进程列表: ps -A |grep minerd 若能…

    database 2023年5月22日
    00
  • SQL Server 服务器优化技巧浅谈

    SQL Server 服务器优化技巧浅谈 优化技巧的重要性 SQL Server 数据库是大型企业和中小型企业的重要数据中心。优化 SQL Server 服务器是保持系统运行稳定和数据安全的关键要素。一个优化良好的 SQL Server 数据库可以提高性能和可用性,并且可以随着时间的推移减少运行成本。本文将讨论 SQL Server 服务器优化的技巧,从系统…

    database 2023年5月19日
    00
  • Orancle的SQL语句之多表查询和组函数

    下面就是关于“Oracle的SQL语句之多表查询和组函数”的完整攻略。 多表查询 在实际的业务场景中,我们经常需要从多个表中查询数据,这就要用到多表查询。Oracle中的多表查询主要有三种方式: 内连接:查询两个表中的共同数据,即交集。使用 INNER JOIN 或 JOIN 关键字实现。 左连接:查询第一个表中的所有数据和第二个表中的共同数据,即左表包含所…

    database 2023年5月21日
    00
  • Redhat 6.5下MySQL5.6集群配置方法完整版

    Redhat 6.5下MySQL5.6集群配置方法完整版 1. 环境准备 1.1 安装MySQL 首先需要为每个节点安装MySQL5.6,可以从MySQL官网下载对应的rpm文件进行安装。具体命令如下: rpm -ivh MySQL-server-5.6.30-1.el6.x86_64.rpm rpm -ivh MySQL-client-5.6.30-1.e…

    database 2023年5月22日
    00
  • SQL SERVER 数据库备份的三种策略及语句

    请看下面的详细讲解。 SQL SERVER 数据库备份的三种策略及语句 SQL SERVER 数据库备份是一项重要的维护任务,可以帮助我们在数据库受到恶意攻击、硬件故障等情况下快速恢复数据。我们可以采用以下三种备份策略: 1. 完整备份 完整备份是指备份整个数据库的策略,它可以备份数据库中所有的数据和日志文件,并将它们保存在备份文件中。当你需要恢复数据库时,…

    database 2023年5月21日
    00
  • 一款高颜值且免费的 SQL 开发工具之Beekeeper Studio详解

    一款高颜值且免费的 SQL 开发工具之 Beekeeper Studio 详解 Beekeeper Studio 简介 Beekeeper Studio 是一款兼容所有主流数据库的 SQL 开发工具,它采用现代化的界面设计,支持多种操作系统,包括 Windows、MacOS 和 Linux 等。Beekeeper Studio 能够方便地连接到 MySQL、…

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