Aurora MySQLのストレージ使用量を正しく理解する3つの視点
「なんでこんなにストレージ使用量が増えているんだろう?」Aurora MySQLを運用していると、一度は感じたことがある疑問ではないでしょうか。従来のRDS MySQLとは異なるアーキテクチャを持つAuroraでは、ストレージの仕組みを正しく理解していないと、予期しないコスト増加やパフォーマンス問題に悩まされることがあります。この記事では、Aurora MySQLのストレージ構造を3つの視点から徹底解説します。
Auroraのストレージは「共有」がキーワード
Aurora MySQLを理解する上で最も重要なのは、クラスタ内のすべてのインスタンスが単一の分散ストレージを共有しているという点です。この「共有ストレージ」というアーキテクチャが、Auroraの高可用性と高性能を支える基盤となっています。

従来のRDSでは、プライマリとレプリカがそれぞれ独立したEBSボリュームを持ち、レプリケーションによってデータを同期していました。これに対してAuroraでは、ストレージレイヤーが完全に分離されており、コンピュートノードとストレージノードが独立してスケールできます。
この共有ストレージは、3つのアベイラビリティゾーンにまたがって6つのコピーが自動的に作成されます。書き込みは4/6のクォーラムで確認され、読み取りは3/6で成功します。この設計により、最大2つのコピーが失われても読み取りは継続し、最大3つのコピーが失われても書き込みは継続できます。
視点1:クラスタボリュームの使用量を把握する
Aurora MySQLのストレージ使用量を理解する最初の視点は「クラスタボリューム」です。これはクラスタ全体で共有されるストレージであり、テーブルデータ、インデックス、システムテーブル、Undoログなどが格納されます。CloudWatchメトリクスのVolumeBytesUsedで監視できます。

import { CloudWatchClient, GetMetricStatisticsCommand } from "@aws-sdk/client-cloudwatch";
interface StorageMetrics {
volumeBytesUsed: number;
volumeReadIOPs: number;
volumeWriteIOPs: number;
}
async function getAuroraStorageMetrics(clusterIdentifier: string): Promise {
const client = new CloudWatchClient({ region: "ap-northeast-1" });
const command = new GetMetricStatisticsCommand({
Namespace: "AWS/RDS",
MetricName: "VolumeBytesUsed",
Dimensions: [{ Name: "DBClusterIdentifier", Value: clusterIdentifier }],
StartTime: new Date(Date.now() - 3600 * 1000), // 過去1時間
EndTime: new Date(),
Period: 300, // 5分間隔
Statistics: ["Average", "Maximum"]
});
const response = await client.send(command);
const latestDatapoint = response.Datapoints?.sort(
(a, b) => (b.Timestamp?.getTime() || 0) - (a.Timestamp?.getTime() || 0)
)[0];
return {
volumeBytesUsed: latestDatapoint?.Average || 0,
volumeReadIOPs: 0,
volumeWriteIOPs: 0
};
}注意すべきは、VolumeBytesUsedがリアルタイムではなく若干のラグがあることです。大量のデータを削除した直後でも、すぐには反映されません。また、Auroraのストレージは10GBから128TBまで自動的にスケールしますが、縮小は自動では行われません。
視点2:インスタンスローカルストレージの存在
見落とされがちですが、各Auroraインスタンスには「ローカルストレージ」も存在します。これはインスタンスに直接アタッチされたストレージで、一時テーブル、ソートバッファ、クエリキャッシュなどがここに格納されます。
ローカルストレージの使用量はFreeLocalStorageメトリクスで監視できます。複雑なJOINやソートを伴うクエリを実行すると、このローカルストレージが急速に消費されることがあります。ローカルストレージが枯渇すると、クエリがエラーになったり、インスタンスの動作が不安定になる可能性があります。
インスタンスクラスによってローカルストレージのサイズは異なります。db.r5.largeでは約20GB、db.r5.4xlargeでは約80GB程度が利用可能です。大規模なテンポラリテーブルを作成するワークロードでは、より大きなインスタンスクラスの選択が必要になることがあります。
視点3:バイナリログとバックアップ保持期間
3つ目の視点は、バイナリログとバックアップの保持設定です。Auroraでは、ポイントインタイムリカバリ(PITR)を実現するためにバイナリログが保持されます。バックアップ保持期間を長く設定すればするほど、バイナリログの保持量も増加し、ストレージコストに影響を与えます。
デフォルトのバックアップ保持期間は1日ですが、多くの本番環境では7日〜35日に設定されています。書き込みが多いワークロードでは、バイナリログだけで数百GBに達することもあります。コスト最適化のためには、ビジネス要件とコンプライアンス要件を満たす最小限の保持期間を設定することが重要です。
また、aurora_binlog_replication_max_yield_secondsパラメータを調整することで、バイナリログの書き込み頻度を最適化できます。ただし、これはレプリケーション遅延とのトレードオフになるため、慎重な検討が必要です。
ストレージコスト最適化のベストプラクティス
Aurora MySQLのストレージコストを最適化するためのベストプラクティスをいくつか紹介します。まず、不要なインデックスを定期的に見直すことです。使用されていないインデックスはストレージを消費するだけでなく、書き込みパフォーマンスにも影響を与えます。
次に、パーティショニングの活用です。時系列データなど、古いデータを定期的に削除するワークロードでは、パーティションのDROPにより効率的にストレージを解放できます。通常のDELETE文では、削除されたスペースは再利用されますが、ストレージ使用量としてはすぐには減少しません。
最後に、Aurora I/O-Optimizedの検討です。I/O コストが高いワークロードでは、I/O-Optimized設定により、I/O料金が不要になる代わりにストレージ単価が上がります。ワークロードのI/O特性を分析した上で、どちらが有利か検討してください。
まとめ
Aurora MySQLのストレージ使用量を正しく理解するには、クラスタボリューム、インスタンスローカルストレージ、バイナリログの3つの視点が重要です。それぞれが異なる性質を持ち、異なる方法で監視・最適化する必要があります。CloudWatchメトリクスを活用した継続的な監視と、定期的な最適化レビューにより、健全なストレージ管理とコスト効率の両立を実現しましょう。特に本番環境では、突発的なストレージ増加に備えたアラート設定も欠かせません。














