교착 상태 쿼리를 찾는 방법

Rupert Harwood -

트랜잭션 데이터베이스에서 교착 상태는 각각 고유의 트랜잭션 내에 있는 두 개의 프로세스가 두 행의 정보를 반대 순서로 업데이트하려 할 때 발생합니다. 예를 들어, 프로세스 B가 행 2를 업데이트하고 나서 행 1을 업데이트하려고 하는 동일 시간대에 프로세스 A가 행 1을 업데이트하고 나서 행 2를 업데이트 합니다. 프로세스 A는 프로세스 B가 완료될 때까지 행 2 업데이트를 완료할 수 없으나, 프로세스 B는 프로세스 A가 완료될 때까지 행 1 업데이트를 완료할 수 없습니다. 아무리 시간이 흘러도 이 상황은 그 자체로 해결되지 않으며 이 때문에 ClustrixDB는 두 트랜잭션 중 가장 젊은 트랜잭션을 종료합니다.

간단히 말해, 교착 상태는 동일한 데이터를 수정하는 둘 또는 그 이상의 동시 트랜잭션의 결과로 트랜잭션은 커밋하거나 중단되기를 서로 대기하고 있어 어느 것도 수행되지 않으므로 하나는 반드시 중단되어야 합니다.

교착 상태를 만드는 간단한 예.

설정

session1> create table foo (id int auto_increment primary key, v varchar);
session1> insert into foo values (1,1);
session1> insert into foo values (2,2);

교착 상태 발생

session1> begin;
session2> begin;
session1> update foo set v = v+1 where id = 1;
session2> update foo set v = v+1 where id = 2;
session1> update foo set v = v+1 where id = 2;

Session1은 이제 차단되어 session2가 커밋하거나 중단될 때까지 대기합니다. 

session2> update foo set v = v+1 where id = 1;

그러면 교착 상태 탐지기는 다른 하나의 트랜잭션을 유지하기 위해 트랜잭션 중 하나를 취소하기 때문에 두 트랜잭션 중 하나가 [Lock manager deadlock detected: ] 오류로 실패합니다,.

교착 상태는 일반적으로 애플리케이션 로직 문제를 나타냅니다. 개발자가 문제를 야기하는 애플리케이션 코드를 추적할 수 있게 하려면 전역 변수인 debug_deadlocks를 활성화한 다음 정확히 어떤 쿼리가 교착 상태가 되는지 확인하려면 clustrix.log를 확인합니다.

교착 상태가 문제를 야기하지 않는 경우에도 가능하면 경쟁의 원인을 제거하는 것이 가장 좋습니다. 아래는 시스템에서 교착 상태를 조사하는 방법입니다. 

교착 상태 조사

sql> set global debug_deadlocks=true;

 위 예제를 실행하여 교착 상태가 발생하면 clustrix.log에 다음 내용이 표시됩니다.

shell> /opt/clustrix/bin/clx cmd 'grep "^2016-03-15" /data/clustrix/log/clustrix.log' | grep "dbcore/deadlock_detect"
2016-03-15 21:48:34.165629 UTC alpo004.colo.sproutsys.com clxnode: INFO dbcore/deadlock_detect.ct:177 victimize(): survivor xid=:0x56ea2520913ac802 user=root@NULL sql="update foo set v = v+1 where id = 2"

2016-03-15 21:48:34.165629 UTC alpo004.colo.sproutsys.com clxnode: INFO dbcore/deadlock_detect.ct:177 victimize(): victim xid=:0x56ea25232f014802 user=root@NULL sql="update foo set v = v+1 where id = 1"
2016-03-15 21:48:34.165629 UTC alpo004.colo.sproutsys.com clxnode: INFO dbcore/deadlock_detect.ct:181 victimize(): Canceling trx 0x56ea25232f014802 in graph to preserve 0x56ea2520913ac802.

위 방법을 활용하면 교착 상태 쿼리 소스를 식별하는데 필요한 정보를 얻을 수 있습니다.

 

또 다른 질문이 있으십니까? 문의 등록

0 댓글

댓글을 남기려면 로그인하세요.
Zendesk 제공