잘린 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.