sqlserver怎么清除死锁
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sqlserver怎么清除死锁相关的知识,希望对你有一定的参考价值。
1、首先需要判断是哪个用户锁住了哪张表.
查询被锁表
select request_session_id spid,OBJECT_NAME(resource_associated_entity_id) tableNamefrom sys.dm_tran_locks where resource_type='OBJECT'
查询后会返回一个包含spid和tableName列的表.
其中spid是进程名,tableName是表名.
2.了解到了究竟是哪个进程锁了哪张表后,需要通过进程找到锁表的主机.
查询主机名
xxx就是spid列的进程,检索后会列出很多信息,其中就包含主机名.
3.通过spid列的值进行关闭进程.
关闭进程
declare @spid intSet @spid = xxx --锁表进程
declare @sql varchar(1000)
set @sql='kill '+cast(@spid as varchar)
exec(@sql)
PS:有些时候强行杀掉进程是比较危险的,所以最好可以找到执行进程的主机,在该机器上关闭进程.
参考技术A查询语句的表名后加(nolock)少用临时表和group by HAVING。
这是与检测死锁相配套的一种措施。
当检测到系统中已发生死锁时,须将进程从死锁状态中解脱出来。
常用的实施方法是撤销或挂起一些进程,以便回收一些资源,再将这些资源分配给已处于阻塞状态的进程,使之转为就绪状态,以继续运行。
死锁的检测和解除措施,有可能使系统获得较好的资源利用率和吞吐量,但在实现上难度也最大。
参考技术B 重启SQL服务即可如何清除事务死锁?
【中文标题】如何清除事务死锁?【英文标题】:How can I clear a transaction deadlock? 【发布时间】:2011-07-24 15:37:58 【问题描述】:使用 'show engine innodb status' 我看到 wordpress 有两个死锁。我想清除这些,但我看不到这些 cmd 中的任何一个的活动进程(即“杀死”并希望强制回滚)。
我可以看到线程 ID、查询 ID 等,但没有任何东西可以用来停止任何一项工作。
关于如何解决这个问题的建议?
编辑:这是状态的(相关?)部分:
------------------------
LATEST DETECTED DEADLOCK
------------------------
110327 10:54:14
*** (1) TRANSACTION:
TRANSACTION 9FBA099E, ACTIVE 0 sec, process no 14207, OS thread id 1228433728 starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 376, 1 row lock(s)
MySQL thread id 12505112, query id 909492800 juno....edu 129....54 wordpress_user updating
DELETE FROM wp_options WHERE option_name = ''_site_transient_timeout_theme_roots''
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 4951009 page no 4 n bits 384 index `option_name` of table `wordpress_work`.`wp_options` trx id 9FBA099E lock_mode X waiting
Record lock, heap no 309 PHYSICAL RECORD: n_fields 2; compact format; info bits 32
0: len 30; hex 5f736974655f7472616e7369656e745f74696d656f75745f7468656d655f; asc _site_transient_timeout_theme_; (total 35 bytes);
1: len 8; hex 0000000000002b6d; asc +m;;
*** (2) TRANSACTION:
TRANSACTION 9FBA0995, ACTIVE 0 sec, process no 14207, OS thread id 1230031168 starting index read
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1248, 2 row lock(s)
MySQL thread id 12505095, query id 909492789 juno....edu 129.....54 wordpress_user updating
DELETE FROM wp_options WHERE option_name = ''_site_transient_timeout_theme_roots''
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 4951009 page no 4 n bits 384 index `option_name` of table `wordpress_work`.`wp_options` trx id 9FBA0995 lock_mode X locks rec but not gap
Record lock, heap no 309 PHYSICAL RECORD: n_fields 2; compact format; info bits 32
0: len 30; hex 5f736974655f7472616e7369656e745f74696d656f75745f7468656d655f; asc _site_transient_timeout_theme_; (total 35 bytes);
1: len 8; hex 0000000000002b6d; asc +m;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 4951009 page no 4 n bits 384 index `option_name` of table `wordpress_work`.`wp_options` trx id 9FBA0995 lock_mode X waiting
Record lock, heap no 309 PHYSICAL RECORD: n_fields 2; compact format; info bits 32
0: len 30; hex 5f736974655f7472616e7369656e745f74696d656f75745f7468656d655f; asc _site_transient_timeout_theme_; (total 35 bytes);
1: len 8; hex 0000000000002b6d; asc +m;;
*** WE ROLL BACK TRANSACTION (1)
【问题讨论】:
但所述查询未通过“显示进程列表”显示 我认为你需要终止连接 这是最后检测到的已经被mysql处理的死锁,因此*** WE ROLL BACK TRANSACTION (1)
【参考方案1】:
给定一些像这样的“innodb status”输出:
---TRANSACTION 0 0, not started, process no 1024, OS thread id 140386055603968
MySQL thread id 197, query id 771 localhost marc
show innodb status
你想做的
KILL QUERY 771
杀死两个死锁的查询之一。这将终止查询,但保持连接打开。如果你想终止连接,那么你会做KILL 197
。
【讨论】:
这应该是新版本的 mysql 中的show engine innodb status
,我在 5.6.10 上,show innodb status
不是一个有效的命令。
我遇到过类似的情况。这与show
命令语法无关。由于show processlist
没有显示与这些查询相关的任何连接,这意味着这些死锁事务保留在存储引擎级别,而不是 MySQL API 级别。我发现解决此类问题的唯一方法是重新启动 MySQL 的服务。
你应该杀死'MySQL thread id',在这个例子中是197。
这个答案是错误的。死锁检测是“即时的”,当它被记录时,不需要更多的操作。该部分仅供参考。
@jkavalik 在极少数情况下,持有锁的线程可能会无限期挂起,需要在再次释放锁之前手动终止。这不是通常发生在死锁中的情况,但除了死锁本身之外,我还遇到过这种情况。【参考方案2】:
我知道这已经过时了,但通常当您看到这样的情况时,这是因为发生了死锁,并且触发死锁的应用程序早已继续运行——死锁的受害者收到警告,要么失败,要么记录了错误或重试,无论哪种方式都已转移到其他富有成效的事情上。如果您正在编写软件,您通常不需要做任何事情,只需查看死锁的原因并尝试避免将来出现死锁。如果您只是使用该软件(例如,如果您不在 Wordpress 工作,则使用 Wordpress),您可以将死锁报告为可能的错误。
【讨论】:
【参考方案3】:使用 'show engine innodb status' 我看到 wordpress 有两个死锁...关于如何解决这个问题的建议?
我们看到 Java 休眠问题导致卡住锁。我们通过梳理以下输出找到了锁:
show engine innodb status;
这会吐出一大堆信息。相关部分位于TRANSACTIONS
部分。在您的输出中,相关问题似乎是:
3 lock struct(s), heap size 1248, 2 row lock(s)
MySQL thread id 12505095, query id 909492789 juno....edu 129.....54
对我们来说,# lock struct(s)
表示锁被卡住了。要杀死它,您需要使用指定的“线程 id #”来执行——在这种情况下:
kill 12505095
这适用于 AWS MySQL RDS 以及本地 MySQL。
在我们的 TRANSACTIONS 部分中,我们还看到以下内容:
---TRANSACTION 644793773, ACTIVE 21 sec
2 lock struct(s), heap size 360, 1 row lock(s)
MySQL thread id 217, OS thread handle 0x2aef097700, query id 1177 1.3.5.7 mpsp cleaning up
我们同时查找2 lock struct(s)
和ACTIVE 21 sec
消息。
【讨论】:
以上是关于sqlserver怎么清除死锁的主要内容,如果未能解决你的问题,请参考以下文章