잘린 200GB 테이블이지만 디스크 공간이 해제되지 않음


23

2GB 만 남았으므로이 기록 테이블을 제거해야합니다. 이 테이블은 이제 비어 있지만 데이터베이스 디스크 공간이 해제되지 않았습니다. 그리고 데이터베이스 파일은 320GB입니다.


데이터베이스에서 일부 복제 흔적을 찾았습니다. 이렇게하면 로그 크기가 크게 증가하고 삭제 또는 축소되지 않습니다.
— Lucas Rodrigues Sena

답변:


25

볼륨에서 실제 데이터베이스 파일 소비를 참조하는 경우 SQL Server는이를 자동으로 처리하지 않습니다 . 데이터베이스에서 데이터를 제거했다고해서 데이터베이스 파일이 기존 데이터에만 맞도록 축소되는 것은 아닙니다.

볼륨의 공간을 확보 해야 할 경우 찾고 있는 것은로 특정 파일을 축소합니다 DBCC SHRINKFILE. 해당 문서에 따라 몇 가지 모범 사례를 주목할 가치가 있습니다.

모범 사례

파일을 축소 할 때는 다음 정보를 고려하십시오.

  • 축소 작업은 자르기 테이블 또는 테이블 삭제 작업과 같이 사용하지 않는 공간을 많이 만드는 작업 후에 가장 효과적입니다.

  • 대부분의 데이터베이스는 일상적인 작업에 사용 가능한 여유 공간이 필요합니다. 데이터베이스를 반복적으로 축소하고 데이터베이스 크기가 다시 커지면 일반 작업에 줄어든 공간이 필요함을 나타냅니다. 이 경우 데이터베이스를 반복적으로 축소하는 것은 낭비되는 작업입니다.

  • 축소 작업은 데이터베이스에서 인덱스의 조각화 상태를 유지하지 않으며 일반적으로 조각화를 어느 정도 증가시킵니다. 이것이 데이터베이스를 반복적으로 축소하지 않는 또 다른 이유입니다.

  • 동일한 데이터베이스에서 여러 파일을 동시에 대신에 축소합니다. 시스템 테이블의 경합으로 인해 차단으로 인해 지연이 발생할 수 있습니다.

참고 사항 :

DBCC SHRINKFILE 프로세스의 어느 시점에서나 작업을 중지 할 수 있으며 완료된 작업이 유지됩니다.

이 작업을 수행 할 때 반드시 고려해야 할 사항이 몇 가지 있습니다. Paul Randal의 블로그 게시물 에서이 작업을 수행 할 때 발생 .

첫 번째 단계는 실제로 대체 할 수있는 공간과 여유 공간 및 파일의 사용 된 공간을 확인하는 것입니다.

use AdventureWorks2012;
go

;with db_file_cte as
(
    select
        name,
        type_desc,
        physical_name,
        size_mb = 
            convert(decimal(11, 2), size * 8.0 / 1024),
        space_used_mb = 
            convert(decimal(11, 2), fileproperty(name, 'spaceused') * 8.0 / 1024)
    from sys.database_files
)
select
    name,
    type_desc,
    physical_name,
    size_mb,
    space_used_mb,
    space_used_percent = 
        case size_mb
            when 0 then 0
            else convert(decimal(5, 2), space_used_mb / size_mb * 100)
        end
from db_file_cte;

6

이는 테이블을자를 때 발생하는 정상적인 동작이며 온라인 설명서 당 128 개가 넘는 익스텐트를 제거해야합니다.

큰 인덱스를 삭제 또는 재 구축하거나 큰 테이블을 삭제 또는 잘라 내면 데이터베이스 엔진은 트랜잭션이 커밋 될 때까지 실제 페이지 할당 해제 및 관련 잠금을 연기합니다. 이 구현은 다중 사용자 환경에서 자동 커밋 및 명시 적 트랜잭션을 모두 지원하며 128 개가 넘는 익스텐트를 사용하는 큰 테이블 및 인덱스에 적용됩니다.

데이터베이스 엔진은 프로세스를 논리적 및 물리적의 두 단계로 분리하여 큰 개체를 삭제하는 데 필요한 할당 잠금을 피합니다.

논리적 단계에서 테이블 또는 인덱스에 사용 된 기존 할당 단위는 할당 해제로 표시되고 트랜잭션이 커밋 될 때까지 잠 깁니다. 삭제 된 클러스터형 인덱스를 사용하면 데이터 행이 복사 된 다음 재 구축 된 클러스터형 인덱스 또는 힙에 저장소에 생성 된 새 할당 단위로 이동됩니다. (인덱스 재 빌드의 경우 데이터 행도 정렬됩니다.) 롤백이 있으면이 논리적 단계 만 롤백하면됩니다.

물리적 단계는 트랜잭션이 커밋 된 후에 발생합니다. 할당 취소로 표시된 할당 단위는 실제로 일괄 적으로 삭제됩니다. 이러한 하락은 백그라운드에서 발생하는 짧은 트랜잭션 내에서 처리되며 많은 잠금이 필요하지 않습니다.

트랜잭션이 커밋 된 후 물리적 단계가 발생하기 때문에 테이블 또는 인덱스의 스토리지 공간이 여전히 사용 불가능한 것으로 나타날 수 있습니다. 물리적 단계가 완료되기 전에 데이터베이스가 커지려면이 공간이 필요한 경우 데이터베이스 엔진은 할당 해제로 표시된 할당 단위에서 공간을 복구하려고합니다. 이러한 할당 단위에서 현재 사용중인 공간을 찾으려면 sys.allocation_units 카탈로그 뷰를 사용하십시오.

지연된 삭제 작업은 할당 된 공간을 즉시 해제하지 않으며 데이터베이스 엔진에 추가 오버 헤드 비용을 발생시킵니다. 따라서 128 개 이하의 익스텐트를 사용하는 테이블과 인덱스는 SQL Server 2000에서와 같이 삭제, 절단 및 재 구축됩니다. 이는 트랜잭션이 커밋되기 전에 논리적 및 물리적 단계가 모두 발생 함을 의미합니다.

기다려야 할 것입니다. 물론 수동으로해야합니다. 공간을 확보하기 위해 파일 축소 해야합니다. 축소와 조각화 사이의 균형을 유지해야합니다. 데이터가 다시 커질 시나리오를 고려하여 축소가 실제로 문제를 해결할 수 있는지 여부를 스스로 확인하는 것이 좋습니다.

아래 쿼리를 사용하여 데이터베이스에 여유 공간이 얼마나 있는지 확인하십시오.

SELECT name ,size/128.0 - CAST(FILEPROPERTY(name, 'SpaceUsed') AS int)/128.0 AS AvailableSpaceInMB
FROM sys.database_files;

6

Tom 및 Shanky의 답변 외에도 데이터베이스에 LOB / BLOB 데이터가 포함 된 경우 DBCC SHRINKFILE이 작동하지 않을 수 있습니다. 이 경우 데이터베이스를 오프라인으로 전환 할 수 있는지 여부에 따라 두 가지 옵션이 있습니다. 데이터베이스를 오프라인으로 전환 할 수 있으면 빈 공간을 제거하기 위해 데이터를 복사 한 후 다시 복사해야합니다. 다음 중 하나를 수행하여이를 수행 할 수 있습니다.

  1. SELECT INTO 문을 사용 하여 전체 테이블을 새 테이블로 전송하십시오. 원래 테이블을 삭제하고 DBCC SHRINKFILE을 실행하십시오. . 새 테이블의 이름을 원래 테이블 이름으로 바꾸십시오.
  2. bcp를 사용하여 기본 모드에서 테이블을 복사하고 테이블을 삭제하고 DBCC SHRINKFILE을 실행하십시오. 작성한 다음 테이블에 데이터를 bcp하십시오.
  3. 내보내기 / 가져 오기 를 사용하여 모든 데이터를 새 데이터베이스로 이동하고 기존 데이터베이스를 삭제하고 새 데이터베이스의 이름을 원래 데이터베이스 이름으로 바꿉니다.

데이터베이스를 오프라인으로 만들 수 없으면 EMPTYFILE 과 함께 DBCC SHRINKFILE 명령을 사용할 수 있습니다 옵션 .

오프라인 사본에 대한 세부 사항 : http://support.microsoft.com/kb/324432/en-us

EMPTYFILE 옵션 http://msdn.microsoft.com/en-us/library/ms189493(v=sql.105).aspx에 대한 최신 정보

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