재현
- SSMS를여십시오
새 쿼리 창에 다음을 입력하십시오
use <YourDatabase>;
go
- 객체 탐색기 (SSMS)로 이동하여 마우스 오른쪽 버튼으로 클릭
<YourDatabase>-> Tasks->Take Offline
두 번째 새 쿼리 창을 열고 다음을 입력하십시오.
use <YourDatabase>;
go
다음과 같은 메시지가 나타납니다.
메시지 952, 수준 16, 상태 1, 줄 1
데이터베이스 'TestDb1'이 전환 중입니다. 나중에 진술을 시도하십시오.
이런 일이 발생하는 이유는 아래의 것과 유사한 진단 쿼리에서 찾을 수 있습니다.
select
l.resource_type,
l.request_mode,
l.request_status,
l.request_session_id,
r.command,
r.status,
r.blocking_session_id,
r.wait_type,
r.wait_time,
r.wait_resource,
request_sql_text = st.text,
s.program_name,
most_recent_sql_text = stc.text
from sys.dm_tran_locks l
left join sys.dm_exec_requests r
on l.request_session_id = r.session_id
left join sys.dm_exec_sessions s
on l.request_session_id = s.session_id
left join sys.dm_exec_connections c
on s.session_id = c.session_id
outer apply sys.dm_exec_sql_text(r.sql_handle) st
outer apply sys.dm_exec_sql_text(c.most_recent_sql_handle) stc
where l.resource_database_id = db_id('<YourDatabase>')
order by request_session_id;
가치있는 것을 위해이 오류를 재현하기 위해 객체 탐색기가 필요하지 않습니다. 동일한 작업을 시도하는 차단 된 요청이 필요합니다 (이 경우 데이터베이스를 오프라인으로 전환). T-SQL의 세 단계에 대해서는 아래 스크린 샷을 참조하십시오.

가장 가능성이 높은 것은 Object Explorer 세션이 다른 세션 (으로 표시됨)에 의해 차단 된 것 blocking_session_id입니다. 해당 오브젝트 탐색기 세션이 X데이터베이스에서 독점 잠금 ( ) 을 얻으려고 합니다. 위의 재현의 경우, Object Explorer 세션에 업데이트 잠금 ( U) 이 부여 되고 독점 잠금 ( X) 으로 변환하려고 시도했습니다 . LCK_M_X첫 번째 쿼리 창 ( 데이터베이스에서 use <YourDatabase>공유 잠금 ( S)을 가져옴) 으로 표시된 세션에 의해 차단 된 wait_type이입니다 .
그런 다음이 오류는 다른 세션에서 잠금을 시도하여 발생 했으며이 오류 메시지로 인해 세션이 거부되어 다른 상태 (이 경우 온라인 상태)로 전환하려는 데이터베이스에 액세스 할 수 없습니다 오프라인 전환으로).
다음에 무엇을해야합니까?
첫째로, 당황하지 않는 및 데이터베이스를 놓기 시작되지 않습니다 . 현재 보고있는 이유를 확인 하려면 문제 해결 방법 (위와 유사한 진단 쿼리 사용)을 수행 해야합니다. 이와 같은 메시지가 나타나거나 무언가가 "멈춤"으로 나타나면 동시성 부족을 자동으로 가정하고 블로킹을 시작하십시오 ( sys.dm_tran_locks좋은 시작입니다).
부수적으로, 나는 당신이 임의의 행동을 취하기 전에 문제의 근원을 알아내는 것이 최선이라고 믿는다. 이 작업뿐만 아니라 예상치 못한 모든 동작에 적용됩니다. 실제로 문제의 원인을 알면 실제로 큰 문제가 아니 었습니다. 기본적으로 블로킹 체인이 있었고 부모 블로커는 방금 발행했을 가능성이 높 KILL거나 세션 요청이 원하지 않는 KILL경우 완료 될 때까지 기다릴 수 있습니다. 어느 쪽이든, 특정 시나리오 (롤백 또는 커밋 대기)가 주어지면 옳고 신중한 결정을 내릴 수있는 지식이 있어야합니다.
주목할만한 또 다른 점은 이것이 GUI 대신 항상 T-SQL 대안을 선택하는 이유 중 하나입니다. T-SQL로 실행중인 작업과 SQL Server가 수행중인 작업을 정확히 알고 있습니다. 결국, 명시 적 명령을 발행했습니다. GUI를 사용하면 실제 T-SQL은 추상화가됩니다. 이 경우 차단 된 개체 탐색기가 데이터베이스를 오프라인 상태로 만들려는 시도를 살펴 보았습니다 ALTER DATABASE <YourDatabase> SET OFFLINE. 롤백 시도가 없었기 때문에 무기한 대기 중이었습니다. 귀하의 경우, 해당 데이터베이스에서 잠금이있는 세션을 롤백하려면 롤백 ALTER DATABASE ... SET OFFLINE WITH ROLLBACK IMMEDIATE이 양호하다는 초기 결정을 내린 경우에 충분했을 것입니다.