如何查看MySQL数据库的死锁信息

如何查看MySQL数据库的死锁信息,第1张

1. 使用终端或命令提示符登录到MySQL,输入命令:mysql -h xxxx.xxx.xxx -P 3306 -u username -p 

解释:xxxx.xxx.xxx是数据库IP地址,username是数据库用户名,输入命令后,会让你输入username对应的密码,就可以登录了

2. 如何查看MySQL数据库的死锁信息 

在MySQL客户端下输入命令: 

show engine innodb status \G 

3. 如何定位MySQL数据库的死锁信息 

在打印出来的信息中找到“LATEST DETECTED DEADLOCK”一节内容,看图中红线 

4. 如何分析日志,定位死锁原因 

看3里面的图,紫色划线部分 

分析: 

事务1,等待 

RECORD LOCKS space id 553 page no 376 n bits 368 index `index_user_id` of table `tbj`.`score_user`,这个位置的X锁 

事务2,持有 

RECORD LOCKS space id 553 page no 376 n bits 368 index `index_user_id` of table `tbj`.`score_user`这个地方的S锁 

事务2,等待这个地方的X锁 

理论上这个事务2是可以提交的不会,死锁,但是这个事务日志只打印最后一部分死锁,信息,这里面隐含的条件是,事务1也持有 

RECORD LOCKS space id 553 page no 376 n bits 368 index `index_user_id` of table `tbj`.`score_user`这个地方的S锁,这样,事务2不能加X锁,同时事务1也不能加X锁,产生死锁。

Oracle数据库出现死锁的时候可以按照以下处理步骤加以解决:

第一步:尝试在sqlplus中通过sql命令进行删除,如果能够删除成功,则万事大吉!但通常情况下,出现死锁时,想通过命令行或者通过Oracle的管理工具删除有死锁的session,oracle只会将该session标记为killed,但无法清除掉,往往需要通过第二步在 *** 作系统层级进行删除!

Connected to Oracle9i Enterprise Edition Release 9.2.0.1.0 

Connected as quik

SQL> select xidusn, object_id, session_id, locked_mode from v$locked_object --查死锁的对象,获取其SESSION_ID

XIDUSN OBJECT_ID SESSION_ID LOCKED_MODE

---------- ---------- ---------- -----------

10 30724 29 3

10 30649 29 3

SQL> select username,sid,serial# from v$session where sid=29 --根据上步获取到的sid查看其serial#号

USERNAME SID SERIAL#

------------------------------ ---------- ----------

QUIK 29 57107

SQL> alter system kill session '29,57107' --删除进程,如已经删除过,则会报ora-00031的错误;否则oracle会将该session标记为killed状态,等待一段时间看能否会自动消失,如长时间消失不掉,则需要做后续步骤

alter system kill session '29,57107'

ORA-00031: session marked for kill

SQL> select pro.spid from v$session ses,v$process pro where ses.sid=29 and ses.paddr=pro.addr --查看spid号,以便在 *** 作系统中根据该进程号删除进程

SPID

------------

2273286

第二步:进入 *** 作系统进行删除进程,本示例的 *** 作系统是IBM aix。

login: root --录入用户名

root's Password: --录入密码

*******************************************************************************

* *

* *

* Welcome to AIX Version 5.3! *

* *

* *

* Please see the README file in /usr/lpp/bos for information pertinent to *

* this release of the AIX Operating System. *

* *

* *

*******************************************************************************

Last unsuccessful login: Fri Apr 23 14:42:57 BEIDT 2010 on /dev/pts/1 from 10.73

.52.254

Last login: Fri Apr 23 15:27:50 BEIDT 2010 on /dev/pts/2 from 10.73.52.254

# ps -ef|grep 2273286 --查看进程详情

root 2289864 2494636 0 17:07:15 pts/1 0:00 grep 2273286

oracle 2273286 1 0 14:38:24 - 0:21 oracleQUIK (LOCAL=NO)

# kill -9 2273286 --删除进程,小心 *** 作,别写错进程号,如果oracle的关键进程被删,数据库会崩溃的!

# ps -ef|grep 2273286 --再次查看

root 2289864 2494636 0 17:07:15 pts/1 0:00 grep 2273286

For Windows, at the DOS Prompt: orakill sid spid

For UNIX at the command line> kill –9 spid

数据库 *** 作的死锁是不可避免的,本文并不打算讨论死锁如何产生,重点在于解决死锁,通过SQL

Server

2005,

现在似乎有了一种新的解决办法。

将下面的SQL语句放在两个不同的连接里面,并且在5秒内同时执行,将会发生死锁。

use

Northwind

begin

tran

insert

into

Orders(CustomerId)

values(@#ALFKI@#)

waitfor

delay

@#00:00:05@#

select

*

from

Orders

where

CustomerId

=

@#ALFKI@#

commit

print

@#end

tran@#

SQL

Server对付死锁的办法是牺牲掉其中的一个,抛出异常,并且回滚事务。在SQL

Server

2000,语句一旦发生异常,T-SQL将不会继续运行,上面被牺牲的连接中,

print

@#end

tran@#语句将不会被运行,所以我们很难在SQL

Server

2000的T-SQL中对死锁进行进一步的处理。

现在不同了,SQL

Server

2005可以在T-SQL中对异常进行捕获,这样就给我们提供了一条处理死锁的途径:

下面利用的try

...

catch来解决死锁。

SET

XACT_ABORT

ON

declare

@r

int

set

@r

=

1

while

@r

<=

3

begin

begin

tran

begin

try 

insert

into

Orders(CustomerId)

values(@#ALFKI@#)

waitfor

delay

@#00:00:05@#

select

*

from

Orders

where

CustomerId

=

@#ALFKI@#

commit

break

end

try

begin

catch

rollback

waitfor

delay

@#00:00:03@#

set

@r

=

@r

+

1

continue

end

catch

end

解决方法当然就是重试,但捕获错误是前提。rollback后面的waitfor不可少,发生冲突后需要等待一段时间,@retry数目可以调整以应付不同的要求。

但是现在又面临一个新的问题:

错误被掩盖了,一但问题发生并且超过3次,异常却不会被抛出。SQL

Server

2005

有一个RaiseError语句,可以抛出异常,但却不能直接抛出原来的异常,所以需要重新定义发生的错误,现在,解决方案变成了这样:

declare

@r

int

set

@r

=

1

while

@r

<=

3

begin

begin

tran

begin

try 

insert

into

Orders(CustomerId)

values(@#ALFKI@#)

waitfor

delay

@#00:00:05@#

select

*

from

Orders

where

CustomerId

=

@#ALFKI@#

commit

break

end

try

begin

catch

rollback

waitfor

delay

@#00:00:03@#

set

@r

=

@r

+

1

continue

end

catch

end

if

ERROR_NUMBER()

<>

0

begin

declare

@ErrorMessage

nvarchar(4000)

declare

@ErrorSeverity

int

declare

@ErrorState

int

select

@ErrorMessage

=

ERROR_MESSAGE(),

@ErrorSeverity

=

ERROR_SEVERITY(),

@ErrorState

=

ERROR_STATE()

raiserror

(@ErrorMessage,

 

@ErrorSeverity,

 

@ErrorState

 

)

end


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/sjk/6771240.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-03-28
下一篇2023-03-28

发表评论

登录后才能评论

评论列表(0条)

    保存