오늘 저는 데이터베이스를 저장하는 하드 드라이브가 가득 찼음을 발견했습니다. 이것은 전에 일어 났으며, 일반적으로 원인이 분명합니다. 일반적으로 쿼리가 잘못되어 tempdb에 대량 유출이 발생하여 디스크가 가득 찰 때까지 커집니다. 이번에는 tempdb가 전체 드라이브의 원인이 아니기 때문에 데이터베이스 자체였습니다.
사실 :
- 일반적인 데이터베이스 크기는 약 55GB이며 605GB로 증가했습니다.
- 로그 파일의 크기가 정상이고 데이터 파일이 큽니다.
- 데이터 파일의 사용 가능한 공간은 85 %입니다 (이를 '공기': 해석되었지만 사용 된 공간으로 해석합니다. SQL Server는 할당 된 모든 공간을 예약합니다).
- Tempdb 크기는 정상입니다.
가능한 원인을 찾았습니다. 너무 많은 행을 선택하는 쿼리가 하나 있습니다 (잘못된 조인은 수십만이 예상되는 110 억 개의 행을 선택합니다). 이것은 SELECT INTO
쿼리이므로 다음 시나리오가 발생할 수 있는지 궁금합니다.
- SELECT INTO가 실행됩니다
- 대상 테이블이 생성됩니다
- 선택된 데이터가 삽입됩니다
- 디스크가 가득 차서 삽입 실패
- SELECT INTO가 중단되고 롤백됩니다.
- 롤백은 여유 공간을 비우고 (이미 삽입 된 데이터는 제거됨) SQL Server는 빈 공간을 해제하지 않습니다.
그러나이 상황에서는에 의해 생성 된 테이블 SELECT INTO
이 여전히 존재할 것으로 기대하지 않았으므로 롤백으로 삭제해야합니다. 나는 이것을 테스트했다 :
BEGIN TRANSACTION
SELECT T.x
INTO TMP.test
FROM (VALUES(1))T(x)
ROLLBACK
SELECT *
FROM TMP.test
결과 :
(1 row affected)
Msg 208, Level 16, State 1, Line 8
Invalid object name 'TMP.test'.
그러나 목표 테이블이 존재합니다. 실제 쿼리는 명시 적 트랜잭션에서 실행되지 않았지만 대상 테이블의 존재를 설명 할 수 있습니까?
여기에 스케치 한 가정이 정확합니까? 이 시나리오가 발생했을 가능성이 있습니까?