sqlserver怎么清除死锁

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sqlserver怎么清除死锁相关的知识,希望对你有一定的参考价值。

1、首先需要判断是哪个用户锁住了哪张表.

查询被锁表

select request_session_id spid,OBJECT_NAME(resource_associated_entity_id) tableName 
from sys.dm_tran_locks where resource_type='OBJECT'

查询后会返回一个包含spid和tableName列的表.

其中spid是进程名,tableName是表名.

2.了解到了究竟是哪个进程锁了哪张表后,需要通过进程找到锁表的主机.

查询主机名

exec sp_who2 'xxx'

xxx就是spid列的进程,检索后会列出很多信息,其中就包含主机名.

3.通过spid列的值进行关闭进程.

关闭进程

declare @spid int
Set @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怎么清除死锁的主要内容,如果未能解决你的问题,请参考以下文章

sqlserver2008r2 死锁

(4.7)怎么捕获和记录SQL Server中发生的死锁?

sql server 2008 r2 日志文件过大怎么清除

SQLServer死锁的解除方法

sqlServer查看死锁及解锁

sqlserver表被锁了怎么解决