Sch-M WAIT는 SQL Server 2014에서 Sch-S를 차단하지만 SQL Server 2008 R2는 차단하지 않습니까?


11

우리는 최근 SQL 2008 R2의 프로덕션 인스턴스를 새로운 SQL 2014 서버로 마이그레이션했습니다. 다음은 Service Broker 사용에 대해 알아 낸 흥미로운 시나리오입니다. 와 데이터베이스 고려 Broker Enabled = trueMyServiceMyQueue. 이 큐에서 포이즌 메시지 처리가 사용 불가능합니다. 대기열에있는 메시지와 2 개 이상의 활성 대화가 있습니다.

한 프로세스 (SPID 100)에서 다음을 실행하십시오.

BEGIN TRANSACTION;
DECLARE @conversation_group_id UNIQUEIDENTIFIER;
RECEIVE TOP (1) @conversation_group_id = conversation_handle FROM MyQueue;

우리는 거래를 열린 채로 둡니다. 외부 리소스에서 오래 기다리는 .NET 프로그램이라고 상상해보십시오. 를 통해 sys.dm_tran_locks우리는이 SPID는 큐에 IX 잠금이 부여 된 것을 알 수 있습니다.

| type   | resource_id | mode | status | spid |
| OBJECT | 277576027   | IX   | GRANT  | 100  |

별도의 프로세스 (SPID 101)에서 다음을 다섯 번 실행하십시오 .

BEGIN TRANSACTION;
DECLARE @conversation_group_id UNIQUEIDENTIFIER;
RECEIVE TOP (1) @conversation_group_id = conversation_handle FROM MyQueue;
ROLLBACK TRANSACTION;

여기서 핵심은 트랜잭션을 5 번 롤백한다는 것 입니다. 내장 된 포이즌 메시지 처리 백그라운드 로직을 트리거합니다 . 대기열이 비활성화되지 않도록 구성되어 있지만 (비활성화되지 않도록 구성되어 있기 때문에) 백그라운드 작업이 여전히 작업을 수행하고 broker_queue_disabled이벤트를 시작 하려고합니다 . 이제 sys.dm_tran_locks다시 쿼리 BRKR TASK하면 Sch-M 잠금을 기다리는 다른 SPID (와 관련됨 )가 표시됩니다.

| type   | resource_id | mode  | status | spid |
| OBJECT | 277576027   | IX    | GRANT  | 100  |
| OBJECT | 277576027   | Sch-M | WAIT   | 36   |

지금까지 모든 것이 의미가 있습니다.

마지막으로 다른 프로세스 (SPID 102)에서 해당 큐를 사용하여 서비스로 전송을 시도하십시오.

BEGIN TRANSACTION;
DECLARE @ch uniqueidentifier;
BEGIN DIALOG @ch FROM SERVICE [MyService] TO SERVICE 'MyService';
SEND ON CONVERSATION @ch ('HELLO WORLD');

SEND명령이 차단됩니다. 다시 살펴보면 sys.dm_tran_locks이 프로세스가 Sch-S 잠금을 기다리고 있음 을 알 수 있습니다. 실행 sp_who2하면 SPID 102는 SPID 36에 의해 차단됩니다.

| type   | resource_id | mode  | status | spid |
| OBJECT | 277576027   | IX    | GRANT  | 100  |
| OBJECT | 277576027   | Sch-M | WAIT   | 36   |
| OBJECT | 277576027   | Sch-S | WAIT   | 102  |

Sch-S 잠금이 대기중인 Sch-M 잠금을 기다리는 이유는 무엇입니까?

이 동작은 SQL 2008 R2와 완전히 다릅니다! 아직 폐기되지 않은 2008R2 인스턴스에서 실행되는이 동일한 시나리오를 사용하면 SEND명령을 포함한 최종 배치 가 대기중인 Sch-M 잠금에 의해 차단 되지 않습니다 .

SQL 2012 또는 2014에서 잠금 동작이 변경 되었습니까? 이 잠금 동작에 영향을 줄 수있는 데이터베이스 또는 서버 설정이 있습니까?


가능한 버그 인 것 같습니다. 최신 SP 및 CU를 적용 했습니까?
Max Vernon

1
우리가 12.00.2370 실행중인 @MaxVernon
조셉 데이 글을

3
초 기자 및 대상과 동일한 서비스를 사용하고 있습니다. SEND블록은 확인하면서 개시 큐. 대상 대기열을 SEND차단하지 않고 단순히 반송하고 전달 하는 데 사용 합니다. 두 가지를 분리하면 (항상 좋은 생각) 문제가 없을 것입니다. sys.transmission_queue
Remus Rusanu

1
@RemusRusanu 감사합니다. 이 예제는 변경된 동작을 보여주기 위해 부분적으로 고안되었지만 팁은 서비스와 대기열을 디자인 할 때 염두에 두어야 할 팁입니다.
Joseph Daigle

답변:


17

이 동작은 SQL Server 2008 R2와 SQL Server 2012간에 변경되었습니다. 2008 R2 구현은 문서화 된 'relaxed FIFO'시맨틱 .

편안한 선입 선출 (FIFO) 방식으로 잠금이 부여됩니다. 순서가 엄격한 FIFO는 아니지만 기아를 피하는 등의 바람직한 속성을 유지하고 불필요한 교착 상태 및 차단을 줄이기 위해 작동합니다.

요청 된 모드가 승인 된 요청의 통합 및 보류중인 요청의 모드와 호환되지 않으면 요청자가 리소스에 대한 잠금을 아직 소유하지 않은 새 잠금 요청이 차단됩니다.

요청 된 모드가 변환 요청 자체가 원래 부여 된 모드를 제외한 모든 부여 된 모드의 통합과 호환되지 않는 경우에만 변환 요청이 차단됩니다.

2008 R2에서 새로운 Sch-S 승인 요청 및 대기 요청의 통합과 호환되지 않는 잠금 요청이 허용되어 잠금 기아 상태가 발생할 수 있습니다. 2012 년에는 Sch-S잠금 요청이 차단되었습니다.

아래의 재생 스크립트는 Service Broker 큐 대신 일반 테이블을 사용합니다.

-- Session 1
CREATE TABLE dbo.LockTest (col1 integer NULL);

INSERT dbo.LockTest (col1) VALUES (1);

BEGIN TRANSACTION;

-- Will hold row-X, Pag-IX, and Tab-IX
INSERT dbo.LockTest (col1) VALUES (2);

-- Session 2
-- Blocked waiting on Sch-M
TRUNCATE TABLE dbo.LockTest;

-- Session 3
-- Takes Sch-S only
-- Not blocked in 2008 R2
SELECT * FROM dbo.LockTest AS LT WITH (READUNCOMMITTED);

요약하면 2008 R2는 설계된대로 작동하지 않았습니다. 이 문제는 SQL Server 2012에서 수정되었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.