mdf 및 ldf의 여유 공간이 데이터베이스 여유 공간과 일치하지 않습니다 속성과 일치하지 않습니다. 여기서 mdf, ldf

SSMS에서 파일 크기 관련 속성을보고 하나의 데이터베이스에 대한 아래 세부 정보를 찾았습니다. 여기서 값은 다른 속성과 일치하지 않습니다. 여기서 mdf, ldf 및 total size의 크기는 각 창 아래의 다른 값과 일치합니다. 그러나 mdf 및 ldf의 사용 가능한 여유 공간이 추가되면 데이터베이스 축소 창에 표시된 사용 가능한 여유 공간 및 데이터베이스 특성에 표시된 사용 가능한 공간과 같지 않습니다. 이것은 모든 데이터베이스에 해당됩니다. 왜 그래야만하지? 누구든지 이것의 논리를 설명 할 수 있습니까?

데이터베이스 속성에서 :

크기 : 91.31 MB

사용 가능 공간 : 13.40 MB

데이터베이스 파일 속성에서 :

mdf 크기 : 17MB

ldf 크기 : 75MB

데이터베이스 축소 :

현재 할당 된 크기 : 91.31 MB

사용 가능한 여유 공간 : 13.40 MB

축소 파일-데이터 파일 :

현재 할당 된 크기 : 16.38MB

사용 가능한 여유 공간 : 12.63 MB

로그 파일 축소 파일에서 :

현재 할당 된 크기 : 74.94 MB

사용 가능한 여유 공간 : 55.62 MB



답변

이것은 실제로 미친 것처럼 보이지는 않지만 일부 UI 대화 상자에는 완전히 최신 정보가 없을 수 있으므로 ( DBCC UPDATEUSAGE 와 같은 것들이 있기 때문에 ) 반올림도 일부에 포함될 수 있습니다. 계산. 마지막으로 대화 상자에 전체 데이터베이스의 총 공간이 표시 되지만 할당되지 않은 공간은 로그가 아닌 데이터 파일에 대해서만 계산됩니다 .

몇 가지를 통합합시다.

  1. 데이터베이스 속성과 축소 데이터베이스는 같은 것을 보여줍니다 (어쨌든 축소 데이터베이스 UI에 있지 않아야 함).
  2. 데이터베이스 파일 속성은 17 + 75 = 92를 보여줍니다. 추가하기 전에 반올림하면 1의 91.31과 같습니다.
  3. 할당 된 공간의 경우 개별 파일의 축소는 16.38 + 74.94 = 91.32를 나타냅니다. 다시 반올림하거나 그렇지 않으면 1과 정확히 일치합니다.
  4. 사용 가능한 공간의 경우 개별 파일의 축소가 실제 불일치를 의심하는 유일한 장소이며, UI가 데이터를 가져 오는 위치가 일치하지 않고 일부 장소는 캐싱이 적용되어 DBCC UPDATEUSAGE가 필요하기 때문입니다.

로컬 AdventureWorks2012 사본 ( 이 스크립트 에서 특정 테이블이 확대됨)에 대해 서로 다른 대화 상자가 어떻게 실행되는지 살펴 보겠습니다 .

EXEC sp_spaceused;

결과를 반환합니다 (첫 번째 결과 집합 만 해당).

database_size    unallocated space
-------------    -----------------
   1545.81 MB          6.67 MB

추적을 통해 확인한 기본적으로이를 실행합니다. 이는 데이터베이스 속성 및 데이터베이스 축소 대화 상자에서 실행되는 것과 거의 동일한 쿼리입니다. SSMS가 표시하기 위해 수행하는 작업) :

SELECT database_size = DbSize*8.0/1024 + LogSize*8.0/1024,
  [unallocated space] = (DbSize-SpaceUsed)*8.0/1024
FROM
(
  SELECT
    (SELECT SUM(CAST(df.size as float)) FROM sys.database_files AS df
       WHERE df.type in ( 0, 2, 4 ) ) AS [DbSize],
    SUM(a.total_pages) AS [SpaceUsed],
    (SELECT SUM(CAST(df.size as float)) FROM sys.database_files AS df
       WHERE df.type in (1, 3)) AS [LogSize]
  FROM sys.partitions p
    join sys.allocation_units a on p.partition_id = a.container_id
    left join sys.internal_tables it on p.object_id = it.object_id
) AS x;

일치하는 결과를 반환합니다.

database_size    unallocated space
-------------    -----------------
    1545.8125             6.671875

이 대화 상자는 모두이 정보를 올바르게 표시합니다. 데이터베이스 속성 대화 상자 :

데이터베이스 속성 대화 상자

데이터베이스 축소 대화 상자 :

데이터베이스 축소 대화 상자

반면에 축소 파일 대화 상자는 약간 다른 쿼리를 실행합니다 (다시 편의를 위해 조각 / 적응 됨).

SELECT SUBSTRING(name, CHARINDEX('_',name)+1, 4),
  [Currently allocated space] = size/1024.0,
  [Available free space] = (Size-UsedSpace)/1024.0
FROM
(
  SELECT s.name,
    CAST(FILEPROPERTY(s.name, 'SpaceUsed') AS float)*CONVERT(float,8) AS [UsedSpace],
    s.size * CONVERT(float,8) AS [Size]
  FROM sys.database_files AS s
  WHERE (s.type IN (0,1))
) AS x;

또한 DMV 대신 함수에서 크기 데이터를 가져 오는 것 외에도 파일 스트림 / 헤 카톤과 같은 새 파일 유형에 대해 술어가 업데이트되지 않았습니다.

결과 :

        Currently allocated space    Available free space
----    -------------------------    --------------------
Data                         1517                  7.9375 -- wrong
Log                       28.8125               25.671875 -- wrong

문제는 FILEPROPERTY()기능이며 최신 상태를 보장하지는 않습니다 ( DBCC UPDATEUSAGE(0);실행 한 후에도 아래 내용 참조). 이것은 대화 상자에 대한 다음과 같은 잘못된 정보로 끝납니다.

사용 가능한 공간이 잘못되었습니다

다시 말하지만 6.67MB는 전체 데이터베이스 크기 (로그 할당을 완전히 무시하고 할당 된 페이지 수) 만 측정하기 때문에 실제로는 절대 정확하지 않았습니다.

정직하게 말해서, 데이터베이스에 사용 된 공간에 대한 정확한보고를 원한다면 모든 종류의 다른 쿼리를 실행하는 미키 마우스 UI 사용을 중지하고 정보를 찾기 위해 파일 축소 대화 상자 사용을 중지하십시오. 경우에 따라 오래된 데이터 문제가 발생할 수 있습니다. 신뢰할 수있는 소스에 대해 실제 쿼리를 실행하십시오. 내가 선호하는 것은 다음과 같습니다.

DECLARE @log_used DECIMAL(19,7);
CREATE TABLE #x(n SYSNAME, s DECIMAL(19,7), u DECIMAL(19,7), b BIT);
INSERT #x EXEC('DBCC SQLPERF(LogSpace);');
SELECT @log_used = u FROM #x WHERE n = DB_NAME();
DROP TABLE #x;

DECLARE @data_used DECIMAL(19,7);
SELECT @data_used = SUM(a.total_pages)*8/1024.0
FROM sys.partitions AS p
INNER JOIN sys.allocation_units AS a
ON p.[partition_id] = a.container_id;

;WITH x(t,s) AS
(
  SELECT [type] = CASE
    WHEN [type] IN (0,2,4) THEN 'data' ELSE 'log' END,
    size*8/1024.0 FROM sys.database_files AS f
)
SELECT
  file_type = t,
  size = s,
  available = s-CASE t WHEN 'data' THEN @data_used ELSE @log_used END
FROM x;

이 쿼리는 매우 친숙하게 보이는 숫자와 그렇지 않은 숫자를 반환합니다.

file_type    size           available
---------    -----------    ----------
data         1517.000000     6.6718750
log            28.812500    17.9008512

참고 DBCC SQLPERF가 실행 한 후, 예를 들어, 또한 공간 사용에 문제가 약간 경향이있다 :

DBCC UPDATEUSAGE(0);

위의 쿼리는 대신 이것을 산출합니다.

file_type    size           available
---------    -----------    ----------
data         1517.000000     8.0781250
log            28.812500    17.8669481

sp_spaceused지금뿐만 아니라 (일치하는 번호를 산출 1545.81 MB / 8.08 MB에서 사용할 수있는 유일한 공간입니다 – 다시 – 비록) 데이터 파일 (들), 데이터베이스 속성 및 데이터베이스 축소 대화 상자는 “정확한”물론이다 (그러나 파일 축소 대화 상자는 여전히 방법은 꺼져 있습니다- FILEPROPERTY()전혀 영향을받지 않는 것 같습니다 UPDATEUSAGE) :

업데이트 후 데이터베이스 속성 대화 상자

업데이트 사용 후 데이터베이스 축소 대화 상자

업데이트 후 데이터 파일 축소 대화 상자

업데이트 후 로그 파일 축소 대화 상자

아, 그리고 Windows 탐색기가 이러한 파일에 대해 어떻게 생각하는지 보여줄 수도 있으므로 MB를 계산하기 위해 수행 한 계산과 관련이 있습니다.

Windows의 파일 크기

물론이 모든 것이 얼마나 정확해야하는지는 정보로 무엇을 할 것인지에 달려 있습니다.


답변