Tüm Ürünler
Search
Belge Merkezi

ApsaraDB RDS:Insufficient space issues for RDS for SQL Server

Son Güncelleme:Oct 03, 2026

Bir RDS for SQL Server örneğinde depolama alanının tükenmesi, yazma işlemlerinin başarısız olmasına ve yedeklemelerin tamamlanamamasına neden olabilir. Bu konuda, hangi dosya türünün alan tükettiğinin nasıl belirleneceği ve depolama alanının nasıl geri kazanılacağı veya genişletileceği açıklanmaktadır.

Depolama alanı kavramlarını anlama

Sorun gidermeye başlamadan önce, alan sayılarının ne anlama geldiğini netleştirin:


Kavram


Tanım


Notlar


Kullanılan veri alanı


Veritabanı dosyalarında depolanan gerçek verilerin kapladığı alan


Ekleme işlemlerinde artar. Ayrılan alan korunduğu için silme işlemlerinde azalmayabilir.


Ayrılan veri alanı


Veritabanı kullanımı için biçimlendirilmiş ve ayrılmış dosya alanı


Otomatik olarak büyür. Küçültme işlemi çalıştırılmadıkça silme işlemlerinden sonra küçülmez.


Ayrılan ancak kullanılmayan veri alanı


Ayrılan alan ile kullanılan alan arasındaki fark


Veri dosyalarını küçülterek geri kazanabileceğiniz maksimum miktar.


Toplam dosya boyutu


Veri dosyalarının veya günlük dosyalarının diskteki boyutu


Konsol ölçümlerinde ve sys.master_files içinde gösterilir. Hem ayrılmış hem de ayrılmamış alanı içerir.

Önemli

Konsol ölçümleri ve çoğu izleme API'si, gerçek veri kullanımını değil dosya boyutunu (ayrılan) bildirir. Her iki değeri de aynı anda görmek için sys.dm_db_file_space_usage veya sys.master_files sorgulayın. Bu ayrım, küçültme işleminin anlamlı bir alan boşaltıp boşaltmayacağını belirler.

Alan kullanımını görüntüleme

Mevcut alan kullanımını kontrol etmek için aşağıdaki yöntemlerden herhangi birini kullanın:

  • Yöntem 1 — Temel Bilgiler sayfası: Yalnızca toplam mevcut alan kullanımını gösterir. Dosya türüne göre döküm veya geçmiş eğilimler sunulmaz.

    Basic Information

  • Yöntem 2 — İzleme ve Uyarılar > Standart İzleme: Disk alanını dosya türüne (veri, günlük, temp, diğer) göre ayrılmış olarak ve geçmiş eğilimlerle birlikte gösterir. Ölçüm tanımları için bkz. Standart izlemeyi görüntüleme.

    Monitoring and Alerts

  • Yöntem 3 — Otonomi Hizmetleri > Depolama Yönetimi: Veri ile günlük kullanımı, geçmiş eğilimler ve en çok alan kullanan veritabanları ve tablolar için alan tahsisi dahil olmak üzere ayrıntılı bir döküm sağlar. Daha fazla bilgi için bkz. Alan Yönetimi.

    Depolama Yönetimi, cloud disklerle çalışan SQL Server 2008 R2 örnekleri için kullanılamaz.

    Storage Management

  • Yöntem 4 — SQL Server Management Studio (SSMS) veya başka bir istemci aracı: Örnek doğrudan bağlanın ve T-SQL sorgularını çalıştırın. Bağlantı talimatları için bkz. SSMS istemcisi kullanarak bir RDS for SQL Server örneğine bağlanma.

Alan kullanımını incelemek için yaygın olarak kullanılan aşağıdaki T-SQL komutlarını kullanabilirsiniz:


Komut veya görünüm


Gösterdiği bilgiler


sp_helpdb


Her veritabanı için toplam boyut (veri dosyaları + günlük dosyaları)


sp_spaceused


Mevcut veritabanı için ad, kullanılan alan ve ayrılmamış alan


DBCC SQLPERF(LOGSPACE)


Her veritabanı için toplam günlük dosyası boyutu ve kullanılan günlük alanı


DBCC SHOWFILESTATS


Mevcut veritabanındaki tüm veri dosyaları için toplam ve kullanılan veri alanı


SELECT * FROM sys.master_files


Her veritabanı için veri ve günlük dosyası boyutları


SELECT * FROM sys.dm_db_log_space_usage


Mevcut veritabanı için toplam ve kullanılan günlük alanı. Yalnızca SQL Server 2012 ve sonraki sürümler.


SELECT * FROM sys.dm_db_file_space_usage


Mevcut veritabanı için toplam ve kullanılan veri dosyası alanı. Yalnızca SQL Server 2012 ve sonraki sürümler.

Alan kullanımı yüksekse, RDS konsolu içindeki Monitoring and Alerts bölümüne gidin ve hangi dosya türünün (veri, günlük, temp veya diğer) en hızlı büyüdüğünü kontrol edin. Ardından aşağıdaki ilgili bölümleri izleyin.

Veri alanını geri kazanma

Neden analizi

tempdb veritabanı, SQL Server'da geçici verileri depolayan bir sistem veritabanıdır. tempdb içindeki veri dosyası alanı, aşağıdakiler gibi birçok senaryoda sıklıkla kullanılır:

  • Kullanıcı nesneleri: Kullanıcılar tarafından oluşturulan geçici tablolar.

  • Dahili nesneler: SQL Server tarafından dahili olarak oluşturulan geçici tablolar.

  • Sürüm deposu: Bir veritabanı için anlık görüntü izolasyonu veya read committed snapshot etkinleştirildiğinde, sürüm oluşturma bilgileri tempdb içinde depolanır.

Uzun süren işlemler, çok sayıda geçici tablo oluşturulması veya anlık görüntü izolasyonu gibi belirli işlemler büyük miktarda alan kullanırsa veri dosyası şişebilir. Bu durum, dosya boyutunun normal aralığının çok ötesine büyümesi anlamına gelir. Daha fazla bilgi için bkz. tempdb veritabanı için resmi Microsoft öğreticisi.

Çözümler

Bir RDS for SQL Server veritabanı veri dosyaları ve günlük dosyaları içerir. Her biri için alanı geri kazanma yöntemleri aşağıdaki gibidir:

Veri dosyası alanını geri kazanma

tempdb için veri dosyası alanı büyük ölçüde büyürse, SHRINKFILE komutunu kullanarak bunu küçültmek pek etkili olmaz. Bunun yerine, resmi Microsoft öğreticisinde (tempdb veritabanını küçültme) açıklandığı gibi, yoğun olmayan saatlerde örneği yeniden başlatarak tempdb alanını serbest bırakabilirsiniz.

tempdb veri dosyalarının alan kullanımını analiz etmek için aşağıdaki çözümleri kullanabilirsiniz:

Senaryo 1: tempdb veri dosyası alanı büyük

  1. Büyük miktarda tempdb veri dosyası alanı kullanılıyorsa, farklı nesne türleri (User Objects, Internal Objects ve Version Store) tarafından kullanılan tempdb alanını kontrol etmek için sys.dm_db_file_space_usage sistem görünümünü kullanarak aşağıdaki SQL ifadesini çalıştırın:

    sys.dm_db_file_space_usage kullanımı hakkında daha fazla bilgi için bkz. resmi Microsoft öğreticisi.

    SELECT 
        SUM(version_store_reserved_page_count) AS [version store pages used], 
        (SUM(version_store_reserved_page_count) * 1.0 / 128) AS [version store object space in MB], 
        SUM(user_object_reserved_page_count) AS [user object pages used], 
        (SUM(user_object_reserved_page_count) * 1.0 / 128) AS [user object space in MB], 
        SUM(internal_object_reserved_page_count) AS [internal_object pages used], 
        (SUM(internal_object_reserved_page_count) * 1.0 / 128) AS [internal_object space in MB] 
    FROM 
        sys.dm_db_file_space_usage;
  2. User Objects veya Internal Objects büyük miktarda alan kullanıyorsa:

    1. Hangi oturumların büyük miktarda tempdb alanı kullandığını bulmak için sys.dm_db_session_space_usage sistem görünümünü kullanarak aşağıdaki SQL ifadesini çalıştırın:

      sys.dm_db_session_space_usage kullanımı hakkında daha fazla bilgi için bkz. resmi Microsoft öğreticisi.

      SELECT 
          session_id, 
          SUM(user_objects_alloc_page_count) AS [user object pages used], 
          (SUM(user_objects_alloc_page_count) * 1.0 / 128) AS [user object space in MB], 
          SUM(internal_objects_alloc_page_count) AS [internal_object pages used], 
          (SUM(internal_objects_alloc_page_count) * 1.0 / 128) AS [internal_object space in MB] 
      FROM 
          sys.dm_db_session_space_usage 
      GROUP BY 
          session_id;
    2. Oturum kimliğini kullanarak, o oturumun şu anda çalıştırdığı SQL ifadesini sorgulayabilirsiniz:

      SELECT 
          r.session_id AS [SPID], 
          r.start_time AS [Start Time], 
          r.status AS [Status], 
          r.command AS [Command Type], 
          r.wait_type AS [Wait Type], 
          r.wait_time AS [Wait Time (ms)], 
          r.last_wait_type AS [Last Wait Type], 
          t.text AS [Executing Statement] 
      FROM 
          sys.dm_exec_requests r 
      CROSS APPLY 
          sys.dm_exec_sql_text(r.sql_handle) t 
      WHERE 
          r.session_id = xxx; ---xxx is the session_id from the previous step
  3. Version Store büyük miktarda alan kullanıyorsa, veritabanında anlık görüntü izolasyonu etkinleştirilmiş olabilir. Bu durum, tempdb'de çok sayıda anlık görüntü sürümünün depolanmasına neden olur.

    1. Anlık görüntü izolasyonunun hangi veritabanlarında etkin olduğunu sorgulayabilirsiniz:

      SELECT 
          name, 
          is_read_committed_snapshot_on, 
          snapshot_isolation_state 
      FROM sys.databases;

      is_read_committed_snapshot_on veya snapshot_isolation_state alanının değeri 1 ise, ilgili veritabanında anlık görüntü izolasyonu etkindir (aşağıdaki şekilde gösterildiği gibi):

      image

    2. Kayıtların Version Store'da otomatik olarak temizlenmesini engelleyen, taahhüt edilmemiş uzun süren işlemlere sahip oturumları kontrol etmek için sys.dm_tran_active_snapshot_database_transactions sistem görünümünü kullanabilirsiniz:

      SELECT * FROM sys.dm_tran_active_snapshot_database_transactions ORDER BY elapsed_time_seconds DESC;

      Ayrıntılar aşağıdaki gibidir:

      image

    3. session_id değerini elde ettikten sonra, oturum durumunu ve yürütülen komutu kontrol etmek için sys.sysprocesses ve sys.dm_exec_requests/sys.dm_exec_sql_text sorgulayabilirsiniz:

      SELECT * FROM sys.sysprocesses WHERE spid = xxx;  --spid is the session_id from the previous step

      Ayrıntılar aşağıdaki gibidir:

      image

    4. Oturum durumu sleeping ise, yürütülen ifadeyi kontrol etmek için aşağıdaki SQL komutunu kullanabilirsiniz:

      DBCC INPUTBUFFER(xxx);  --xxx is the session ID (spid) from the previous step

      Ayrıntılar aşağıdaki gibidir:

      image

Senaryo 2: Yeniden başlatmadan sonra geçmiş tempdb alan büyümesinin nedenini araştırma

Canlı veriler mevcut değilse, sorunu Ortalama Etkin Oturumlar (AAS), yavaş sorgu günlükleri ve denetim günlüklerini kullanarak analiz edebilirsiniz. Adımlar aşağıdaki gibidir:

  1. tempdb alan büyümesinin başlangıç ve bitiş zamanlarını analiz etme

    İlk olarak, tempdb alan kullanımının büyüme eğilimini analiz edin. Örnek ayrıntıları sayfasında Monitoring and Alerts > Standard Monitoring yolunu izleyin. Instance Storage bölümünde, tmp_size ölçümünün arttığı başlangıç ve bitiş zamanlarını not edin. Bir SQL işlemi başladığında, tempdb'de öncelikle yeniden kullanılan mevcut boş alan bulunabilir. Bu nedenle, gerçek alan genişletme zamanı SQL işleminin başlangıç zamanından daha sonra olabilir. Sistem, tempdb'deki mevcut alan tükendiğinde yeni depolama alanı ayırmak için bir dosya genişletme işlemi tetikler.

    image

  2. AAS (Ortalama Etkin Oturumlar) kullanarak analiz etme

    Örnek ayrıntıları sayfasında Autonomy Service > Performance Optimization > Performance Insight yolunu izleyin. Hedef zaman aralığını seçin. İlgili tüm işlemleri yakalamak için zaman aralığının başlangıcını genişletmeniz gerekir. Bu dönemdeki SQL çalıştırma kayıtlarını analiz ederek disk tabanlı geçici tabloları yoğun kullanan işlemleri belirleyin.

    Örneğin, #RKD_SJ gibi geçici tabloların oluşturulmasını ve kullanımını kontrol edin. Bu geçici tabloların sık kullanılması, tempdb alan büyümesinin temel nedeni olabilir.

    image

  3. Anahtar kelimelerle yavaş sorgu günlüklerini filtreleyerek analiz etme

    Örnek ayrıntıları sayfasında Autonomy Service > Slow Query Logs yolunu izleyin. Yavaş sorgu günlüklerini anahtar kelimeye göre filtreleyin. SQL çalışma süresini ve başlangıç zamanını kontrol edin. Sorgunun bitiş zamanının tempdb alanının büyümeyi durdurduğu zamanla eşleşip eşleşmediğini analiz edebilirsiniz.

    image

Günlük dosyası alanını geri kazanma

tempdb için günlük dosyası alanı büyürse, bu genellikle uzun süren bir işlemin günlüğün kesilmesini engellemesinden kaynaklanır. Alanı aşağıdaki gibi geri kazanabilirsiniz:

  1. sys.database içindeki log_reuse_wait_desc alanında günlük yeniden kullanım bekleme türünü kontrol edin. Günlük yeniden kullanım bekleme türü ACTIVE_TRANSACTION ise, uzun süren bir işlem vardır.

  2. tempdb veritabanında hangi uzun süren işlemlerin çalıştığını belirleyin. Uzun süren işlemleri sonlandırdıktan sonra, günlük dosyasını küçültmek için SHRINKFILE kullanabilirsiniz.

tempdb günlük dosyalarının alan kullanımını analiz etmek için aşağıdaki çözümleri kullanabilirsiniz:

  1. İlk olarak, veritabanı günlük dosyasının durumunu kontrol edin.

    Çalıştırma sonuçlarında, tempdb günlük alanı durumunu kontrol edin. LogReuseWaitDescription değeri NOTHING ise, günlük dosyasını doğrudan SHRINKFILE ile küçültebilirsiniz. Değer NOTHING değilse (örneğin, yaygın olan ACTIVE_TRANSACTION değeri), etkin uzun süren bir işlem vardır. Günlük dosyasını SHRINKFILE ile küçültmeden önce uzun süren işlemi sonlandırmanız gerekir.

    SELECT
    name AS [DatabaseName],
    recovery_model_desc AS [RecoveryModel],
    log_reuse_wait_desc AS [LogReuseWaitDescription]
    FROM sys.databases;

    image

  2. Tempdb günlük dosyası büyümesi genellikle etkin uzun süren işlemlerden kaynaklanır. Tempdb veritabanındaki en uzun süren işlemi kontrol etmek ve sonlandırıp sonlandırmamaya karar vermek için aşağıdaki SQL komutunu kullanabilirsiniz:

    USE tempdb;
    GO
    DBCC OPENTRAN;
    GO

    Aşağıdaki şekilde gösterildiği gibi, oturum kimliğine (SPID) ve işlem başlangıç zamanına (Start time) dikkat edin:

    image

  3. Ardından, oturumun ne yaptığını ve durumunu kontrol edebilirsiniz. Önceki adımdaki oturum kimliğini kullanabilirsiniz:

    SELECT * FROM sys.sysprocesses WHERE spid = xxx;--spid is the SPID from the previous step

    Örneğin:

    image

  4. Oturum durumu sleeping ise, yürütülen ifadeyi kontrol etmek için aşağıdaki SQL komutunu kullanabilirsiniz:

    DBCC INPUTBUFFER(xxx);  --xxx is the session ID (spid) from the previous step

    Aşağıdaki şekilde bir örnek gösterilmektedir.

    image

Veri alanı nasıl çalışır

Toplam veri alanı, tüm veri dosyası boyutlarının toplamına eşittir ve iki bölüme ayrılır:

  • Ayrılan alan: Tablolara veya dizinlere atanmış alan. Hem veri içeren satırları hem de aynı tablo veya dizine gelecekteki eklemeler için ayrılmış sayfaları içerir. Diğer nesneler bu alanı doğrudan kullanamaz.

  • Ayrılmamış alan: Herhangi bir nesneyle ilişkilendirilmemiş tamamen boş genişletmeler (her genişletme 64 KB'lık bitişik alandır). Bir dosyayı küçültmek, bu alanı işletim sistemine geri bırakır.

Veriler hala büyüyorsa, ayrılmamış alan genellikle küçüktür. Dosyaları doğrudan küçültmenin etkisi azdır. Önce ayrılan alanı geri kazanın, ardından küçültmeyi düşünün.

Ayrılan alanı geri kazanma

Verileri arşivleme veya silme

Eski geçmiş kayıtlar gibi nadiren erişilen verileri başka bir örneğe veya arşiv formatına silin veya taşıyın. Bu işlem, kullanılan veri alanını doğrudan azaltır ve en etkili uzun vadeli çözümdür, ancak uygulama mantığında ve veritabanı tasarımında değişiklikler gerektirir.

Verileri sıkıştırma

SQL Server 2016 veya sonraki sürümleri çalıştıran örnekler ve daha eski sürümleri çalıştıran Enterprise Edition örnekleri, tablo, dizin veya bölüm düzeyinde satır ve sayfa sıkıştırmayı destekler. Ayrıntılar için bkz. Veri sıkıştırma.

Tasarruflar şemaya, sütun türlerine ve veri dağılımına bağlı olarak büyük ölçüde değişir (%10–%90). Sıkıştırmayı etkinleştirmeden önce tasarrufları tahmin etmek için sp_estimate_data_compression_savings kullanın.

Sıkıştırma ayarlarını değiştirmek bir Veri Tanımlama Dili (DDL) işlemidir. Büyük tablolarda bu işlem, uzun süren tablo kilitlemelerine neden olabilir. Yoğun olmayan saatlerde çalıştırın.
Enterprise Edition örneklerinde, iş etkisini en aza indirmek için ONLINE = ON ayarlayın.
Sıkıştırma CPU yükünü artırır. Yalnızca alan tasarrufunun maliyeti haklı çıkardığı büyük tablolarda etkinleştirin.

Dizini parçalama giderme

Yüksek dizin parçalanması sorguları yavaşlatır ve depolamayı boşa harcar. Parçalanma oranlarını görüntülemek için Autonomy Services > Performance Optimization bölümüne gidin ve Index Usage sekmesine tıklayın. Konsol, her tablo için parçalanma oranını gösterir ve her dizini yeniden oluşturup yeniden düzenlemeniz gerekip gerekmediğini önerir.

Dizin parçalanma oranı, mantıksal olarak bitişik olan dizin sayfalarının fiziksel olarak bitişik olmama yüzdesini ölçer. Bu, sayfalar içindeki boş alan yüzdesinden farklıdır. Sayfa başına ortalama boş alanı ölçmek için sys.dm_db_index_physical_stats öğesini SAMPLED veya DETAILED modunda sorgulayın ve avg_page_space_used_in_percent sütununu kontrol edin. Ayrıntılar için bkz. sys.dm_db_index_physical_stats (Transact-SQL) . Bu sorgu birçok dizin sayfasını okur; yoğun olmayan saatlerde çalıştırın.

Dizini yeniden oluşturma (REBUILD): Dizini tamamen yeniden oluşturur. Yüksek parçalanmaya sahip dizinler için yeniden düzenlemeden daha etkilidir. Varsayılan olarak, işlem sırasında tabloyu kilitler. Enterprise Edition örneklerinde, uzun tablo kilitlerinden kaçınmak için ONLINE = ON ayarlayın.

Önemli

Yeniden oluşturma işlemi, veritabanı depolamasını ve günlük boyutunu geçici olarak önemli ölçüde artırır. Yeniden oluşturmadan önce, örnekte yeniden oluşturulan dizinin boyutunun en az iki katı kadar boş depolama alanı olduğundan emin olun.

  • Boş alanı kontrol edin: örneğin Basic Information sayfasına gidin ve Instance Resources bölümüne bakın.

  • Boş alan yetersizse, önce depolamayı ölçeklendirin. Yeni alan, yeniden başlatma olmadan hemen etkili olur.

ALTER INDEX <IX_YourIndexName> ON <YourTableName> REBUILD WITH (ONLINE = ON);

Yeniden oluşturma işleminden sonra konsol dizin istatistiklerini eşzamansız olarak günceller. En son verileri almak için Recollect düğmesine tıklayın, ardından parçalanma oranını doğrulamak için Export Script düğmesine tıklayarak betiği indirin.

Index Usage

Dizini yeniden düzenleme (REORGANIZE): Tabloyu kilitlemeden yaprak düzeyi sayfaları yeniden yapılandırır. Yeniden oluşturmaya göre daha az etkilidir, ancak düşük parçalanmaya sahip dizinler için uygundur.

Veri dosyalarını küçültme

Yukarıdaki yöntemleri kullanarak ayrılan alanı geri kazandıktan sonra, depolama baskısı devam ediyorsa aşağıdaki yaklaşımlardan birini kullanın.

Önemli

Tek seferde büyük ölçekli bir küçültme işlemi, önemli ölçüde işlem günlüğü büyümesine ve uzun süreli engellemeye neden olabilir. Küçük partiler halinde küçültmek için Yöntem 1'i kullanın.

Yöntem 1 — Artımlı küçültme döngüsü (önerilen)

Her seferinde yaklaşık 5 GB'lık yinelemelerle küçültme yapın. Aşağıdaki betik SQL Server 2012 ve sonraki sürümler için geçerlidir:

-- This script applies only to SQL Server 2012 and later versions. Specify the following parameters before running.
DECLARE @dbName NVARCHAR(128) = 'YourDBName'  -- Database name
DECLARE @fileName NVARCHAR(128)               -- Data file name
DECLARE @targetSize INT = 2000                -- Target size (MB)
DECLARE @shrinkSize INT = 5120                -- Size to shrink per iteration (MB). 5 GB recommended.
DECLARE @currentSize INT                      -- Current file size
DECLARE @freeSize INT                         -- Unallocated space
DECLARE @usedSize INT                         -- Used space

DECLARE @sql NVARCHAR(500)
DECLARE @waitTime INT = 10                    -- Wait between iterations (seconds)

-- Get the data file name
SELECT @fileName = name
FROM sys.master_files
WHERE database_id = DB_ID(@dbName)
AND type_desc = 'ROWS'

-- Shrink in a loop
WHILE 1 = 1
BEGIN
    -- Get current size and space breakdown
    DECLARE @sql0 NVARCHAR(MAX) = N'
    USE [' + @dbName + '];
    SELECT
      @currentSize = (SUM(total_page_count) * 1.0 / 128),
      @freesize = (SUM(unallocated_extent_page_count) * 1.0 / 128)
    FROM sys.dm_db_file_space_usage
    WHERE database_id = DB_ID();'

    EXEC sp_executesql
      @sql0,
      N'@currentSize INT OUTPUT, @freesize INT OUTPUT',
      @currentSize OUTPUT,
      @freesize OUTPUT

    PRINT 'Current size:' + CAST(@currentSize AS VARCHAR(10)) + 'MB'
    PRINT 'Free size:' + CAST(@freeSize AS VARCHAR(10)) + 'MB'

    SET @usedSize = @currentSize - @freeSize
    PRINT 'Used size:' + CAST(@usedSize AS VARCHAR(10)) + 'MB'

    -- Validate target size
    IF @targetSize <= @usedSize
    BEGIN
        PRINT 'The target size is too small. Specify a new size. The target size cannot be smaller than: ' + CAST(@usedSize AS VARCHAR(20)) + 'MB'
        BREAK
    END

    -- Exit when target is reached
    IF @currentSize <= @targetSize
    BEGIN
        PRINT 'Shrink completed. Current size: ' + CAST(@currentSize AS VARCHAR(20)) + 'MB'
        BREAK
    END

    -- Calculate the new size for this iteration
    DECLARE @newSize INT = @currentSize - @shrinkSize
    IF @newSize < @targetSize
        SET @newSize = @targetSize

    -- Run the shrink
    SET @sql = 'USE [' + @dbName + '];DBCC SHRINKFILE (N''' + @fileName + ''', ' + CAST(@newSize AS VARCHAR(20)) + ')'
    PRINT 'Executing shrink: ' + @sql
    EXEC (@sql)

    -- Wait before the next iteration
    PRINT 'Waiting ' + CAST(@waitTime AS VARCHAR(10)) + ' seconds to continue...'
    WAITFOR DELAY '00:00:10'
END

Yöntem 2 — Doğrudan DBCC SHRINKFILE

Tek bir veri dosyasını hedef boyuta küçültmek için DBCC SHRINKFILE çalıştırın. Bu işlem, ayrılmamış alanı işletim sistemine geri bırakır. Referans için bkz. Veritabanını küçültme ve DBCC SHRINKFILE.

DBCC SHRINKFILE(<File ID>, <Target size in MB>)

Bir örnek görüntülemek için tıklayın

Örnek: Aşağıdaki şekilde, her genişletme 64 KB'dır. Toplam veri dosyası boyutu = (1673344 × 64) / 1024 = 104.584 MB. Ayrılan alan = (1313432 × 64) / 1024 = 82.089,5 MB. Dosya 82.089,5 MB'nin altına küçültülemez. 90.000 MB'ye küçültmek için şunu çalıştırın:

DBCC SHRINKFILE(1, 90000)

DBCC SHRINKFILE example

Yaygın veri alanı sorunlarını giderme

Dizini yeniden oluşturduktan sonra Index Usage tablosundaki parçalanma oranı neden güncellenmiyor?

Yeniden oluşturma tamamlandıktan sonra konsol, güncellenmiş istatistikleri arka planda eşzamansız olarak toplar. Manuel yenilemeyi tetiklemek için Recollect düğmesine tıklayın. Toplama tamamlandığında, mevcut parçalanma oranını doğrulamak için Export Script düğmesine tıklayarak betiği indirin.

Index Usage after rebuild

SHRINKFILE çalıştırdıktan sonra neden ilerleme olmadan askıda kalıyor?

Sorun açıklaması

Bir Alibaba Cloud RDS for SQL Server örneğinde, boş alanı geri kazanmak için bir veritabanı veri dosyası veya günlük dosyasında SHRINKFILE işlemini çalıştırmayı denediğinizde aşağıdaki sorunlarla karşılaşabilirsiniz:

  • SHRINKFILE komutu uzun süre tamamlanmaz.

  • İlerleme yüzdesi (percent_complete) uzun süre güncellenmez.

Bu tür sorunlar genellikle uzun süren işlem engellemesinden kaynaklanır; özellikle veritabanı için Anlık Görüntü İzolasyonu etkinleştirildiğinde, anlık görüntü sürümlerinin korunması SHRINKFILE işleminin normal şekilde tamamlanmasını engeller.

Çözüm

  1. SQL Server Management Studio (SSMS) kullanarak RDS for SQL Server örneğine bağlanın.

  2. SHRINKFILE işleminin durumunu ve ilerlemesini onaylamak için aşağıdaki sorguyu çalıştırın:

    SELECT 
        r.session_id AS [SPID],
        r.start_time AS [Start Time],
        r.status AS [Status],
        r.command AS [Command Type],
        r.wait_type AS [Wait Type],
        r.wait_time AS [Wait Time (ms)],
        r.last_wait_type AS [Last Wait Type],
        t.text AS [Executed Statement],
        r.percent_complete AS [Execution Progress]
    FROM 
        sys.dm_exec_requests r
    CROSS APPLY 
        sys.dm_exec_sql_text(r.sql_handle) t;

    Durum sütunu suspended gösteriyorsa ve percent_complete sütunundaki değer uzun süre güncellenmemişse, SHRINKFILE işlemi engellenmiştir. Bir sonraki adıma geçebilirsiniz.

    image

  3. RDS for SQL Server hata günlüğünde aşağıdakine benzer bir mesaj olup olmadığını kontrol edin:

    DBCC SHRINKFILE for file ID 1 is waiting for the snapshot
    transaction with timestamp 15 and other snapshot transactions linked to
    timestamp 15 or with timestamps older than 109 to finish.

    Örnek sonuç:

    Bu günlük, veritabanı için anlık görüntü izolasyonunun etkinleştirilmesi nedeniyle SHRINKFILE işleminin bir anlık görüntü işlemi tarafından engellendiğini ve devam edemediğini gösterir.

    image

  4. Veritabanı için anlık görüntü izolasyonunun etkin olup olmadığını kontrol etmek için aşağıdaki sorguyu çalıştırın:

    SELECT 
        name,
        is_read_committed_snapshot_on,
        snapshot_isolation_state,
        snapshot_isolation_state_desc
    FROM 
        sys.databases;

    is_read_committed_snapshot_on=1 veya snapshot_isolation_state_desc=ON ise, veritabanı için anlık görüntü özelliği etkindir ve uzun süren işlemler için daha fazla araştırma yapmanız gerekir.

    image

  5. Engellemeye neden olabilecek uzun süren işlemleri kontrol etmek ve sürelerini kontrol etmek için aşağıdaki SQL ifadesini çalıştırın:

    SELECT db_name(exe.database_id),tr.* FROM sys.dm_tran_active_snapshot_database_transactions AS tr JOIN sys.dm_exec_requests AS exe ON tr.session_id=exe.session_id;

    Çalıştırma tamamlandıktan sonra session_id ve elapsed_time_seconds alanlarına dikkat edin. elapsed_time_seconds alanı işlem süresini belirtir. Daha büyük bir değer, işlemin daha uzun süredir çalıştığını ve daha fazla dikkat gerektirdiğini gösterir. Belirli uzun süren işlemlerin engellemeye neden olduğunu tespit ederseniz, bu işlemleri sonlandırmayı (KILL) düşünebilir ve SHRINKFILE işleminin devam edip etmediğini gözlemleyebilirsiniz.

    Not

    Engellenen bir SHRINKFILE işlemi mutlaka mevcut veritabanındaki uzun süren işlemlerden kaynaklanmaz. Kök neden, özellikle veritabanları arası sorguları içeren senaryolarda, anlık görüntülerin etkin olduğu diğer veritabanlardaki uzun süren işlemler de olabilir. Bu nedenle, sorun giderme sırasında sorunu doğru bir şekilde tanımlamak ve çözmek için tüm ilgili veritabanlarının işlem durumunu kontrol etmeniz gerekir.

    image

  6. Önceki adımlar aracılığıyla bir veya daha fazla uzun süren işlemin SHRINKFILE işlemini engellediğini onaylarsanız, SHRINKFILE işleminin normal yürütülmesini sürdürmek için bu işlemleri durdurup (KILL) durduramayacağınızı değerlendirmeniz gerekir. Uzun süren bir işlemi durdurmanın geri alınmasına neden olduğunu unutmayın. Bu nedenle, KILL işlemini çalıştırmadan önce geri almanın işiniz üzerindeki etkisini tam olarak değerlendirmeniz gerekir. İş nedenleriyle uzun süren işlemleri durduramıyorsanız, aşağıdaki önerilere bakın:

    • Uzun süren işlemin tamamlanmasını bekleyin. Tamamlandıktan sonra SHRINKFILE işlemini tekrar çalıştırabilirsiniz.

    • SHRINKFILE işlemini durdurun. Mevcut pencere beklemek için uygun bir zaman değilse, SHRINKFILE işlemini durdurabilir ve uygun bir bakım penceresi için yeniden planlayabilirsiniz.

Günlük alanını geri kazanma

Günlük alanı kullanımını kontrol etme

Her veritabanının günlük dosyasındaki kullanılan alan yüzdesini kontrol etmek için DBCC SQLPERF(LOGSPACE) veya Monitoring and Alerts sayfasını kullanın.

Kullanılan yüzde yüksekse, günlük dosyasını küçültmenin etkisi az olacaktır. Engelleme koşulu çözülene kadar günlük kesilemez. Kesmenin neden beklediğini belirlemek için sys.databases sorgulayın ve log_reuse_wait_desc sütununu kontrol edin:

SELECT name, log_reuse_wait, log_reuse_wait_desc FROM sys.databases;

log_reuse_wait_desc değerlerinin tam listesi için bkz. sys.databases (Transact-SQL).

İşlem günlüklerini küçültme

Uyarı

İşlem günlüğü doluysa, konsoldan küçültemezsiniz. Risk taşıyan SQL'i manuel olarak çalıştırmanız gerekir. Mümkün olduğunda önce disk depolamasını ölçeklendirin. Acil durum prosedürleri için bkz. Yetersiz günlük alanı çözümü (yalnızca acil durum kullanımı için).

Durumunuza uygun yaklaşımı seçin:


Çözüm 1: Tek veritabanı küçültme (yedekleme yok)


Çözüm 2: Örnek düzeyinde yedekleme ve küçültme


Kapsam


Tek veritabanı


Tüm örnek


Yedekleme


Yedekleme alınmaz


Önce tüm işlem günlüklerini otomatik olarak yedekler


Hız


Hızlı


Daha yavaş — küçültmeden önce yedekleme çalışır


Ne zaman kullanılır


Günlük hızlı büyüyor ve planlanmış bir yedeklemeyi bekleyemiyorsunuz


Yeterli günlük alanı var ve global optimizasyon istiyorsunuz


Diğer veritabanlarına etkisi


Yok


Tüm örneği etkiler


Nasıl çalıştırılır


Veritabanı işlem günlüklerini küçültme


İşlem günlüklerini yedekleme ve küçültme

Küçültme tamamlandıktan sonra, güncellenen günlük alanını doğrulamak için Monitoring and Alerts bölümüne gidin.

Log space after shrink

tempdb alanını geri kazanma

tempdb alanı nasıl kullanır

tempdb geçici verileri depolayan bir SQL Server sistem veritabanıdır. Üç kategori nesne onun veri dosyası alanını tüketir:

  • Kullanıcı nesneleri: Kullanıcı oturumları tarafından oluşturulan geçici tablolar (örneğin, #TempTable).

  • Dahili nesneler: SQL Server tarafından dahili olarak oluşturulan geçici yapılar (örneğin, sıralama işlemleri veya hash join'ler için).

  • Sürüm deposu: Anlık görüntü izolasyonu veya read committed snapshot isolation (RCSI) etkinleştirildiğinde, SQL Server satır sürümlerini tempdb içinde depolar. Uzun süren işlemler bu sürümlerin temizlenmesini engeller.

Bu kategorilerden herhangi biri büyük ölçüde büyürse (özellikle uzun süren işlemler, geçici tabloların yoğun kullanımı veya anlık görüntü izolasyonu yoluyla), tempdb veri dosyası normal boyutunun çok ötesine şişebilir. Arka plan bilgisi için bkz. Microsoft tempdb belgeleri.

tempdb veri dosyası alanını geri kazanma

SHRINKFILE genellikle tempdb veri dosyaları için etkisizdir. Alanı geri kazanmanın en güvenilir yolu, yoğun olmayan saatlerde örneği yeniden başlatmaktır. SQL Server, başlangıçta tempdb değerini sıfırlar. Ayrıntılar için bkz. tempdb veritabanını küçültme.

Yeniden başlatmadan önce, tekrarlamayı önlemek için büyümeye neyin neden olduğunu teşhis edin.

Senaryo 1: tempdb şu anda büyük (canlı örnek)

Adım 1 — Nesne türüne göre alanı kontrol etme

Her kategoriye (kullanıcı nesneleri, dahili nesneler, sürüm deposu) ne kadar alan tüketildiğini görmek için aşağıdaki sorguyu çalıştırın:

SELECT
    SUM(version_store_reserved_page_count) AS [version store pages used],
    (SUM(version_store_reserved_page_count) * 1.0 / 128) AS [version store space (MB)],
    SUM(user_object_reserved_page_count) AS [user object pages used],
    (SUM(user_object_reserved_page_count) * 1.0 / 128) AS [user object space (MB)],
    SUM(internal_object_reserved_page_count) AS [internal object pages used],
    (SUM(internal_object_reserved_page_count) * 1.0 / 128) AS [internal object space (MB)]
FROM
    sys.dm_db_file_space_usage;

Referans için bkz. sys.dm_db_file_space_usage.

Adım 2a — Kullanıcı nesneleri veya dahili nesneler büyükse

En çok tempdb alanı kullanan oturumları bulun:

SELECT
    session_id,
    SUM(user_objects_alloc_page_count) AS [user object pages used],
    (SUM(user_objects_alloc_page_count) * 1.0 / 128) AS [user object space (MB)],
    SUM(internal_objects_alloc_page_count) AS [internal object pages used],
    (SUM(internal_objects_alloc_page_count) * 1.0 / 128) AS [internal object space (MB)]
FROM
    sys.dm_db_session_space_usage
GROUP BY
    session_id;

Referans için bkz. sys.dm_db_session_space_usage.

Ardından, oturumun çalıştırdığı SQL ifadesini bulmak için session_id değerini kullanın:

SELECT
    r.session_id AS [SPID],
    r.start_time AS [Start Time],
    r.status AS [Status],
    r.command AS [Command Type],
    r.wait_type AS [Wait Type],
    r.wait_time AS [Wait Time (ms)],
    r.last_wait_type AS [Last Wait Type],
    t.text AS [Executing Statement]
FROM
    sys.dm_exec_requests r
CROSS APPLY
    sys.dm_exec_sql_text(r.sql_handle) t
WHERE
    r.session_id = <session_id>; -- Replace with the session_id from the previous query

Adım 2b — Sürüm deposu büyükse

Veritabanında muhtemelen temizlemeyi engelleyen uzun süren işlemlerle birlikte anlık görüntü izolasyonu etkindir.

Anlık görüntü izolasyonunun hangi veritabanlarda etkin olduğunu kontrol edin:

SELECT
    name,
    is_read_committed_snapshot_on,
    snapshot_isolation_state
FROM sys.databases;

is_read_committed_snapshot_on veya snapshot_isolation_state değeri 1 ise, anlık görüntü izolasyonu aktiftir.

Snapshot isolation state

Sürüm deposu temizlemesini engelleyen, taahhüt edilmemiş uzun süren işlemlere sahip oturumları bulun:

SELECT * FROM sys.dm_tran_active_snapshot_database_transactions ORDER BY elapsed_time_seconds DESC;

Active snapshot transactions

Oturumun ne yaptığını kontrol etmek için session_id değerini kullanın:

SELECT * FROM sys.sysprocesses WHERE spid = <session_id>;

Session process details

Oturum durumu sleeping ise, son yürütülen ifadeyi kontrol edin:

DBCC INPUTBUFFER(<session_id>);

DBCC INPUTBUFFER result

Senaryo 2: Yeniden başlatmadan sonra geçmiş tempdb büyümesini araştırma

Örnek zaten yeniden başlatıldıysa ve canlı veriler mevcut değilse, ne olduğunu yeniden yapılandırmak için Ortalama Etkin Oturumlar (AAS), yavaş sorgu günlükleri ve denetim günlüklerini kullanın.

Adım 1 — Büyüme penceresini bulma

Örnek ayrıntıları sayfasında Monitoring and Alerts > Standard Monitoring bölümüne gidin. Instance Storage bölümünde, tmp_size ölçümünün yükselmeye başladığı ve durduğu zamanları not edin. tempdb öncelikle mevcut boş alanı yeniden kullanabilir; gerçek dosya genişletmesi yalnızca mevcut alan tükendiğinde gerçekleşir, bu nedenle grafikteki büyüme SQL işleminin başlangıcından gecikebilir.

tmp_size metric

Adım 2 — AAS kullanarak analiz etme

Autonomy Services > Performance Optimization > Performance Insight bölümüne gidin. İlgili tüm işlemleri yakalamak için başlangıç zamanını daha önceye uzatarak zaman penceresini seçin. Disk tabanlı geçici tabloları yoğun kullanan SQL ifadelerini arayın (örneğin, # tablolarının sık oluşturulması).

Performance Insight AAS

Adım 3 — Yavaş sorgu günlüklerini anahtar kelimeye göre filtreleme

Autonomy Services > Slow Query Logs bölümüne gidin. Anahtar kelimeye göre arama yapın (örneğin, bir geçici tablo adı). Sorgu başlangıç zamanlarını ve sürelerini kontrol ederek sorgu bitiş zamanının tempdb büyümeyi durdurduğu zamanla hizalanıp hizalanmadığını görün.

Slow query logs

tempdb günlük dosyası alanını geri kazanma

Uzun süren bir işlem günlük kesilmesini engellediğinde tempdb günlük dosyaları büyür.

  1. sys.databases içindeki log_reuse_wait_desc değerini kontrol edin:

    SELECT
        name AS [DatabaseName],
        recovery_model_desc AS [RecoveryModel],
        log_reuse_wait_desc AS [LogReuseWaitDescription]
    FROM sys.databases;

    LogReuseWaitDescription değeri NOTHING ise, günlük dosyasını doğrudan SHRINKFILE ile küçültün. ACTIVE_TRANSACTION gösteriyorsa, önce etkin uzun süren işlemi sonlandırın.

    Log reuse wait status

  2. tempdb içindeki en uzun süren işlemi bulun:

    USE tempdb;
    GO
    DBCC OPENTRAN;
    GO

    Oturum kimliğini (SPID) ve işlem başlangıç zamanını not edin.

    DBCC OPENTRAN result

  3. Oturumun ne yaptığını kontrol edin:

    SELECT * FROM sys.sysprocesses WHERE spid = <spid>;

    Session process

  4. Oturum durumu sleeping ise, son yürütülen ifadesini kontrol edin:

    DBCC INPUTBUFFER(<session_id>);

    DBCC INPUTBUFFER

Engelleyen işlemi sonlandırdıktan sonra tempdb günlük dosyasını küçültün:

USE tempdb;
DBCC SHRINKFILE(templog, 1);
GO

Diğer dosya alanını geri kazanma

Diğer dosya alanı neleri içerir

Diğer dosya alanı sistem veritabanı dosyalarını kapsar: sqlserver.other_size, mastersize, modelsize ve msdbsize. Bunlar genellikle küçüktür, ancak iki senaryoda beklenmedik şekilde büyüyebilir:

  • Hata günlükleri: Örnek çok sayıda hata olayı oluşturursa errorlog dosyası birkaç gigabayt veya daha fazla büyüyebilir.

  • Bellek döküm dosyaları: SQL Server, kritik özel durumlar sırasında otomatik olarak bellek dökümleri oluşturur.

Boyutu aşırı büyük dosyaları belirleme ve temizleme

  1. Monitoring and Alerts > Standard Monitoring bölümüne gidin ve bu dosya türleri tarafından kullanılan alanı kontrol edin. Ölçüm tanımları için bkz. Standart izlemeyi görüntüleme.

    Other file space monitoring

  2. errorlog büyük miktarda alan tüketiyorsa, hata günlüklerini temizlemek için Logs sayfasına gidin. Talimatlar için bkz. Günlükleri yönetme.

Diğer sistem dosyaları (örneğin sqlserver.other_size ) beklenmedik şekilde büyükse, kök nedeni belirlemek için teknik destekle iletişime geçin.

Depolama alanını ölçeklendirme

Yukarıdaki adımları uyguladıktan sonra alan kullanımı hala yüksekse, örneğin depolama kapasitesini ölçeklendirin. Talimatlar için bkz. Örnek teknik özelliklerini değiştirme. Yeni depolama alanı, örnek yeniden başlatılmadan hemen etkili olur.