すべてのプロダクト
Search
ドキュメントセンター

ApsaraDB RDS:RDS for SQL Server の容量不足の問題

最終更新日:Nov 10, 2025

RDS for SQL Server インスタンスの容量使用率は、監視すべき重要なメトリックです。ストレージ容量が不足すると、データベースへのデータ書き込み失敗やバックアップ作成失敗など、深刻な問題が発生する可能性があります。さらに、ストレージ容量のスケールアウトには時間がかかる場合があります。このトピックでは、容量使用率の表示方法と容量関連の問題のトラブルシューティング方法について説明します。

容量使用率の表示

  • 方法 1: インスタンスの 基本情報 ページに移動して容量使用率を表示します。このページには、現在の合計容量使用率のみが表示されます。異なるデータ型が占有する容量の詳細や、過去の使用状況に関する情報は提供されません。基本信息

  • 方法 2: インスタンスの モニターとアラーム ページに移動します。[標準モニタリング] ページでは、異なるデータ型が占有するディスク容量とその履歴傾向を表示できます。メトリックの詳細については、「標準モニタリングの表示」をご参照ください。

    image

  • 方法 3: コンソールの 自律型サービス > 空間の管理 ページに移動して、より詳細な容量使用率情報を表示します。これには、データとログの容量使用率の比較、履歴傾向、上位のデータベースとテーブルの容量割り当て詳細が含まれます。詳細については、「容量管理」をご参照ください。

    説明

    お使いの RDS インスタンスは、クラウドディスクで SQL Server 2008 R2 を実行していません。

    image

  • 方法 4: SQL Server Management Studio (SSMS) などのクライアントツールを使用して、インスタンスの容量使用率情報を表示します。詳細については、「SSMS クライアントを使用して RDS for SQL Server インスタンスに接続する」をご参照ください。

    次の表に、SQL Server データベースの容量使用率情報を表示するための一般的なコマンドをリストします。

    システムビューまたはコマンド

    説明

    sp_helpdb

    各データベースの合計容量サイズ (データファイルとログファイルのサイズの合計) を表示します。

    sp_spaceused

    現在のデータベースの名前、使用済み容量サイズ、未割り当て容量サイズを表示します。

    DBCC SQLPERF(LOGSPACE)

    各データベースの合計ログファイルサイズと実際の使用済みログ容量を表示します。

    DBCC SHOWFILESTATS

    現在のデータベース内のすべてのデータファイルの合計データファイルサイズと実際の使用済みデータ容量を表示します。

    SELECT * FROM sys.master_files

    各データベースのデータファイルとログファイルのサイズを表示します。

    SELECT * FROM sys.dm_db_log_space_usage

    現在のデータベースの合計ログ容量と実際の使用済みログ容量を表示します。このコマンドは SQL Server 2012 以降のバージョンにのみ適用されます。

    SELECT * FROM sys.dm_db_file_space_usage

    現在のデータベースの合計データファイル容量と実際の使用済みデータ容量を表示します。このコマンドは SQL Server 2012 以降のバージョンにのみ適用されます。

インスタンスの容量使用率が高い場合は、RDS コンソール[モニタリングとアラート] ページに移動します。データ、ログ、一時ファイル、その他のファイルの容量使用率を確認して、どのファイルタイプが急速に増加しているかを特定します。次に、容量を解放できるか、または急速な増加を防ぐことができるかを評価します。詳細な分析とソリューションについては、次のセクションをご参照ください。

データ容量の再利用と解放

原因の分析

合計データ容量は、すべてのデータファイルサイズの合計であり、割り当て済み領域と未割り当て領域の 2 つの部分で構成されます。

  • 割り当て済み領域には、使用済み領域と未使用領域が含まれます。未使用領域は、同じテーブルまたはインデックス内の新しいレコードにのみ割り当てることができ、他のデータベースオブジェクトが直接使用することはできません。

  • 未割り当て領域は、完全に未割り当てのエクステントで構成されます。各エクステントは 64 KB の隣接した領域です。未割り当て領域は、どのデータベースオブジェクトにも関連付けられていません。ファイルを圧縮することで、この領域を解放できます。

データ量が継続的に増加する場合、通常、未割り当て領域は小さくなります。このシナリオでは、ファイルを直接圧縮しても効果はありません。ファイルを圧縮する前に、まず割り当て済み領域を最適化して再利用する必要があります。

データ容量の再利用

データ容量を再利用するために一般的に使用される方法は次のとおりです。

  • データのアーカイブ

    古い既存データなど、使用頻度の低いデータをデータベースから削除します。データを他のデータベースインスタンスに移行したり、他のフォーマットでアーカイブしたりすることもできます。この方法は、データ量と使用済みデータ容量を直接削減します。

    この方法はデータ容量の増加を制御するのに効果的ですが、データベースオブジェクトとアプリケーションロジックの特定の設計が必要です。また、アプリケーション設計者と開発者の協力も必要です。

  • データの圧縮

    SQL Server 2016 以降を実行するインスタンス、および 2016 より前のバージョンを実行する Enterprise インスタンスには、組み込みのデータ圧縮機能があります。単一のテーブル、インデックス、またはパーティションで行またはページの圧縮を有効にできます。詳細については、「データ圧縮」をご参照ください。

    データ圧縮率は大きく異なります。これは、テーブルスキーマ、列のデータの型、および値の分布に依存します。比率は 10% から 90% の範囲になります。SQL Server は、専用のストアドプロシージャ sp_estimate_data_compression_savings を提供しており、特定のテーブルまたはインデックスで圧縮を有効にすることによって得られるストレージの節約量を迅速に見積もるのに役立ちます。

    説明
    • テーブルまたはインデックスの圧縮設定の変更は、データ定義言語 (DDL) 操作です。大規模なテーブルの場合、この操作は長期間のテーブルロックを引き起こし、ビジネスに影響を与える可能性があります。この操作はオフピーク時に実行する必要があります。

    • RDS for SQL Server Enterprise インスタンスの場合、ONLINE パラメーターを ON に設定できます。その後、変更を実行できます。これにより、ビジネスへの影響は最小限に抑えられます。

    • データ圧縮は CPU のオーバーヘッドを増加させます。必要に応じて影響を評価する必要があります。大規模なテーブルでのみデータ圧縮を有効にしてください。

  • インデックスのデフラグ

    高いインデックスの断片化率は、クエリを遅くし、データストレージの使用量を増加させる可能性があります。インデックスをデフラグすることで、クエリ速度を向上させ、不要なストレージ容量を解放できます。

    インデックスの断片化率の表示: RDS コンソールで、自律型サービス > 性能を最適化する ページに移動します。[インデックスの使用状況] タブをクリックして、各テーブルのインデックスの断片化率を表示します。自律サービスは、インデックスの再構築または再編成の提案を提供します。

    説明
    • インデックスの断片化率は、論理的に隣接しているが物理的に隣接していないインデックスページの割合です。これは、インデックスページ内の空き領域の割合とは異なります。ただし、断片化率の高いインデックスは、再利用可能な領域の割合も高い可能性があります。

    • インデックスのページ内の平均空き領域の割合を分析するには、sys.dm_db_index_physical_stats システムビューを SAMPLED または DETAILED モードでクエリします。次に、結果セットの avg_page_space_used_in_percent 列の値を確認します。詳細については、「sys.dm_db_index_physical_stats (Transact-SQL)」をご参照ください。このクエリは多くのインデックスページを読み取るため、データベースのパフォーマンスに影響を与える可能性があります。この操作はオフピーク時に実行する必要があります。

    • インデックスの再構築操作

      この操作は、高い断片化率を持つインデックスに対してより良い最適化を提供し、より効率的です。デフォルトでは、再構築操作は対応するテーブルをロックします。Enterprise インスタンスの場合、ONLINE パラメーターを ON に設定して、長期間のテーブルロックを回避できます。

      重要

      大規模なインデックスの場合、再構築操作はデータベースのストレージ容量とログサイズを短期的に大幅に増加させる可能性があります。インデックスを再構築する前に、RDS インスタンスに再構築されるインデックスのサイズの少なくとも 2 倍の空きストレージ容量があることを確認してください。

      • RDS インスタンスのストレージ容量の表示: RDS インスタンスの [基本情報] ページに移動します。[インスタンスリソース] セクションで、インスタンスの合計および使用済みストレージ容量を表示できます。

      • 空き領域が不足している場合は、ストレージのスケールアウトを実行できます。スケールアウトが成功した後、インスタンスを再起動する必要はありません。システムは自動的に新しい容量を適用し、変更はすぐに有効になります。

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

      コマンドが実行された後、システムはバックグラウンドで非同期にインデックス統計を再度収集します。このプロセスには時間がかかります。したがって、コンソールページに表示される断片化率はすぐには更新されない場合があります。[再収集] ボタンをクリックして、最新のデータを手動で収集できます。データ収集が完了したら、[スクリプトのエクスポート] をクリックしてスクリプトをローカルマシンにダウンロードし、インデックスの断片化率が低下したかどうかを確認できます。

      image

    • インデックスの再編成操作

      この操作は、低い断片化率を持つインデックスに対してより効率的ですが、その最適化効果は再構築ほど大きくありません。

データファイルの圧縮

前のセクションで説明したデータ容量の再利用方法は、通常、データ容量の使用量を効果的に削減できます。インスタンスの容量がまだ圧迫されている場合は、次の 2 つの方法のいずれかを使用できます。

重要

SQL Server データベースでの単一の大規模な圧縮操作は、大幅なトランザクションログの増加と長期間のブロッキングを引き起こす可能性があります。方法 1 を使用して、ミニバッチのループでファイルを圧縮してください。

  • 方法 1: ミニバッチのループでデータファイルを圧縮します。各反復でファイルを 5 GB ずつ圧縮することをお勧めします。以下に例を示します:

    -- このスクリプトは SQL Server 2012 以降のバージョンにのみ適用されます。使用前に以下のパラメーターを指定してください。
    DECLARE @dbName NVARCHAR(128) = 'YourDBName'  -- データベース名
    DECLARE @fileName NVARCHAR(128)  -- データファイル名
    DECLARE @targetSize INT = 2000   -- ターゲットサイズ (MB)
    DECLARE @shrinkSize INT = 5120   -- 各ループ反復で圧縮するサイズ (MB)。5 GB を推奨します。
    DECLARE @currentSize INT         -- 現在のサイズ
    DECLARE @freeSize INT            -- 空き容量サイズ
    DECLARE @usedSize INT            -- 使用済み容量サイズ
    
    DECLARE @sql NVARCHAR(500)       
    DECLARE @waitTime INT = 10      -- 各圧縮操作後の待機時間 (秒)
    
    -- データファイル名を取得
    SELECT @fileName = name
    FROM sys.master_files
    WHERE database_id = DB_ID(@dbName)
    AND type_desc = 'ROWS'
    
    
    -- ループで圧縮
    WHILE 1 = 1
    BEGIN
        -- 現在のサイズ、空き容量サイズ、使用済み容量サイズを取得
        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'
    
        -- ターゲットサイズが使用済み容量サイズより小さいかどうかを確認
        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
    
        
        -- ターゲットサイズに達したら終了
        IF @currentSize <= @targetSize
        BEGIN
            PRINT 'Shrink completed. Current size: ' + CAST(@currentSize AS VARCHAR(20)) + 'MB'
            BREAK
        END
        
        -- この圧縮操作後の新しいサイズを計算
        DECLARE @newSize INT = @currentSize - @shrinkSize
        IF @newSize < @targetSize
            SET @newSize = @targetSize
            
        -- 圧縮操作を実行
        SET @sql = 'USE [' + @dbName + '];DBCC SHRINKFILE (N''' + @fileName + ''', ' + CAST(@newSize AS VARCHAR(20)) + ')'
        PRINT 'Executing shrink: ' + @sql
        EXEC (@sql)
        
        -- 一定期間待機してから続行
        PRINT 'Waiting ' + CAST(@waitTime AS VARCHAR(10)) + ' seconds to continue...'
        WAITFOR DELAY '00:00:10'
    END
  • 方法 2: DBCC SHRINKFILE コマンドを実行して、単一のデータファイルを直接圧縮します。このコマンドは、データファイル内の未割り当て領域をオペレーティングシステムに解放します。詳細については、「データベースの圧縮」および「DBCC SHRINKFILE (Transact-SQL)」をご参照ください。

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

    クリックして例を表示

    案例上の図では、エクステントのサイズは 64 KB です。データファイルの合計サイズは (1673344 × 64) / 1024 = 104584 MB です。割り当て済み領域は (1313432 × 64) / 1024 = 82089.5 MB です。これは、圧縮後のデータファイルの合計サイズが 82089.5 MB 未満にはならないことを意味します。データファイルの合計サイズを 90000 MB に圧縮するには、次のコマンドを実行します:

    DBCC SHRINKFILE(1, 90000)

よくある質問

RDS インスタンスのインデックスの断片化率が高いです。インデックスを再構築するための再構築コマンドを実行した後、RDS コンソールの [インデックス使用状況情報] テーブルの [断片化率] が変わらないのはなぜですか?

ソリューション: 再構築コマンドが実行された後、システムはバックグラウンドで非同期にデータを再度収集します。このプロセスには時間がかかります。[再収集] ボタンをクリックして、最新のデータを手動で収集できます。データ収集が完了したら、[スクリプトのエクスポート] をクリックしてスクリプトをローカルマシンにダウンロードし、インデックスの再利用状況を確認できます。

image

SHRINKFILE コマンドを実行した後、完了までに時間がかかり、進行状況のパーセンテージが更新されないのはなぜですか?

問題の説明

Alibaba Cloud RDS for SQL Server インスタンスで、データベースのデータファイルまたはログファイルに対して SHRINKFILE 操作を実行して空き領域を再利用しようとすると、次の問題が発生する可能性があります:

  • SHRINKFILE コマンドが長時間完了しない。

  • 進行状況のパーセンテージ (percent_complete) が長時間更新されない。

このような問題は、通常、長時間実行トランザクションのブロッキングによって引き起こされます。特に、データベースでスナップショット分離が有効になっている場合、スナップショットバージョンの保持により SHRINKFILE 操作が正常に完了できなくなるためです。

ソリューション

  1. SQL Server Management Studio (SSMS) を使用して RDS for SQL Server インスタンスに接続します

  2. 次のクエリを実行して、SHRINKFILE 操作のステータスと進行状況を確認します:

    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;

    ステータス列に suspended が表示され、percent_complete 列の値が長時間更新されていない場合、SHRINKFILE 操作はブロックされています。次のステップに進むことができます。

    image

  3. RDS for SQL Server のエラーログで、次のようなメッセージを確認します:

    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.

    結果の例:

    このログは、データベースでスナップショット分離が有効になっているため、SHRINKFILE 操作がスナップショットトランザクションによってブロックされ、続行できないことを示しています。

    image

  4. 次のクエリを実行して、データベースでスナップショット分離が有効になっているかどうかを確認します:

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

    is_read_committed_snapshot_on=1 または snapshot_isolation_state_desc=ON の場合、データベースでスナップショット機能が有効になっており、長時間実行トランザクションをさらに調査する必要があります。

    image

  5. 次の SQL 文を実行して、ブロックを引き起こしている可能性のある長時間実行トランザクションとその期間を確認します:

    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;

    実行が完了したら、session_idelapsed_time_seconds フィールドに特に注意してください。elapsed_time_seconds フィールドはトランザクションの期間を示します。値が大きいほど、トランザクションが長時間実行されており、より注意が必要であることを示します。特定の長時間実行トランザクションがブロッキングを引き起こしていることがわかった場合は、これらのトランザクションを終了 (KILL) して、SHRINKFILE 操作が再開されるかどうかを観察することを検討できます。

    説明

    ブロックされた SHRINKFILE 操作は、必ずしも現在のデータベースの長時間実行トランザクションによって引き起こされるわけではありません。根本原因は、スナップショットが有効になっている他のデータベースの長時間実行トランザクションである可能性もあります。特に、クロスデータベースクエリを含むシナリオではそうです。したがって、トラブルシューティングを行う際には、すべての関連データベースのトランザクションステータスを確認して、問題を正確に特定して解決する必要があります。

    image

  6. 前のステップで、1 つ以上の長時間実行トランザクションが SHRINKFILE 操作をブロックしていることを確認した場合、これらのトランザクションを停止 (KILL) して SHRINKFILE 操作の正常な実行を再開できるかどうかを評価する必要があります。長時間実行トランザクションを停止すると、ロールバックが発生することに注意してください。したがって、KILL 操作を実行する前に、ロールバックがビジネスに与える影響を十分に評価する必要があります。ビジネス上の理由で長時間実行トランザクションを停止できない場合は、次の提案をご参照ください:

    • 長時間実行トランザクションが完了するのを待ちます。完了後、SHRINKFILE 操作を再度実行できます。

    • SHRINKFILE 操作を停止します。現在のウィンドウが待機するのに適した時間でない場合は、SHRINKFILE 操作を停止し、適切なメンテナンスウィンドウに再スケジュールできます。

ログ容量の再利用

使用済みログ容量の表示

ログ容量の再利用は比較的簡単です。DBCC SQLPERF(LOGSPACE) コマンドまたは DAS を使用して、データベースログファイルの使用済み容量の割合を表示できます。使用済み容量の割合が高い場合、ログファイルを圧縮してもほとんど効果はありません。sys.databases システムビューをクエリできます。log_reuse_wait および log_reuse_wait_desc 列の出力を確認して、容量を再利用できない理由を判断します。

説明

log_reuse_wait および log_reuse_wait_desc の値の詳細については、「sys.databases (Transact-SQL)」をご参照ください。

トランザクションログの圧縮

警告

データベースサーバーがトランザクションログがいっぱいであることを示している場合、コンソールからトランザクションログを圧縮することはできません。SQL 文を手動で実行してこの問題に対処できます。ただし、このソリューションにはリスクが伴います。詳細については、「ログ容量不足のソリューション (緊急時のみ)」をご参照ください。ログ容量が不足している場合は、まずディスクをスケールアウトすることをお勧めします。

機能

ソリューション 1: 単一データベースの圧縮 (圧縮のみ、バックアップなし)

ソリューション 2: インスタンスレベルでのバックアップと圧縮 (最初にバックアップ、次に圧縮)

範囲

単一データベース

インスタンス全体

バックアップ

バックアップなし

すべてのトランザクションログを自動的にバックアップ

容量再利用速度

高速

遅い (圧縮前にバックアップが必要)

シナリオ

ログの急増、次のインスタンスレベルの完全または増分バックアップを待てない (緊急の容量再利用が必要)

十分なログ容量 (トランザクションログの圧縮は一部のログ容量を消費する)、グローバルな最適化が必要

他のデータベースへの影響

影響なし

インスタンス全体に影響

操作

データベーストランザクションログの圧縮

トランザクションログのバックアップと圧縮

圧縮操作が完了したら、RDS インスタンスの [モニタリングとアラート] ページに移動して、最新のログ容量の状態を表示できます。

image

一時ファイル容量の再利用

原因分析

tempdb データベースは、一時データを格納する SQL Server のシステムデータベースです。tempdb のデータファイル容量は、次のような多くのシナリオで頻繁に使用されます:

  • ユーザーオブジェクト: ユーザーが作成した一時テーブル。

  • 内部オブジェクト: SQL Server が内部的に生成した一時テーブル。

  • バージョンストア: データベースでスナップショット分離または読み取りコミット済みスナップショットが有効になっている場合、バージョン管理情報が tempdb に格納されます。

長時間実行トランザクション、多数の一時テーブルの作成、スナップショット分離などの特定の操作が大量の容量を使用すると、データファイルが肥大化する可能性があります。これは、ファイルサイズが通常の範囲を大幅に超えて増加することを意味します。詳細については、tempdb データベースに関する Microsoft の公式チュートリアルをご参照ください。

ソリューション

RDS for SQL Server データベースには、データファイルとログファイルが含まれています。それぞれの容量を再利用する方法は次のとおりです:

データファイル容量の再利用

tempdb のデータファイル容量が大きくなった場合、SHRINKFILE コマンドを使用して圧縮してもあまり効果がありません。代わりに、Microsoft の公式チュートリアル (tempdb データベースの圧縮) で説明されているように、オフピーク時に インスタンスを再起動して tempdb の容量を解放できます。

次のソリューションを使用して、tempdb データファイルの容量使用率を分析できます:

シナリオ 1: tempdb データファイルの容量が大きい

  1. 大量の tempdb データファイルの領域が使用されている場合は、次の SQL 文を実行できます。システムビュー sys.dm_db_file_space_usage を使用して、tempdb 領域がどのオブジェクトタイプ (ユーザーオブジェクト内部オブジェクト、および バージョンストア) によって使用されているかを確認します:

    sys.dm_db_file_space_usage の使用方法の詳細については、「Microsoft の公式チュートリアル」をご参照ください。

    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. ユーザーオブジェクトまたは内部オブジェクトが大量の容量を使用している場合:

    1. 次の SQL 文を実行します。システムビュー sys.dm_db_session_space_usage を使用して、どのセッションが大量の tempdb 容量を使用しているかを見つけることができます:

      sys.dm_db_session_space_usage の使用方法の詳細については、「Microsoft の公式チュートリアルをご参照ください。

      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. 返されたセッション ID を使用して、セッションが現在実行している SQL 文をクエリできます:

      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 は前のステップの session_id です
  3. バージョンストアが大量の容量を使用している場合、データベースでスナップショット分離が有効になっている可能性があります。これにより、多くのスナップショットバージョンが tempdb に格納されます。

    1. どのデータベースでスナップショット分離が有効になっているかをクエリできます:

      SELECT 
          name, 
          is_read_committed_snapshot_on, 
          snapshot_isolation_state 
      FROM sys.databases;

      is_read_committed_snapshot_on または snapshot_isolation_state フィールドの値が 1 の場合、対応するデータベースでスナップショット分離が有効になっています。次の図を参照してください:

      image

    2. システムビュー sys.dm_tran_active_snapshot_database_transactions を使用して、コミットされていない長時間実行トランザクションを持つセッションを確認できます。これらのトランザクションは、バージョンストア内のレコードが自動的にクリーンアップされるのを防ぎます:

      SELECT * FROM sys.dm_tran_active_snapshot_database_transactions ORDER BY elapsed_time_seconds DESC;

      詳細は次のとおりです:

      image

    3. session_id を取得した後、sys.sysprocessessys.dm_exec_requests/sys.dm_exec_sql_text をクエリして、セッションのステータスと実行されたコマンドを確認できます:

      SELECT * FROM sys.sysprocesses WHERE spid = xxx;  --spid は前のステップの session_id です

      詳細は次のとおりです:

      image

    4. セッションのステータスが sleeping の場合、次の SQL コマンドを使用して実行された文を確認できます:

      DBCC INPUTBUFFER(xxx);  --xxx は前のステップのセッション ID (spid) です

      詳細は次のとおりです:

      image

シナリオ 2: 再起動後に過去の tempdb 容量増加の原因を調査する

ライブデータが利用できない場合は、平均アクティブセッション (AAS)、スロークエリログ、監査ログを使用して問題を分析できます。手順は次のとおりです:

  1. tempdb 容量増加の開始時刻と終了時刻を分析する

    まず、tempdb 容量使用量の増加傾向を分析します。インスタンス詳細ページで、[モニタリングとアラート] > [標準モニタリング] に移動します。[インスタンス容量] セクションで、tmp_size メトリックが増加した開始時刻と終了時刻をメモします。SQL 操作が開始されると、tempdb にはまだ利用可能な空き領域があり、それが最初に再利用される場合があります。したがって、実際の容量拡張時間は SQL 操作の開始時刻よりも後になる可能性があります。システムは、tempdb の既存の容量が使い果たされた後にのみ、ファイル拡張操作をトリガーして新しいストレージ容量を割り当てます。

    image

  2. AAS (平均アクティブセッション) を使用して分析する

    インスタンス詳細ページで、[自律サービス] > [パフォーマンスの最適化] > > [パフォーマンスインサイト] に移動します。ターゲット期間を選択します。関連するすべての操作をキャプチャするために、時間範囲の開始を延長する必要があります。この期間の SQL 実行レコードを分析して、ディスクベースの一時テーブルを多用する操作を特定します。

    たとえば、#RKD_SJ のような一時テーブルの作成と使用を確認します。これらの一時テーブルを頻繁に使用すると、tempdb の容量増加の主な原因となる可能性があります。

    image

  3. キーワードでスロークエリログをフィルタリングして分析する

    インスタンス詳細ページで、[自律サービス] > [低速 SQL] に移動します。キーワードでスロークエリログをフィルタリングします。SQL の実行時間と開始時間を確認します。クエリの終了時間が tempdb 容量の増加が止まった時間と一致するかどうかを分析できます。

    image

ログファイル容量の再利用

tempdb のログファイル容量が大きくなった場合、通常は長時間実行トランザクションがログの切り捨てを妨げていることが原因です。次のように容量を再利用できます:

  1. sys.databaselog_reuse_wait_desc フィールドでログ再利用待機タイプを確認します。ログ再利用待機タイプが ACTIVE_TRANSACTION の場合、長時間実行トランザクションが存在します。

  2. tempdb データベースで実行されている長時間実行トランザクションを特定します。長時間実行トランザクションを終了した後、SHRINKFILE を使用してログファイルを圧縮できます。

次のソリューションを使用して、tempdb ログファイルの容量使用率を分析できます:

  1. まず、データベースログファイルの状態を確認します。

    実行結果で、tempdb ログ容量の状態を確認します。LogReuseWaitDescriptionNOTHING の場合、SHRINKFILE で直接ログファイルを圧縮できます。値が NOTHING でない場合、たとえば一般的な値である ACTIVE_TRANSACTION の場合、アクティブな長時間実行トランザクションが存在します。ログファイルを SHRINKFILE で圧縮する前に、長時間実行トランザクションを終了する必要があります。

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

    image

  2. Tempdb ログファイルの増加は、多くの場合、アクティブな長時間実行トランザクションによって引き起こされます。次の SQL コマンドを使用して、tempdb データベースで最も長く実行されているトランザクションを確認し、それを終了するかどうかを決定できます:

    USE tempdb;
    GO
    DBCC OPENTRAN;
    GO

    次の図に示すように、セッション ID (SPID) とトランザクション開始時刻 (Start time) に注意してください:

    image

  3. 次に、セッションが何をしているか、その状態を確認できます。前のステップのセッション ID を使用できます:

    SELECT * FROM sys.sysprocesses WHERE spid = xxx;--spid は前のステップの SPID です

    例:

    image

  4. セッションのステータスが sleeping の場合、次の SQL コマンドを使用して実行された文を確認できます:

    DBCC INPUTBUFFER(xxx);  --xxx は前のステップのセッション ID (spid) です

    次の図に例を示します。

    image

その他のファイル容量の再利用

原因の分析

その他のファイル容量とは、sqlserver.other_sizemastersizemodelsizemsdbsize などのファイルが占有する容量を指します。これらのファイルは通常小さいですが、場合によっては非常に大きくなることがあります。例:

  • 多くのエラーログ (errorlog) があり、エラーログファイルのサイズが数ギガバイト、あるいはそれ以上に増加する。

  • 重大な例外が発生した際に、メモリダンプファイルが自動的に生成される。

ソリューション

  1. RDS インスタンスの [モニタリングとアラート] ページの [標準モニタリング] タブに移動して、これらのファイルが占有する容量を表示します。メトリックの詳細については、「標準モニタリングの表示」をご参照ください。

    image

  2. errorlog が大量の容量を占有している場合は、[ログ管理] ページに移動してエラーログをクリアできます。詳細については、「ログの管理」をご参照ください。

    説明

    sqlserver.other_size などの他のファイルが過剰な容量を占有している場合は、テクニカルサポートにお問い合わせください。原因の特定と問題の解決を支援します。

ストレージ容量のスケールアウト

RDS インスタンスの容量使用率が高く、上記の方法で効果的に削減できない場合は、速やかにインスタンスのストレージ容量をスケールアウトする必要があります。詳細については、「インスタンスの仕様変更」をご参照ください。