こんにちは。テクニカルサポート課の森本です。
お客様からお問い合わせをいただく中で、RDS の DB スナップショットにはいつ時点のデータが含まれるのか聞かれることがあり、検証してみました。
DB スナップショットについておさらい
DB インスタンスのスナップショットは DB インスタンスストレージのスナップショットです。 つまり、スナップショット取得時点で DB インスタンスのダーティメモリ等にのみ存在するデータ(トランザクション途中の未コミットデータ等)は含まれず、 コミットが完了している(ストレージに永続化されている)状態のデータが含まれることが期待されます。
Amazon RDS は DB インスタンスのストレージボリュームのスナップショットを作成し、個々のデータベースだけではなく、その DB インスタンス全体をバックアップします。
シングル AZ DB インスタンスの DB スナップショットの作成 - Amazon Relational Database Service
トランザクション途中に取得したスナップショットに未コミットのデータが含まれないことについて検証されている外部記事はたくさん存在するので、今回のブログでは割愛します。
検証
今回は、RDS for MySQL で検証を行います。 以下のように1秒毎に書き込みを行っている最中に DB スナップショットを取得し、取得した DB スナップショットを復元して中に含まれているデータを確認します。 なお、自動コミットは有効化されています。
$ for i in `seq 1 3600` ; do mysql -h xxx.xxx.ap-northeast-1.rds.amazonaws.com -u xxx -pxxx -e "insert into test.t1 values (now());" ; sleep 1 ; done
手動スナップショット
マネジメントコンソールから手動スナップショットを取得しました。 CloudTrailの CreateDBSnapshot API実行時間は以下のとおりでした。
CreateDBSnapshot (中略) "eventTime": "2024-09-11T06:13:26Z" (中略)
RDS イベントによる DB スナップショット取得開始と完了時間は以下のとおりです。
$ aws rds describe-events --source-type db-snapshot --source-identifier xxx --duration 20160; { "Events": [ { "SourceIdentifier": "xxx", "SourceType": "db-snapshot", "Message": "Creating manual snapshot", "EventCategories": [ "creation" ], "Date": "2024-09-11T06:13:52.677000+00:00", "SourceArn": "arn:aws:rds:ap-northeast-1:000000000000:snapshot:xxx" }, { "SourceIdentifier": "xxx", "SourceType": "db-snapshot", "Message": "Manual snapshot created", "EventCategories": [ "creation" ], "Date": "2024-09-11T06:15:15.421000+00:00", "SourceArn": "arn:aws:rds:ap-northeast-1:000000000000:snapshot:xxx" } ] }
また、DB スナップショットの取得開始時間は以下のとおりとなっており、API を実行した時間と RDS イベントのスナップショット取得開始イベントより後、RDSイベントのスナップショット取得完了イベントの前と、それぞれの時間とはずれがあることがわかります。
$ aws rds describe-db-snapshots --db-snapshot-identifier xxx (中略) "SnapshotCreateTime": "2024-09-11T06:14:03.573000+00:00" (中略)
復元した DB インスタンス上で SELECT クエリを発行した結果は以下です。 DB スナップショット取得開始時点(SnapshotCreateTime)までのデータが含まれていることがわかります。
mysql> select * from test.t1 order by snapshottime desc limit 1; +---------------------+ | snapshottime | +---------------------+ | 2024-09-11 06:14:03 | +---------------------+ 1 row in set (0.05 sec)
自動スナップショット
RDS イベントによる DB スナップショット取得開始と完了時間は以下のとおりです。
$ aws rds describe-events --source-type db-snapshot --source-identifier rds:xxx --duration 20160; { "Events": [ { "SourceIdentifier": "rds:xxx", "SourceType": "db-snapshot", "Message": "Creating automated snapshot", "EventCategories": [ "creation" ], "Date": "2024-09-12T07:08:18.310000+00:00", "SourceArn": "arn:aws:rds:ap-northeast-1:000000000000:snapshot:rds:xxx" }, { "SourceIdentifier": "rds:xxx", "SourceType": "db-snapshot", "Message": "Automated snapshot created", "EventCategories": [ "creation" ], "Date": "2024-09-12T07:10:01.163000+00:00", "SourceArn": "arn:aws:rds:ap-northeast-1:000000000000:snapshot:rds:xxx" } ] }
DB スナップショットの取得開始時間は以下のとおりです。上述の自動スナップショットの取得開始イベントと取得完了イベントの間のタイミングで取得が開始されていることがわかります。
$ aws rds describe-db-snapshots --db-snapshot-identifier xxx (中略) "SnapshotCreateTime": "2024-09-12T07:08:29.304000+00:00" (中略)
復元した DB インスタンス上で SELECT クエリを発行した結果 こちらも DB スナップショットの取得開始時点(SnapshotCreateTime)までのデータが含まれていることがわかります。
mysql> select * from test.t1 order by snapshottime desc limit 1; +---------------------+ | snapshottime | +---------------------+ | 2024-09-12 07:08:28 | +---------------------+ 1 row in set (0.01 sec)
(おまけ)特定時点までの復元(PiTR)を実行した場合
CloudTrail上のリクエストパラメータ
RestoreDBInstanceToPointInTime "requestParameters": { (中略) "restoreTime": "Sep 11, 2024 6:15:15 AM", (中略)
復元した DB インスタンス上で SELECT クエリを発行した結果 秒単位での復元が可能なことがわかります。
mysql> select * from test.t1 order by snapshottime desc limit 1; +---------------------+ | snapshottime | +---------------------+ | 2024-09-11 06:15:15 | +---------------------+ 1 row in set (0.04 sec)
まとめ
DB インスタンススナップショットにどの時点までのデータが含まれているかを確認する場合、対象のスナップショットの取得開始時間を確認すればよいことがわかりました。
なお、手動で CreateDBSnapshot API を実行した時間と内部的にスナップショットの取得が開始される時間にはずれが生じます(API実行が非同期で行われているため)。
厳密に特定の時点までのデータが含まれているスナップショットを作成したいというご要望の場合は、一度PiTRで復元した DB インスタンスからスナップショットを取得するとよさそうです。
(一方この場合、スナップショットに記録される取得時間(SnapshotCreateTime)と内部のデータの時間は必ずしも一致しないので、必要に応じてスナップショット名やタグ等でいつまでのデータ、と残しておくとよりよさそうです。)
この記事がどなたかの参考になれば幸いです。