Mdf ve ldf boş alan veritabanı boş alan ile eşleşmiyor


9

SSMS'de dosya boyutuyla ilgili özellikleri gördüm ve bir veritabanı için aşağıdaki ayrıntıları buldum. Burada değerler diğer özelliklerle eşleşmiyor. Burada mdf, ldf ve total size her pencerenin altındaki diğer değerlerle eşleşir. Ancak mdf ve ldf kullanılabilir boş alan eklenirse, shrink veritabanı penceresinde gösterilen kullanılabilir boş alan ve veritabanı özelliklerinde gösterilen boş alan ile eşit değildir. Bu herhangi bir veritabanı için geçerlidir. Neden böyle? Lütfen kimse bunun arkasındaki mantığı açıklayabilir mi?

Veritabanı özellikleri altında:

Boyut: 91.31 MB
Mevcut alan: 13.40 MB

Veritabanı dosyası özellikleri altında:

mdf boyutu: 17 MB
ldf boyutu: 75 MB

shrink veritabanı altında:

Şu anda tahsis edilen boyut: 91.31 MB
Mevcut boş alan: 13.40 MB

shrink dosyası altında-veri dosyası için:

şu anda ayrılan boyut: 16.38 MB
Mevcut boş alan: 12.63 MB

shrink dosyası altında-günlük dosyası için:

şu anda ayrılan boyut: 74.94 MB
Mevcut boş alan: 55.62 MB

Yanıtlar:


11

Bu gerçekten bu kadar çılgın görünmüyor, ancak bazı UI iletişim kutularının tamamen güncel bilgilere sahip olmayabileceğini unutmayın (bu yüzden DBCC GÜNCELLEME gibi şeylere sahibiz ) ve yuvarlama da bunlardan bazılarında yer alabilir hesaplamaları. Son olarak, iletişim kutuları size tüm veritabanının toplam alanını gösterir , ancak ayrılmamış alan yalnızca veri dosyaları için hesaplanır , günlük için hesaplanmaz .

Bazı şeyleri birleştirelim.

  1. Veritabanı özellikleri ve shrink veritabanı aynı şeyi gösterir (yine de shrink veritabanı arayüzünde olmanız gerekmez!).
  2. Veritabanı dosyası özellikleri, eklemeden önce yuvarlama ile muhtemelen 1'de 91.31 olan 17 + 75 = 92 değerini gösterir.
  3. Ayrılan alan için, tek tek dosyalar için shrink 16.38 + 74.94 = 91.32'yi gösterir - yine, muhtemelen orada yuvarlama, aksi takdirde tam olarak eşleşen 1.
  4. Kullanılabilir alan için, tek tek dosyalar için küçült, gerçek bir tutarsızlıktan şüphelendiğim tek yer ve bunun nedeni kullanıcı arayüzünün verilerini nereden aldığı konusunda tutarsız olması ve bu yerlerin bazılarının DBCC GÜNCELLEMESİ gerektiren önbelleğe alınmasıdır.

Bu farklı diyalogların AdventureWorks2012 yerel kopyam için ne çalıştırdığına bir bakayım (bazı tablolar bu komut dosyasından büyütülmüş olarak ).

EXEC sp_spaceused;

Bu döndürür (yalnızca ilk sonuç kümesi):

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

Temel olarak, bu - izleme yoluyla onayladığım - kabaca veritabanı özellikleri ve veritabanı küçültme iletişim kutularından yürütülen aynı sorguyu çalıştırır (saklı yordamdan alakasız parçaları oydum ve matematik temsil etmek için bir dış sorgu ekledim SSMS'nin görüntüleme için yaptığı):

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;

Bu bir eşleşme döndürür:

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

Bu iletişim kutularının tümü bu bilgileri doğru bir şekilde gösterir. Veritabanı Özellikleri iletişim kutusu:

Veritabanı Özellikleri iletişim kutusu

Veritabanını Küçült iletişim kutusu:

Veritabanını Küçült iletişim kutusu

Shrink dosyası iletişim kutuları ise biraz farklı bir sorgu çalıştırır (yine bu kolaylık sağlamak için oyulmuştur / uyarlanmıştır):

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;

Ayrıca, DMV yerine bir işlevden boyut verileri almanın yanı sıra, tahminlerin filestream / hekaton gibi yeni dosya türleri için güncellenmediğini unutmayın.

Sonuçlar:

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

Sorun, FILEPROPERTY()güncel olması garanti edilmeyen işlevdir ( DBCC UPDATEUSAGE(0);çalıştırıldıktan sonra bile ; daha aşağıda). Bu, iletişim kutularındaki yanıltıcı bilgilerle sonuçlanır:

Yanlış alan okumaları

Yine, sadece toplam veritabanı boyutunu ölçtüğünden, 6.67 MB'nin hiçbir zaman gerçekten doğru olmadığını unutmayın; ayrılan sayfa sayısı, günlüğü tamamen göz ardı eder.

Dürüst olmak gerekirse, veritabanında kullanılan alanın doğru bir şekilde raporlanmasını istiyorsanız, bunu anlamak için her türlü farklı sorguyu çalıştıran mickey mouse kullanıcı arayüzlerini kullanmayı bırakın ve bilgi almak için shrink dosyası iletişim kutularını kullanmayı bırakın. Bunlar, bazı durumlarda açıkça eski veri sorunlarına tabidir. Güvenebileceğiniz bir kaynağa karşı gerçek bir sorgu çalıştırın. İşte tercih ettiğim şey:

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;

Bu sorgu, çok tanıdık görünmesi gereken üç sayı ve olmaması gereken bir sayı döndürür:

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

DBCC SQLPERF'nin , örneğin çalıştırdıktan sonra alan kullanımı ile ilgili sorunlara da eğilimli olduğunu unutmayın :

DBCC UPDATEUSAGE(0);

Yukarıdaki sorgu bunun yerine verir:

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

sp_spaceusedşimdi 1545.81 MB / 8.08 MByine de eşleşen sayıları verir ( ), yine de - bu sadece veri dosyalarında bulunan alan ve veritabanı özelliği ve veritabanı küçültme iletişim kutuları da "doğru" olsa da (küçültme dosya iletişim kutuları hala kapalı - FILEPROPERTY()hiç etkilenmiyor gibi görünüyor UPDATEUSAGE):

Güncelleme kullanımından sonra Veritabanı Özellikleri iletişim kutusu

Güncelleme kullanımından sonra veritabanı küçültme iletişim kutusu

Güncelleme kullanımından sonra veri dosyası küçültme iletişim kutusu

Güncelleme kullanımından sonra günlük dosyası küçültme iletişim kutusu

Oh, ve aynı zamanda Windows Gezgini'nin bu dosyalar hakkında ne düşündüğünü gösterebilir, böylece MB'yi belirlemek için yapılan hesaplamalar ile ilgili olabilir:

Windows'ta dosya boyutları

Tüm bunların ne kadar doğru olması gerektiği elbette bilgilerle ne yapacağınıza bağlıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.