`

一则MySQL deadlock问题的解决

 
阅读更多

用户反馈服务器日志中出现大量:Deadlock found when trying to get lock; Try restarting transaction message from server: "Lock wait timeout exceeded; try restarting transaction";

进行了一段时间loadrunner并发测试并在网上找了很多先行者的文章,之后终于找到了解决的方法:

 

基本条件:

服务器存在两个进程(线程)均需要对同一个table进行插入动作:
表xxshistory(id2,id1,row1,row2),主键(id2,id1,row1),外键FK_1(id2,id1)
表zzequip主键(id2,id1),含字段netstat

线程1:
    对xxshistory表插入当天数据,如:
    insert into xxshistory(id2,id1,row1,row2)values(?,?,?,?);
线程2:
    对xxshistory表插入当天数据,sql例:
INSERT INTO xxshistory (id1,row1,row2,id2)  SELECT * FROM (SELECT h.id1,'2016-11-30','3 ' , h.id2 FROM xxshistory h LEFT JOIN zzequip s ON h.id1=s.AID AND h.id2=s.id2 AND s.netstat='1' GROUP BY h.id1,h.id2 HAVING MAX(h.row1)<'2016-11-30' ) AS b

-----------------然后就是deadlock
Deadlock found when trying to get lock; Try restarting transaction message from server: "Lock wait timeout exceeded; try restarting transaction"

 

原因:

根据MYSQL EXPLAIN语句的执行结果 线程2的sql在操作中用到了外键索引,而显然线程1的操作是根据主键操作的;

线程1:插入过程,获得主键锁(s锁),仍需要外键锁,等待对外键FK_1索引加锁(x锁),

线程2:插入过程,获得外键索引锁(x锁),仍需申请主键锁,等待对主键加锁(s锁),

(备注:INSERT可能产生的锁包括检查dup key时的s锁lock mode S locks rec but not gap waiting,
插入意向锁lock_mode X locks gap before rec insert intention waiting)
并发形成死锁; (主键索引锁与非聚簇索引锁冲突)

解决办法:
避免主键索引锁与非聚簇索引锁冲突,在插入操作时都先得到需要操作的记录主键,根据主键插入。
线程2把查询和插入操作拆分,先查询得到对应主键信息:
 " SELECT h.id1,'' ,'' ,h.id2 FROM statushistory h LEFT JOIN zzequip  s ON h.id1=s.AID AND h.id2=s.id2 AND s.netstat='1' "+ "GROUP BY h.id1,h.id2 HAVING MAX(h.row1)<'' ;
在逐条根据主键信息插入。
上述改进解决了deadlock问题,但是会产生主键冲突异常,解决办法是线程1、线程2在插入新记录时均增加ignore关键字以避免主键冲突;

deadlock日志:

=====================================
161130  0:02:54 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 38 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 2451 1_second, 2451 sleeps, 228 10_second, 750 background, 750 flush
srv_master_thread log flush and writes: 2663
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 205002, signal count 170785
Mutex spin waits 2454690, rounds 11657610, OS waits 127717
RW-shared spins 55583, rounds 971864, OS waits 20354
RW-excl spins 62517, rounds 1832253, OS waits 40305
Spin rounds per wait: 4.75 mutex, 17.48 RW-shared, 29.31 RW-excl
------------------------
LATEST DETECTED DEADLOCK
------------------------
161130  0:00:01
*** (1) TRANSACTION:
TRANSACTION 15B43CE, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 5 lock struct(s), heap size 1024, 3 row lock(s), undo log entries 1
MySQL thread id 21650, OS thread handle 0x347c, query id 6211894 localhost 127.0.0.1 usrer1 update
insert into xxshistory(id2,id1,row1,row2) values ('-1', 'X83','2016-11-30' ,'7 '  )
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 55130 n bits 672 index `FK_xxshistory` of table `db1`.`xxshistory` trx id 15B43CE lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 288 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 3; hex 583834; asc X84;;
 1: len 2; hex 2d31; asc -1;;
 2: len 3; hex 8fc16e; asc   n;;

*** (2) TRANSACTION:
TRANSACTION 15B352B, ACTIVE 1 sec inserting, thread declared inside InnoDB 500
mysql tables in use 3, locked 3
288 lock struct(s), heap size 44352, 73483 row lock(s), undo log entries 947
MySQL thread id 21608, OS thread handle 0x2c20, query id 6204529 localhost 127.0.0.1 usrer1 Sending data
INSERT INTO xxshistory (id1,row1,row2,id2)  SELECT * FROM (SELECT h.id1,'2016-11-30','3 ' , h.id2 FROM xxshistory h LEFT JOIN zzequiprow2 s ON h.id1=s.AID AND h.id2=s.id2 AND s.netstat='1' GROUP BY h.id1,h.id2 HAVING MAX(h.row1)<'2016-11-30' ) AS b
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 0 page no 55130 n bits 672 index `FK_xxshistory` of table `db1`.`xxshistory` trx id 15B352B lock mode S
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 3; hex 583634; asc X64;;
 1: len 2; hex 2d31; asc -1;;
 2: len 3; hex 8fc176; asc   v;;

 1: len 2; hex 2d31; asc -1;;
 2: len 3; hex 8fc16e; asc   n;;

Record lock, heap no 236 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 3; hex 583830; asc X80;;
 1: len 2; hex 2d31; asc -1;;
 2: len 3; hex 8fc16f; asc   o;;


------------------------中间省略

Record lock, heap no 600 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 3; hex 583732; asc X72;;
 1: len 2; hex 2d31; asc -1;;
 2: len 3; hex 8fc17e; asc   ~;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 56536 n bits 200 index `PRIMARY` of table `db1`.`xxshistory` trx id 15B352B lock mode S locks rec but not gap waiting
Record lock, heap no 122 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
 0: len 3; hex 583833; asc X83;;
 1: len 3; hex 8fc17e; asc   ~;;
 2: len 2; hex 2d31; asc -1;;
 3: len 6; hex 0000015b43ce; asc    [C ;;
 4: len 7; hex d70000d9d20110; asc        ;;
 5: len 30; hex 374e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e; asc 7NNNNNNNNNNNNNNNNNNNNNNNNNNNNN; (total 96 bytes);

*** WE ROLL BACK TRANSACTION (1)
------------
TRANSACTIONS
------------
Trx id counter 15E0036
Purge done for trx's n:o < 15E0034 undo n:o < 0
History list length 1198
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0, not started
MySQL thread id 22260, OS thread handle 0x1ce0, query id 6544403 localhost 127.0.0.1 root
show engine innodb row2
--------
FILE I/O
--------
I/O thread 0 state: wait Windows aio (insert buffer thread)
I/O thread 1 state: wait Windows aio (log thread)
I/O thread 2 state: wait Windows aio (read thread)
I/O thread 3 state: wait Windows aio (read thread)
I/O thread 4 state: wait Windows aio (read thread)
I/O thread 5 state: wait Windows aio (read thread)
I/O thread 6 state: wait Windows aio (write thread)
I/O thread 7 state: wait Windows aio (write thread)
I/O thread 8 state: wait Windows aio (write thread)
I/O thread 9 state: wait Windows aio (write thread)
Pending normal aio reads: 0 [0, 0, 0, 0] , aio writes: 0 [0, 0, 0, 0] ,
 ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0
Pending flushes (fsync) log: 0; buffer pool: 0
8881 OS file reads, 280945 OS file writes, 157745 OS fsyncs
0.00 reads/s, 0 avg bytes/read, 0.00 writes/s, 0.00 fsyncs/s
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 3, seg size 5, 0 merges
merged operations:
 insert 0, delete mark 0, delete 0
discarded operations:
 insert 0, delete mark 0, delete 0
Hash table size 1365571, node heap has 79 buffer(s)
0.00 hash searches/s, 0.00 non-hash searches/s
---
LOG
---
Log sequence number 3238511178
Log flushed up to   3238511178
Last checkpoint at  3238511178
0 pending log writes, 0 pending chkp writes
153570 log i/o's done, 0.00 log i/o's/second
----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 349536256; in additional pool allocated 0
Dictionary memory allocated 5236825
Buffer pool size   21056
Free buffers       11046
Database pages     9931
Old database pages 3653
Modified db pages  0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 16, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 8870, created 1061, written 124154
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
No buffer pool page gets since the last printout
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 9931, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
--------------
ROW OPERATIONS
--------------
0 queries inside InnoDB, 0 queries in queue
1 read views open inside InnoDB
Main thread id 2792, state: waiting for server activity
Number of rows inserted 363271, updated 1551713, deleted 349439, read 872878012
0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s
----------------------------
END OF INNODB MONITOR OUTPUT
============================

 

分享到:
评论

相关推荐

    mysql报错:Deadlock found when trying to get lock; try restarting transaction的解决方法

    MySQL中的死锁问题通常发生在并发事务之间,当两个或多个事务相互等待对方释放资源时发生。在描述的场景中,程序在尝试更新数据时遇到了"Deadlock found when trying to get lock; try restarting transaction"的...

    mysql死锁检测机制初探1

    在 MySQL 中,死锁检测机制是一种重要的机制,用于检测和解决事务之间的死锁问题。在本文中,我们将详细介绍 MySQL 死锁检测机制的原理和实现。 一、死锁的定义和原理 在 MySQL 中,死锁是指两个或两个以上的事务...

    MySQL死锁的产生原因以及解决方案

    本文将探讨MySQL死锁的产生原因以及解决方案。 **死锁的产生原因** 1. **资源竞争与顺序依赖**:当两个事务A和B分别持有对方需要的资源,A等待B释放资源,B也在等待A释放资源,就会形成死锁。例如,事务A锁定表A后...

    MySQL死锁问题分析及解决方法实例详解

    MySQL数据库在处理并发事务时,可能会遇到一种特殊的情况,即死锁(Deadlock),这是由于多个事务间的资源竞争导致的互相等待状态。本篇文章将深入探讨MySQL中的死锁问题,以及如何进行分析和解决。 首先,了解...

    MySQL 8.0的新特性简述

    MySQL 8.0 是一个重要的版本升级,引入了一系列新特性以提升数据库的性能、安全性和易用性。以下是对这些新特性的详细说明: 1. **数据字典**: MySQL 8.0 引入了一个事务性的数据字典,用于存储关于数据库对象的...

    mysql性能优化与诊断

    #### 一、MySQL存储引擎对比:MyISAM vs InnoDB 在MySQL中,MyISAM和InnoDB是最常用的两种存储引擎。对于不同的应用场景,选择合适的存储引擎至关重要。以下是对这两种存储引擎的主要特点进行的对比: - **空间...

    MySQL写输入时崩溃SQLAlchemy-0.7.8.zip

    MySQL数据库在进行写入操作时可能会遇到各种问题,其中一种常见的情况是系统崩溃,尤其是在使用ORM(对象关系映射)工具如SQLAlchemy时。SQLAlchemy是Python编程语言中广泛使用的库,它允许开发者以面向对象的方式...

    SQL死锁监控工具

    理解死锁监控工具的工作原理和使用方法是解决问题的第一步。当发现死锁时,需要深入分析事务的执行顺序、锁定资源的顺序以及事务的隔离级别等因素,找出引发死锁的原因。可能的解决方案包括优化SQL语句、调整事务的...

    InnoDB数据库死锁问题处理

    然而,这种灵活性也可能导致死锁(Deadlock)问题,即两个或多个事务在等待对方释放资源而形成的一种僵局。 当在更新表时遇到`DeadlockLoserDataAccessException`异常("Deadlock found when trying to get lock; ...

    mysql怎么减少行锁对性能的影响

    在MySQL数据库中,行锁是一种重要的锁定机制,它主要应用于InnoDB存储引擎中,用于控制并发事务对数据行的访问。行锁的使用可以显著提高系统的并发处理能力,但同时也会带来一定的性能开销。因此,了解如何有效地...

    【MySQL面试第二弹】MySQL 服务占用cpu 100%,如何排查问题?

    总的来说,解决MySQL服务CPU 100%的问题,需要综合运用监控、诊断和优化工具,结合业务逻辑和数据库特性,逐步排查并优化问题点。对于面试来说,掌握这些排查技巧不仅可以应对紧急问题,也是展现技术深度和解决问题...

    Mysql 8.0 新增特性1

    1. **事务型数据字典**:在MySQL 8.0中,数据库对象信息不再存储在元数据文件和非事务型表中,而是转移到了一个事务型的数据字典。这提供了更高的数据一致性,确保在系统崩溃或回滚操作后,数据库对象的状态仍然保持...

    Deadlock User Management System-开源

    今天我们要探讨的是一个名为"Deadlock User Management System"的开源项目,它专为保护Web目录和文档而设计,采用Apache的htaccess和htpasswd机制,为用户提供了一种强大的安全解决方案。 死锁用户管理系统是用PHP...

    MySQL 中查找含有目标字段的表的方法

    8. **mysql查找删除重复数据并只保留一条实例详解**:可以先使用`GROUP BY`和`MIN/MAX`或`COUNT(*)`找出重复记录,然后根据业务需求决定保留哪一条,最后通过`DELETE`或`UPDATE`语句进行处理。 了解这些相关知识点...

    MYSQL 解锁与锁表介绍

    首先,表级锁是MySQL中最简单也是最快的一种锁,它在MyISAM和MEMORY存储引擎中被广泛使用。表级锁一次性锁定整个表,这意味着当一个用户对表进行读或写操作时,其他用户无法同时进行其他读写操作,直到当前锁被释放...

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

    MySQL的InnoDB存储引擎在处理死锁问题上采用了一系列策略,确保数据库的正常运行和高并发性能。首先,我们需要理解什么是死锁。死锁是指两个或多个事务在执行过程中,因争夺资源而造成的一种相互等待的现象,若无...

    Java中死锁的例子

    在Java编程中,死锁(DeadLock)是一个重要的并发控制问题,它发生在两个或多个线程互相持有对方需要的资源并等待对方释放时,导致所有线程都无法继续执行的情况。死锁是多线程编程中需要特别注意和避免的问题,因为...

    死锁查找与排除工具

    它依赖于一系列的DLL库文件来处理与数据库的连接、通信以及死锁分析,而find_deadlock.exe则是实际执行这些操作的程序。通过这个工具,数据库管理员可以更高效地排查和修复死锁,保障数据库服务的稳定性和性能。

    互联网高频Java后端面试题20道(适合1~3年)V1.0.57.docx

    Java 中常见的线程安全问题包括数据竞争(race condition)、死锁(deadlock)、活锁(livelock)和饥饿(starvation)。例如,多个线程同时修改共享变量可能导致数据不一致,而死锁则发生在两个或更多线程互相等待...

    计院学网盘复习资料--数据库.zip

    SQL(Structured Query Language)是用于管理关系型数据库的标准语言,而MySQL则是一种广泛使用的开源关系数据库管理系统。本压缩包“计院学网盘复习资料--数据库.zip”显然是针对计算机学院学生的期末复习资料,...

Global site tag (gtag.js) - Google Analytics