재현
- 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
이 양호하다는 초기 결정을 내린 경우에 충분했을 것입니다.