관련글 :
by ceusee | 2009/07/20 17:17
Deadlock 발생시 원인과 해결법. 1. Deadlock 이유를 알고 싶으면 trace 1204 를 켜 준다. DBCC traceon(1204,-1) DBCC Tracestatus(...
deadlock이 자주 발생하는 쿼리가 있다면, 해당 원인을 찾아야 한다.
이때 T 1204를와 T 1222를 켜줘서 실행 확인이 가능하다.
1204만을 적용되었을 때는 dbcc page 번호를 통해 발생원인이 되는 객체와 인덱스를 찾으면 된다.
몇번의 deadlock이 발생후 멈추는거라면 쿼리를 반복 실행해서 원하는 결과를 얻게 할 수 있다.
이때
TRY ... CATCH 문을 이용하고 ERROR_NUMBER() = 1205를 사용해서 처리 가능핟.
** DeadLock 발생 예제 **
1. 필요한 객체 생성
[code sql]
USE AdventureWorks;
GO
-- Verify that the table does not exist.
IF OBJECT_ID (N'my_sales',N'U') IS NOT NULL
DROP TABLE my_sales;
GO
-- Create and populate the table for deadlock simulation.
CREATE TABLE my_sales
(
itemid INT PRIMARY KEY,
sales INT not null
);
GO
INSERT my_sales (itemid, sales) VALUES (1, 1);
INSERT my_sales (itemid, sales) VALUES (2, 1);
GO
-- Create a stored procedure for printing error information.
CREATE PROCEDURE usp_MyErrorLog
AS
PRINT
'Error ' + CONVERT(VARCHAR(50), ERROR_NUMBER()) +
', Severity ' + CONVERT(VARCHAR(5), ERROR_SEVERITY()) +
', State ' + CONVERT(VARCHAR(5), ERROR_STATE()) +
', Line ' + CONVERT(VARCHAR(5), ERROR_LINE());
PRINT
ERROR_MESSAGE();
GO
[/code]
2. session # 1, #2에 동시에 해당 쿼리를 실행한다.
#1을 먼저 실행하게되면, #2에서 deadlock가 발생하며, 재시도 처리하고
그후 원하는 내용으로 update 된다.
[code sql]
USE AdventureWorks;
GO
-- Declare and set variable
-- to track number of retries
-- to try before exiting.
DECLARE @retry INT;
DECLARE @count INT;
SET @retry = 2;
SET @count = 0
-- Keep trying to update
-- table if this task is
-- selected as the deadlock
-- victim.
WHILE (@retry > 0)
BEGIN
BEGIN TRY
BEGIN TRANSACTION;
UPDATE my_sales
SET sales = sales + 1
WHERE itemid = 1;
WAITFOR DELAY '00:00:8';
UPDATE my_sales
SET sales = sales + 1
WHERE itemid = 2;
SET @retry = 0;
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
-- Check error number.
-- If deadlock victim error,
-- then reduce retry count
-- for next update retry.
-- If some other error
-- occurred, then exit
-- retry WHILE loop.
IF (ERROR_NUMBER() = 1205)
BEGIN
SET @count = @count + 1;
SET @retry = @retry - 1;
SELECT @count as '[재 실행count]', ERROR_MESSAGE()
END
ELSE
SET @retry = -1;
-- Print error information.
EXECUTE usp_MyErrorLog;
IF XACT_STATE() <> 0
ROLLBACK TRANSACTION;
END CATCH;
END; -- End WHILE loop.
SELECT @count as '[총 실행count]'
GO
[/code]
deadlock이 발생했을 경우 errorlog 기록된 내역
2009-11-24 17:30:10.780 spid4s Wait-for graph
2009-11-24 17:30:10.780 spid4s NULL
2009-11-24 17:30:10.780 spid4s Node:1
2009-11-24 17:30:10.780 spid4s KEY: 10:72057594054639616 (020068e8b274) CleanCnt:3 Mode:X Flags: 0x0
2009-11-24 17:30:10.780 spid4s Grant List 1:
2009-11-24 17:30:10.780 spid4s Owner:0x054AD9A0 Mode: X Flg:0x0 Ref:0 Life:02000000 SPID:55 ECID:0 XactLockInfo: 0x0962185C
2009-11-24 17:30:10.780 spid4s SPID: 55 ECID: 0 Statement Type: UPDATE Line #: 24
2009-11-24 17:30:10.780 spid4s Input Buf: Language Event:
-- Declare and set variable
-- to track number of retries
-- to try before exiting.
DECLARE @retry INT;
DECLARE @count INT;
SET @retry = 2;
SET @count = 1;
--Keep trying to update
-- table if this task is
-- selected as the deadlock
-- vict
2009-11-24 17:30:10.780 spid4s Requested By:
2009-11-24 17:30:10.780 spid4s ResType:LockOwner Stype:'OR'Xdes:0x09621290 Mode: X SPID:59 BatchID:0 ECID:0 TaskProxy:(0x097F8378) Value:0x54ae760 Cost:(0/208)
2009-11-24 17:30:10.780 spid4s NULL
2009-11-24 17:30:10.780 spid4s Node:2
2009-11-24 17:30:10.780 spid4s KEY: 10:72057594054639616 (010086470766) CleanCnt:2 Mode:X Flags: 0x0
2009-11-24 17:30:10.780 spid4s Grant List 1:
2009-11-24 17:30:10.780 spid4s Owner:0x054AF040 Mode: X Flg:0x0 Ref:0 Life:02000000 SPID:59 ECID:0 XactLockInfo: 0x096212B4
2009-11-24 17:30:10.780 spid4s SPID: 59 ECID: 0 Statement Type: UPDATE Line #: 23
2009-11-24 17:30:10.780 spid4s Input Buf: Language Event:
-- Declare and set variable
-- to track number of retries
-- to try before exiting.
DECLARE @retry INT;
SET @retry = 2;
-- Keep trying to update
-- table if this task is
-- selected as the deadlock
-- victim.
WHILE (@retry > 0)
BEGIN
2009-11-24 17:30:10.780 spid4s Requested By:
2009-11-24 17:30:10.780 spid4s ResType:LockOwner Stype:'OR'Xdes:0x09621838 Mode: X SPID:55 BatchID:0 ECID:0 TaskProxy:(0x0983C378) Value:0x54adc40 Cost:(0/208)
2009-11-24 17:30:10.780 spid4s NULL
2009-11-24 17:30:10.780 spid4s Victim Resource Owner:
2009-11-24 17:30:10.780 spid4s ResType:LockOwner Stype:'OR'Xdes:0x09621838 Mode: X SPID:55 BatchID:0 ECID:0 TaskProxy:(0x0983C378) Value:0x54adc40 Cost:(0/208)
2009-11-24 17:30:10.780 spid15s deadlock-list
2009-11-24 17:30:10.780 spid15s deadlock victim=process2e58e38
2009-11-24 17:30:10.780 spid15s process-list
2009-11-24 17:30:10.780 spid15s process id=process2e58e38 taskpriority=0 logused=208 waitresource=KEY: 10:72057594054639616 (010086470766) waittime=3978 ownerId=347267 transactionname=user_transaction lasttranstarted=2009-11-24T17:30:03.803 XDES=0x9621838 lockMode=X schedulerid=2 kpid=9648 status=suspended spid=55 sbid=0 ecid=0 priority=0 transcount=2 lastbatchstarted=2009-11-24T17:30:03.783 lastbatchcompleted=2009-11-24T17:30:03.780 clientapp=Microsoft SQL Server Management Studio - 쿼리 hostname=최보라 hostpid=8252 loginname=sa isolationlevel=read committed (2) xactid=347267 currentdb=10 lockTimeout=4294967295 clientoption1=671090784 clientoption2=390200
2009-11-24 17:30:10.780 spid15s executionStack
2009-11-24 17:30:10.780 spid15s frame procname=adhoc line=24 stmtstart=38 sqlhandle=0x020000007245e338daab90ce8e17c9bb5e80187b4d642c14
2009-11-24 17:30:10.780 spid15s UPDATE [my_sales] set [sales] = [sales]+@1 WHERE [itemid]=@2
2009-11-24 17:30:10.780 spid15s frame procname=adhoc line=24 stmtstart=938 stmtend=1106 sqlhandle=0x020000002ac2d80354f3e91e11b6251c8c189c5d7eccce5d
2009-11-24 17:30:10.780 spid15s UPDATE my_sales
2009-11-24 17:30:10.780 spid15s SET sales = sales + 5
2009-11-24 17:30:10.780 spid15s WHERE itemid = 1;
2009-11-24 17:30:10.780 spid15s inputbuf
2009-11-24 17:30:10.780 spid15s -- Declare and set variable
2009-11-24 17:30:10.780 spid15s -- to track number of retries
2009-11-24 17:30:10.780 spid15s -- to try before exiting.
2009-11-24 17:30:10.780 spid15s DECLARE @retry INT;
2009-11-24 17:30:10.780 spid15s DECLARE @count INT;
2009-11-24 17:30:10.780 spid15s SET @retry = 2;
2009-11-24 17:30:10.780 spid15s SET @count = 1;
2009-11-24 17:30:10.780 spid15s --Keep trying to update
2009-11-24 17:30:10.780 spid15s -- table if this task is
2009-11-24 17:30:10.780 spid15s -- selected as the deadlock
2009-11-24 17:30:10.780 spid15s -- victim.
2009-11-24 17:30:10.780 spid15s WHILE (@retry > 0)
2009-11-24 17:30:10.780 spid15s BEGIN
2009-11-24 17:30:10.780 spid15s BEGIN TRY
2009-11-24 17:30:10.780 spid15s BEGIN TRANSACTION;
2009-11-24 17:30:10.780 spid15s UPDATE my_sales
2009-11-24 17:30:10.780 spid15s SET sales = sales + 5
2009-11-24 17:30:10.780 spid15s WHERE itemid = 2;
2009-11-24 17:30:10.780 spid15s WAITFOR DELAY '00:00:03';
2009-11-24 17:30:10.780 spid15s UPDATE my_sales
2009-11-24 17:30:10.780 spid15s SET sales = sales + 5
2009-11-24 17:30:10.780 spid15s WHERE itemid = 1;
2009-11-24 17:30:10.780 spid15s SET @retry = 0;
2009-11-24 17:30:10.780 spid15s COMMIT TRANSACTION;
2009-11-24 17:30:10.780 spid15s END TRY
2009-11-24 17:30:10.780 spid15s BEGIN CATCH
2009-11-24 17:30:10.780 spid15s -- Check error number.
2009-11-24 17:30:10.780 spid15s -- If deadlock victim error,
2009-11-24 17:30:10.780 spid15s -- then reduce retry count
2009-11-24 17:30:10.780 spid15s -- for next update retry.
2009-11-24 17:30:10.780 spid15s -- If some other error
2009-11-24 17:30:10.780 spid15s -- occurred, then exit
2009-11-24 17:30:10.780 spid15s -- retry WHILE loop.
2009-11-24 17:30:10.780 spid15s IF (ERROR_NUMBER() = 1205)
2009-11-24 17:30:10.780 spid15s BEGIN
2009-11-24 17:30:10.780 spid15s SET @retry = @retry - 1;
2009-11-24 17:30:10.780 spid15s SELECT @count as '[실행count]', ERROR_MESSAGE()
2009-11-24 17:30:10.780 spid15s process id=process2e58f28 taskpriority=0 logused=208 waitresource=KEY: 10:72057594054639616 (020068e8b274) ownerId=347255 transactionname=user_transaction lasttranstarted=2009-11-24T17:30:02.793 XDES=0x9621290 lockMode=X schedulerid=2 kpid=6876 status=suspended spid=59 sbid=0 ecid=0 priority=0 transcount=2 lastbatchstarted=2009-11-24T17:30:02.793 lastbatchcompleted=2009-11-24T17:30:02.793 clientapp=Microsoft SQL Server Management Studio - 쿼리 hostname=최보라 hostpid=8252 loginname=sa isolationlevel=read committed (2) xactid=347255 currentdb=10 lockTimeout=4294967295 clientoption1=671090784 clientoption2=390200
2009-11-24 17:30:10.780 spid15s executionStack
2009-11-24 17:30:10.780 spid15s frame procname=adhoc line=23 stmtstart=38 sqlhandle=0x020000007245e338daab90ce8e17c9bb5e80187b4d642c14
2009-11-24 17:30:10.780 spid15s UPDATE [my_sales] set [sales] = [sales]+@1 WHERE [itemid]=@2
2009-11-24 17:30:10.780 spid15s frame procname=adhoc line=23 stmtstart=868 stmtend=1036 sqlhandle=0x020000008a4537232ab1f574eb75390b8f81a691db149df4
2009-11-24 17:30:10.780 spid15s UPDATE my_sales
2009-11-24 17:30:10.780 spid15s SET sales = sales + 1
2009-11-24 17:30:10.780 spid15s WHERE itemid = 2;
2009-11-24 17:30:10.780 spid15s inputbuf
2009-11-24 17:30:10.780 spid15s -- Declare and set variable
2009-11-24 17:30:10.780 spid15s -- to track number of retries
2009-11-24 17:30:10.780 spid15s -- to try before exiting.
2009-11-24 17:30:10.780 spid15s DECLARE @retry INT;
2009-11-24 17:30:10.780 spid15s SET @retry = 2;
2009-11-24 17:30:10.780 spid15s -- Keep trying to update
2009-11-24 17:30:10.780 spid15s -- table if this task is
2009-11-24 17:30:10.780 spid15s -- selected as the deadlock
2009-11-24 17:30:10.780 spid15s -- victim.
2009-11-24 17:30:10.780 spid15s WHILE (@retry > 0)
2009-11-24 17:30:10.780 spid15s BEGIN
2009-11-24 17:30:10.780 spid15s BEGIN TRY
2009-11-24 17:30:10.780 spid15s BEGIN TRANSACTION;
2009-11-24 17:30:10.780 spid15s UPDATE my_sales
2009-11-24 17:30:10.780 spid15s SET sales = sales + 1
2009-11-24 17:30:10.780 spid15s WHERE itemid = 1;
2009-11-24 17:30:10.780 spid15s WAITFOR DELAY '00:00:8';
2009-11-24 17:30:10.780 spid15s UPDATE my_sales
2009-11-24 17:30:10.780 spid15s SET sales = sales + 1
2009-11-24 17:30:10.780 spid15s WHERE itemid = 2;
2009-11-24 17:30:10.780 spid15s SET @retry = 0;
2009-11-24 17:30:10.780 spid15s COMMIT TRANSACTION;
2009-11-24 17:30:10.780 spid15s END TRY
2009-11-24 17:30:10.780 spid15s BEGIN CATCH
2009-11-24 17:30:10.780 spid15s -- Check error number.
2009-11-24 17:30:10.780 spid15s -- If deadlock victim error,
2009-11-24 17:30:10.780 spid15s -- then reduce retry count
2009-11-24 17:30:10.780 spid15s -- for next update retry.
2009-11-24 17:30:10.780 spid15s -- If some other error
2009-11-24 17:30:10.780 spid15s -- occurred, then exit
2009-11-24 17:30:10.780 spid15s -- retry WHILE loop.
2009-11-24 17:30:10.780 spid15s IF (ERROR_NUMBER() = 1205)
2009-11-24 17:30:10.780 spid15s BEGIN
2009-11-24 17:30:10.780 spid15s SET @retry = @retry - 1;
2009-11-24 17:30:10.780 spid15s SELECT ERROR_MESSAGE()
2009-11-24 17:30:10.780 spid15s END
2009-11-24 17:30:10.780 spid15s ELSE
2009-11-24 17:30:10.780 spid15s SET @retry = -1;
2009-11-24 17:30:10.780 spid15s resource-list
2009-11-24 17:30:10.780 spid15s keylock hobtid=72057594054639616 dbid=10 objectname=AdventureWorks.dbo.my_sales indexname=PK__my_sales__7CA47C3F id=lock5446f00 mode=X associatedObjectId=72057594054639616
2009-11-24 17:30:10.780 spid15s owner-list
2009-11-24 17:30:10.780 spid15s owner id=process2e58f28 mode=X
2009-11-24 17:30:10.780 spid15s waiter-list
2009-11-24 17:30:10.780 spid15s waiter id=process2e58e38 mode=X requestType=wait
2009-11-24 17:30:10.780 spid15s keylock hobtid=72057594054639616 dbid=10 objectname=AdventureWorks.dbo.my_sales indexname=PK__my_sales__7CA47C3F id=lock5447340 mode=X associatedObjectId=72057594054639616
2009-11-24 17:30:10.780 spid15s owner-list
2009-11-24 17:30:10.780 spid15s owner id=process2e58e38 mode=X
2009-11-24 17:30:10.780 spid15s waiter-list
2009-11-24 17:30:10.780 spid15s waiter id=process2e58f28 mode=X requestType=wait
'Database Administrator > Peformance Tuning' 카테고리의 다른 글
| 성능::엑셀이용분석하기 (0) | 2010.06.03 |
|---|---|
| read-ahead는 무었인가? (0) | 2009.12.03 |
| 성능:: 강제 매개변수화 Forced Parameterization (0) | 2009.11.13 |
| SQL서버 성능counter (0) | 2009.11.12 |