적용 대상: Microsoft Fabric의✅ Warehouse
웨어하우스의 쿼리를 실행하는 데 비정상적으로 오래 걸리거나 중단된 것처럼 보이는 경우 한 가지 가능한 원인은 잠금입니다. 잠금은 세션이 다른 쿼리를 진행하지 못하게 하는 잠금을 보유할 때 발생합니다.
이 문서에서는 잠금이 워크로드에 영향을 미치는지 여부와 수행할 수 있는 작업을 확인하는 방법을 보여 줍니다.
Tip
웨어하우스는 테이블 수준 잠금을 사용합니다. 모든 DML 작업은 영향을 받는 행 수에 관계없이 전체 테이블에 대한 잠금을 획득합니다. 이 동작은 행 수준 및 페이지 수준 잠금을 지원하는 SQL Server 다릅니다.
사전 요구 사항
- 활성 워크로드가 있는 웨어하우스입니다.
- 뷰어 작업 영역 역할의 멤버 자격은 이 문서의 DMV(동적 관리 뷰)를 쿼리할 수 있는 최소 권한입니다.
- DMV 문제 해결에 대한 자세한 내용은 DMV를 사용하여 연결, 세션 및 요청 모니터링을 참조하세요.
1단계: 쿼리가 잠금을 기다리고 있는지 확인
먼저 쿼리가 현재 잠금을 기다리고 있는지 확인합니다.
다음 쿼리를 실행합니다.
SELECT
request_session_id,
resource_type,
resource_description,
request_mode,
request_status
FROM sys.dm_tran_locks
WHERE request_status = 'WAIT';
쿼리가 행을 반환하는 경우 일부 세션은 다른 세션에서 보유한 리소스를 기다리고 있습니다. 각 행은 현재 부여할 수 없는 잠금 요청을 나타냅니다.
Tip
sys.dm_tran_locks 보기는 부여된 잠금에 대한 많은 수의 행을 반환할 수 있습니다. 필터링 기준 request_status = 'WAIT' 은 차단된 세션에 중점을 둡니다.
2단계: 차단된 쿼리 식별
다음으로 차단된 쿼리와 차단되는 세션을 확인합니다.
SELECT
session_id,
status,
blocking_session_id,
wait_type,
total_elapsed_time,
open_transaction_count
FROM sys.dm_exec_requests
WHERE blocking_session_id <> 0;
이 쿼리는 다음을 반환합니다.
- 차단된 쿼리를 실행하는 세션(
session_id) - 현재 차단 중인 세션(
blocking_session_id) - 대기한 시간(
total_elapsed_time밀리초) - 차단 세션에 열린 트랜잭션이 있는지 여부(
open_transaction_count)
쿼리에 blocking_session_id가 0이 아니고 open_transaction_count > 0인 것으로 표시되면, 잠금을 보유한 다른 세션을 기다리고 있는 것입니다.
3단계: 차단 세션 찾기
잠긴 리소스를 이해하려면 차단 세션에서 현재 보유하고 있는 잠금을 검사합니다. 다음 샘플 쿼리에서 <blocking_session_id>를 이전에 식별한 session_id로 대체합니다.
SELECT
request_session_id,
resource_type,
resource_associated_entity_id,
request_mode,
request_status
FROM sys.dm_tran_locks
WHERE
request_status = 'GRANT'
AND request_session_id = <blocking_session_id>;
이 쿼리를 사용하여 다음을 확인합니다.
- 차단 세션이 현재 잠금을 보유하고 있는 리소스입니다. 예를 들어
sys.objects를 사용하여resource_type = OBJECT이 있는resource_associated_entity_id를 식별할 수 있습니다. - 잠금 모드(예: 배타적(
X), Schema-Modification(Sch-M)) - 잠금이 DDL 작업 또는 통계 업데이트와 관련이 있는지 여부(
UPDSTATS)
메모
통계 관련 잠금(예: UPDSTATS에서 발생한 잠금)도 sys.dm_tran_locks에도 표시됩니다. Schema-Modification(Sch-M) 및 배타적(X) 잠금은 가장 일반적인 차단기이지만 모든 잠금 형식은 충돌하는 요청(예: Sch-S 블록 Sch-M)을 차단할 수 있습니다.
4단계: 차단 트랜잭션 소유자 찾기
대부분의 경우 세션을 종료하는 대신 차단 트랜잭션의 소유자에게 COMMIT 요청하거나 ROLLBACK 해당 작업을 요청하는 것을 선호할 수 있습니다.
COMMIT 또는 ROLLBACK를 사용하는 오류 처리에는 TRYCATCH 구조를 사용하는 것을 고려하세요. 자세한 내용은 TRY...CATCH를 참조하세요.
차단 세션과 연결된 소유자 및 쿼리를 식별할 수 있습니다. 앞서 식별한 session_id로 다음 샘플 쿼리의 <blocking_session_id>를 대체합니다.
SELECT
r.session_id,
s.login_name,
s.program_name,
r.status,
r.blocking_session_id,
r.command,
r.total_elapsed_time,
s.last_request_start_time,
s.last_request_end_time
FROM sys.dm_exec_requests r
JOIN sys.dm_exec_sessions s
ON r.session_id = s.session_id
WHERE r.session_id = <blocking_session_id>;
-
login_name는 차단 세션의 소유자입니다. -
program_name는 세션을 시작한 애플리케이션입니다. 이 값은DMS_userFabric 포털 쿼리 편집기를 나타냅니다. -
command는 현재 실행 중인 명령입니다.
그런 다음 적절한 경우 트랜잭션 소유자에게 문의하여 커밋하거나 롤백할 수 있습니다.
5단계: 블로킹 세션이 유휴 상태이거나 진행되지 않는 상태인지 확인
차단 세션이 활성 상태로 나타날 수 있지만 실제로는 진행되지 않습니다.
유휴 또는 중단된 세션의 지표는 다음과 같습니다.
-
status = 'sleeping'은 활성 쿼리가 실행되고 있지 않음을 나타냅니다. - 오랫동안 열려 있는 요청을 의미하는, 현재 시각보다 훨씬 이른
last_request_start_time을 찾으세요. - 점검 간에 증가하지 않는
total_elapsed_time를 찾아 세션이 정체되었음을 확인합니다.
SELECT
session_id,
status,
last_request_start_time,
last_request_end_time,
open_transaction_count
FROM sys.dm_exec_sessions
WHERE session_id = <blocking_session_id>;
- 세션 상태가
sleeping고open_transaction_count > 0세션에 활성 쿼리가 없는 열린 트랜잭션이 있는 경우 작업을 수행하지 않고 잠금을 유지합니다. - 세션이
sys.dm_exec_requests에 표시되고total_elapsed_time가 점검할 때마다 계속 증가하면 해당 세션은 현재 진행 중인 상태입니다. 트랜잭션을 종료하고 롤백을 강제하는 대신 트랜잭션이 완료될 때까지 기다리는 것이 좋습니다.
6단계: 차단을 해결하기 위한 작업 수행
메모
차단 세션이 트랜잭션을 완료하면 차단 상황은 자체적으로 해결되는 경우가 많습니다. 워크로드가 지연을 허용할 수 있는 경우 대기가 가장 안전한 옵션입니다.
다운스트림 쿼리의 차단을 해제해야 하는 경우 차단 세션에 다음과 같은 특성이 있는지 고려합니다.
- 열려 있는 트랜잭션이 있습니다.
- 유휴 상태로 표시되거나 진행되지 않음
- 차단 잠금(예: 배타적(
X) 또는Sch-M)을 보유하고 있습니다.
이 경우 관리자 작업 영역 역할의 멤버는 다음을 사용하여 세션을 종료할 수 있습니다.
KILL <session_id>;
KILL 명령은 다음과 같습니다:
- 세션 종료
- 해당 세션의 활성 트랜잭션에서 수행된 모든 작업 롤백
- 잠금 해제
- 다운스트림 쿼리를 계속 진행하도록 허용
Caution
세션을 종료하면 해당 세션에서 수행한 커밋되지 않은 모든 작업이 롤백됩니다. 이 작업은 사용자 또는 애플리케이션의 데이터 변경 내용을 실행 취소할 수 있습니다. 트랜잭션을 종료해도 워크로드에 부정적인 영향을 주지 않는다고 확신하는 경우에만 이 옵션을 사용합니다.
7단계: 향후 잠금 문제 방지
유사한 문제를 방지하려면 다음을 수행합니다.
- 명시적 트랜잭션을 열어 둔 채로 두지 마세요(
BEGIN TRANSACTION에 대응하는COMMIT또는ROLLBACK가 없는 경우). - 트랜잭션을 짧게 유지합니다. 트랜잭션 내에서 필요한 작업만 수행합니다.
- 완료되면 항상
COMMIT또는ROLLBACK트랜잭션을 하세요. - 트래픽이 적은 기간 동안 DDL 작업(예:
ALTER TABLE)을 예약합니다.
다음을 사용하여 열린 트랜잭션을 사전에 모니터링합니다.
SELECT
session_id,
login_name,
open_transaction_count,
program_name,
status,
blocking_session_id,
last_request_start_time
FROM sys.dm_exec_sessions
WHERE open_transaction_count > 0;
정기적으로 열린 트랜잭션을 모니터링하고 적절한 경우 개입하면 차단 체인이 형성될 가능성을 줄이는 데 도움이 됩니다.