giip
SES Proposal
SQL ServerIOPSストレージEBSCDCログファイル移行コスト

Causes and Countermeasures for Disk I/O Performance Degradation After Migrating an On-Premises SQL Server to AWS

公開日 2026-09-07 · 更新日 2026-09-07 · 最終検証日 2026-09-07

結論

On-premises physical servers use PCIe bus-attached local NVMe/SSD with extremely low latency and high I/O throughput, but Amazon EBS, the standard for AWS RDS/EC2, is a virtual block storage attached via network, with IOPS and throughput strictly throttled according to instance size and volume type. Without understanding this difference, batches and index rebuilds stall due to throttling even when CPU headroom exists, and oversizing Provisioned IOPS only increases costs without addressing the root cause. The basic approach is to reduce the volume of disk I/O itself, with buffer pool maximization, data compression, physical separation of data and log files, and addressing CDC cleanup delays causing log bloat as the practical center of these efforts.

この文書の適用条件

対象製品SQL Server (Amazon RDS for SQL Server / SQL Server on EC2)
確認バージョンSQL Server 2012 and later (CDC-supported editions vary by version; verify)
適用環境AWS migration from on-premises physical servers (Amazon RDS for SQL Server, EC2)
必要権限Read-only commands require VIEW DATABASE STATE or equivalent. db_owner (or sysadmin depending on environment) for manually running sys.sp_cdc_cleanup_job and executing DBCC SHRINKFILE
実行影響Read-only commands only query. sp_cdc_cleanup_job deletes CDC change data; DBCC SHRINKFILE changes log file size
再起動Not required
最終検証日2026-09-07

そのまま実行できるコマンド

Estimate space reduction from compressing existing tables参照のみ
対象
SQL Server 2008 or later / Amazon RDS for SQL Server
権限
reference permission on the target table (execute permission for sp_estimate_data_compression_savings)
変更作業
none (estimate only, does not perform actual compression)
Production実行
allowed
-- Target: SQL Server 2008 or later / Amazon RDS for SQL Server
-- Permission: reference permission on the target table (execute permission for sp_estimate_data_compression_savings)
-- Change: none (estimate only, does not perform actual compression)
-- Production execution: allowed
USE [SampleDB];
GO
EXEC sys.sp_estimate_data_compression_savings
    @schema_name = 'dbo',
    @object_name = 'Orders',
    @index_id = NULL,
    @partition_number = NULL,
    @data_compression = 'PAGE';

The difference between size_with_current_compression_setting and size_with_requested_compression_setting in the results indicates the estimated disk space reduction from compression. Compression reduces disk I/O at the cost of CPU overhead, so it is more effective in environments with CPU headroom.

Identify why the log is not being truncated (check log_reuse_wait_desc)参照のみ
対象
SQL Server 2008 or later / Amazon RDS for SQL Server
権限
metadata visibility on sys.databases
変更作業
none (read-only)
Production実行
allowed
-- Target: SQL Server 2008 or later / Amazon RDS for SQL Server
-- Permission: metadata visibility on sys.databases
-- Change: none (read-only)
-- Production execution: allowed
SELECT name, log_reuse_wait_desc
FROM sys.databases
WHERE name = 'SampleDB';
-- If the result is 'REPLICATION', CDC or transactional replication is holding unread logs

REPLICATION can apply to both CDC and transactional replication. Check whether CDC is enabled on the target database with sys.databases.is_cdc_enabled. For details on tracking capture delays, see "How to check whether the CDC log scan has stopped in SQL Server".

Manually execute CDC cleanup (purge change data beyond retention period)
対象
SQL Server 2008 or later (CDC-supported editions) / Amazon RDS for SQL Server
権限
db_owner (execute permission for cdc.sp_cdc_cleanup_job)
変更作業
yes (deletes data from CDC change tables beyond the retention period)
Production実行
allowed, but verify that downstream integrations are not still consuming the data to be deleted
-- Target: SQL Server 2008 or later (CDC-supported editions) / Amazon RDS for SQL Server
-- Permission: db_owner (execute permission for cdc.sp_cdc_cleanup_job)
-- Change: yes (deletes data from CDC change tables beyond the retention period)
-- Production execution: allowed, but verify that downstream integrations are not still consuming the data to be deleted
USE [SampleDB];
GO
EXEC sys.sp_cdc_cleanup_job;

This is an immediate workaround when the scheduled cleanup job is delayed. However, this addresses the symptom, not why the cleanup job itself became delayed (job stoppage, insufficient runtime, etc.) — investigate separately. Before executing, always confirm that replication targets or downstream ETL processes have not yet read change data within the retention period.

Shrink the transaction log (execute after cleanup completes)
対象
SQL Server 2008 or later / Amazon RDS for SQL Server
権限
sysadmin or db_owner
変更作業
yes (truncates the end of the log file to reduce its size)
Production実行
generally allowed, but only after confirming log_reuse_wait_desc is NOTHING
-- Target: SQL Server 2008 or later / Amazon RDS for SQL Server
-- Permission: sysadmin or db_owner
-- Change: yes (truncates the end of the log file to reduce its size)
-- Production execution: generally allowed, but only after confirming log_reuse_wait_desc is NOTHING
USE [SampleDB];
GO
-- specify target size in MB to shrink to
DBCC SHRINKFILE (N'SampleDB_log', 1024);

Shrinking before resolving the log_reuse_wait_desc cause will result in immediate re-expansion. In this knowledge base, all SHRINK operations are marked as "high" regardless of impact level. For the difference between data file and log file shrinking and how to use TRUNCATEONLY, see "The difference between DBCC SHRINKDATABASE and DBCC SHRINKFILE, and what to check before running them".

結果の読み方

意味確認するポイント
log_reuse_wait_descReason why transaction log space is not being released'REPLICATION' indicates CDC or transactional replication is holding unread logs. 'NOTHING' means there is no factor preventing release
size_with_requested_compression_settingEstimated size after applying the specified compression typeThe larger the difference from the current size, the greater the potential for disk I/O reduction and storage cost savings

こういう状況で使います

  • Nightly batches and index rebuilds take two or more times longer, even with an AWS instance of equivalent or higher spec than the on-premises server before migration
  • The entire database becomes temporarily unresponsive during large-scale data loads or index rebuilds
  • Batches never complete despite CPU having available capacity
  • Storage capacity sharply depletes shortly after migration, triggering frequent RDS auto-storage scaling
  • Increasing Provisioned IOPS (io2, etc.) only drives up storage costs without achieving fundamental improvement

考えられる原因(可能性の高い順)

  1. 01

    Latency inherent to network-attached storage (EBS)

    On-premises physical NVMe/SSD is directly attached via the PCIe bus and operates with microsecond-level latency, but Amazon EBS, the standard for AWS RDS/EC2, is a virtual block storage connected to the instance via a dedicated internal network link. Physical latency (in the order of milliseconds) is structurally unavoidable.

  2. 02

    IOPS and throughput throttling (bandwidth limiting)

    IOPS and throughput (MB/s) limits per second are strictly defined according to instance size, volume type, and allocated capacity. General-purpose volumes such as gp2/gp3 consume burst credits when exceeding the baseline performance, and reaching limits during large-scale data loads or index rebuilds causes severe throttling that can make the entire DB unresponsive. Even raising volume-side IOPS with io2 or similar may be bottlenecked by the instance-side EBS dedicated bandwidth (EBS-Optimized).

  3. 03

    Cost inflation from oversizing Provisioned IOPS

    When attempting to easily resolve insufficient I/O performance by heavily provisioning high-cost IOPS types such as io2/io2 Block Express, storage costs alone can balloon to hundreds of thousands to millions of yen per month, eliminating the cost-reduction benefits of cloud migration.

  4. 04

    Unreleased logs due to CDC cleanup job delay

    When large batch updates occur and the CDC cleanup job cannot keep up, the transaction log is marked as "not yet read by CDC," preventing log space from being released even after CHECKPOINT or log backups. The log file continues auto-extending, depleting storage capacity and forcing RDS auto-storage scaling to trigger.

確認手順

  1. 1

    Estimate compression space reduction for existing tables

    参照のみ

    Use sys.sp_estimate_data_compression_savings to determine how much disk I/O reduction and storage cost savings potential exists.

  2. 2

    Identify the cause of unreleased logs with log_reuse_wait_desc

    参照のみ

    Check whether sys.databases.log_reuse_wait_desc is fixed at REPLICATION. If so, CDC or transactional replication delay is suspected.

  3. 3

    Check whether CDC is enabled and if capture is delayed

    参照のみ

    Verify CDC status with sys.databases.is_cdc_enabled. If enabled, check capture delay with sys.dm_cdc_log_scan_sessions (see the related article for details).

  4. 4

    Verify EBS volume and instance IOPS/throughput contracted values

    参照のみ

    Check the provisioned IOPS and throughput for the volume type (gp3/io2, etc.) and the EBS bandwidth limit on the instance side via the AWS console or CLI.

  5. 5

    Manually execute CDC cleanup

    After confirming that downstream integrations have consumed all data within the retention period, execute sys.sp_cdc_cleanup_job to restore the log to a releasable state.

  6. 6

    Shrink the transaction log

    After confirming log_reuse_wait_desc is NOTHING, shrink the log file to the target size using DBCC SHRINKFILE.

対応方法

すぐに実施できる低リスクの対応

  • Maximize the buffer pool to reduce disk reads

    Before paying to increase storage IOPS, scale up the instance size to increase RAM and maximize the SQL Server buffer pool size. Maintaining a state where frequently accessed active data remains cached in memory greatly alleviates the EBS I/O bottleneck.

  • Manually execute CDC cleanup to clear unreleased logs

    Execute sys.sp_cdc_cleanup_job without waiting for the scheduled job, restoring the log to a releasable state. Verify downstream integrations have consumed the data before executing.

事前検討が必要な変更

  • Separate data files and log files onto different EBS volumes

    Mixing data files (random I/O dominant) and transaction logs (sequential writes dominant) on the same EBS volume causes I/O queue contention. Always separate them onto different EBS volumes.

  • Apply PAGE/ROW compression to reduce I/O volume

    When CPU resources are available, data compression reduces the block size read from disk and the size written to the log. Estimate the effect with sp_estimate_data_compression_savings before applying.

  • Offload read load with a read replica

    If reporting queries and batch reads are straining the primary DB I/O bandwidth, build a read-only replica to distribute traffic.

  • Add CDC cleanup job lag to monitoring

    Monitor the success/failure and duration of the cleanup job to detect before the delay becomes chronic.

再起動・サービス影響を伴う変更

  • Shrink the transaction log with DBCC SHRINKFILE

    Execute after confirming log_reuse_wait_desc is NOTHING. Shrinking without resolving the cause will result in immediate re-expansion. The operation consumes I/O during execution, slowing writes to the target.

専門家のレビューが必要な作業

  • Redesign the need for Provisioned IOPS (io2, etc.) across the entire workload

    専門家レビュー必須

    Consider this only when IOPS remain insufficient even after buffer pool maximization, data compression, and file separation. Unplanned increases significantly raise monthly costs — have the I/O pattern of the entire workload analyzed and undergo professional review.

!注意事項

  • Before running DBCC SHRINKFILE, confirm that log_reuse_wait_desc is NOTHING. Shrinking while the cause remains will result in immediate re-expansion.
  • Before deleting CDC change data beyond the retention period with sys.sp_cdc_cleanup_job, verify that downstream integrations (replication targets or ETL) have not yet consumed data from that period.
  • Before casually increasing Provisioned IOPS (io2, etc.), first evaluate whether reducing disk I/O itself through buffer pool maximization and data compression is feasible.
  • The compression ratios and cost savings figures in this article depend on the workload and data content and are not guaranteed for all environments.

これで解決しない場合に確認すること

  • Have you checked whether EBS volume IOPS/throughput burst credits are exhausted?

    Verify that gp2/gp3 burst credit balance has not been depleted using CloudWatch metrics.

  • Have you checked whether the instance-side EBS bandwidth (EBS-Optimized) is the bottleneck?

    Even raising volume-side IOPS will not produce expected performance if the instance EBS dedicated bandwidth limit has been reached.

  • Have you checked the CDC cleanup job execution history and errors?

    Verify that the cleanup job regularly succeeds and that there are no consecutive failures or skips in the job history.

  • Have you measured network latency including whether AWS Direct Connect is needed?

    Verify that communication latency between on-premises remaining applications and the DB on AWS is not another bottleneck.

この文書の根拠と限界

実運用で確認した内容

This article generalizes Amazon EBS IOPS/throughput specifications, SQL Server CDC and DBCC SHRINKFILE public specifications, and trends commonly observed across multiple similar migration cases. Specific numerical values for compression ratios and cost savings are environment-dependent estimates and do not include specific customer examples or internal issue numbers.

よくある質問

Is slow disk I/O after AWS migration always an instance sizing mistake?

Not necessarily. On-premises physical NVMe/SSD and AWS network-attached storage (EBS) have fundamentally different structures, and even selecting an equivalent-spec instance results in performance limits due to IOPS and throughput throttling. First consider designs that account for this structural difference: buffer pool maximization, file separation, and compression.

Does increasing Provisioned IOPS (io2, etc.) solve the problem?

It may solve the problem in some cases, but costs tend to escalate rapidly. We recommend first maximizing the buffer pool to reduce disk reads, then reducing I/O volume with data compression, and only considering IOPS increases if those measures are still insufficient.

Is the same response appropriate when log files are enlarging even though CDC is not in use?

log_reuse_wait_desc becoming REPLICATION can apply to both CDC and transactional replication. First check whether CDC is enabled with sys.databases.is_cdc_enabled. If CDC is not in use, refer to the transaction replication configuration or general log file usage verification procedures.

When is it safe to run DBCC SHRINKFILE?

When log_reuse_wait_desc has become NOTHING. If CDC cleanup delay is the cause, first execute sys.sp_cdc_cleanup_job to make the log releasable. Data file shrinking and log file shrinking have different impacts, so review the related articles before proceeding.

この文書がカバーする質問

  • I want to know the cause of slowdown after migrating on-premises SQL Server to AWS
  • I want to know why storage costs surged after AWS migration
  • I want to know how to handle log files that keep growing due to CDC

リスク表示の意味

  • 参照のみデータと設定を変更しません。
  • 影響は限定的ですが、権限と負荷の確認が必要です。
  • 性能・ロック・コストに影響する可能性があります。
  • 障害・データ損失・復旧作業が発生する可能性があります。
  • 専門家レビュー必須本番適用前に別途レビューが必須です。

GIIPの対応範囲

Alerts based solely on resource threshold values such as "Disk I/O exceeds 90%" cannot reveal which queries or processes are causing the I/O pressure or how much unnecessary cost is actually being incurred per month. GIIP retains storage I/O, IOPS consumption, CDC cleanup job execution status, and log file changes in the same time series, enabling root causes to be identified on a cost ($) basis. Decisions that are irreversible and high-cost, such as Provisioned IOPS increases, are operated on the basis of having a human confirm the SQL and rollback procedures to be executed beforehand.

執筆・技術検証

GIIP プロダクション運用チーム

大規模Webサービス、SQL Server、Oracle、AWS、Azureの設計・移行・運用に約30年従事。x12largeクラスのAWS RDS for SQL Server環境12セット、約12万テーブルのOracle環境、約3TBのTiDBからAurora MySQLへの移行を経験。現在も複数のクラウドデータベースと約30のWebサービスを、AIエージェントと人間の専門家が継続的に監視・運用しています。

関連サービス

Diagnose disk I/O performance after an AWS migration

同じ確認を複数の環境で継続する必要がある場合は、運用体制ごと相談できます。

Diagnose disk I/O performance after an AWS migration

ナレッジベース一覧へ