こんにちは、インフラエンジニア の 加藤(@kuromitsu_ka)です。
今回は、Amazon Auroraのポイントインタイムリカバリ(特定時点へのリストア)を触ったので、記事を残します。
概要
Auroraのバックアップ保持期間内であれば、特定の時点のデータで、DBクラスタを作成できる機能があり、これが便利でした。
DBクラスタの作成にかかる時間と、DB作成時にどこまで正確にデータを復元できるか確認したので、そのまとめを記載します。
※手順の方は、ドキュメントに記載あるので割愛します。
ざっくりよかったこと
- バックアップ保持期間であれば、秒単位で指定した時点でDBクラスタを作成できる。
- 運用中のDBを切り戻すのでなくDBを新規作成するため、現行DBに手を加えなくて良い。
ちょっと細かいところ。
Auroraは、フルバックアップと合わせて、トランザクションデータも保存しています。
一番早くて、最新時間の5分前の時間で、DBクラスタを作成できる模様でした。
※切り戻せる時間の範囲については、describe-db-clusters から確認できます。
参考になる公式ドキュメント
検証したこと
ざっくり2つ確認しました。
(検証1)DBクラスタ再作成にかかる時間の計測
Auroraクラスタのステータスが、作成中から使用可能になるまでの時間を確認しました。
$ cat check.sh #!/bin/bash while true do echo $(date +"%Y%m%d %H:%M:%S";aws rds describe-db-clusters --db-cluster-identifier $1 | jq -r ".DBClusters[].Status") sleep 1 done
- 結果としては、以下のようになりました。 積んでいるデータが大きいと、そこそこ時間はかかりそうなものの、まぁ大丈夫かと。
データ | 所用時間 | インスタンスタイプ | データのサイズ |
---|---|---|---|
開発環境データ | 15分程度 | db.t3.small(vCPU:2,メモリ:2GiB) | 30GB |
本番環境データ | 27分程度 | db.r6g.4xlarge(vCPU:16,メモリ:128) | 160GB |
おまけの計測
Auroraのリストアも、フルバックからリストア後、差分適用してるのかな?と思い。
開発環境にて、フルバックアップ取得時間を軸に、ざっくり2パターンで検証しました。
結果として、特に大差はなかったです。
Auroraのフルバックアップ取得から、1時間経過した時点のデータでDB作成した場合
→約13分30秒Auroraのフルバックアップ取得より、1時間前(23時間経過した)の時点のデータでDB作成した場合
→約14分00秒
(検証2)切り戻し時点の前後のトランザクションデータの正確性の確認
切り戻したい時間帯に発生していたトランザクションのデータは、ちゃんと復元できるのか確認しました。
検証の結果
リストアでデータが正確に復元できないのは、リストアで指定する時間の前後1秒間にコミットされていないトランザクションだけでした。
具体的な検証方法
スクリプトでINSERT,UPDATEを流して、トランザクションを発生させました。
スクリプト実行中の時間を指定して、DBクラスタを作成して起動後のデータを確認しました。
検証ログ
データの追加時間・更新時間がわかるように、こんな感じのテーブルを作成してトランザクションを発生させました。
+------------+-------------+------+-----+-------------------+-----------------------------+ | Field | Type | Null | Key | Default | Extra | +------------+-------------+------+-----+-------------------+-----------------------------+ | id | int(11) | NO | PRI | NULL | | | comment | varchar(20) | YES | | NULL | | | created_at | timestamp | NO | | CURRENT_TIMESTAMP | | | updated_at | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP | +------------+-------------+------+-----+-------------------+-----------------------------+
- スクリプトのINSERT,UPDATE部分
外部のサーバから、任意の数のトランザクションを発生させるスクリプトです。
※DELETEも流していた時の名残もありますが、こちらはスルーでお願いします。
for i in $(seq ${NUMBER_OF_QUERIES_INSERT_and_UPDATE}) mysql -h $RDS -u${user} -p${password} -e "INSERT INTO ${TABLE_NAME} (id, comment) VALUES (${i},\"insert${i}\");" mysql -h $RDS -u${user} -p${password} -e "UPDATE ${TABLE_NAME} set comment=\"update${i}\" where id=${i};" # if [ ${i} -lt ${NUMBER_OF_QUERIES_DELETE} ] || [ ${i} -eq ${NUMBER_OF_QUERIES_DELETE} ]; then # mysql -h $RDS -u${user} -p${password} -e "DELETE FROM ${TABLE_NAME} WHERE id = ${i};" # fi done echo $(date "+%H:%M:%S") Script END >> ${STATUS_FILE}
- スクリプトの出力するステータスファイルから開始終了時間を確認
# cat /tmp/status.txt 2022-01-31 11:58:21 Script START 2022-01-31 21:52:14 Script END
- リストア後のテーブル
2021/01/31 21:51:59秒までのデータは、問題なく切り戻せていました。
mysql> select * from bm_messages.AWSNEXT_1215 ORDER BY id desc limit 5; +--------+--------------+---------------------+---------------------+ | id | comment | created_at | updated_at | +--------+--------------+---------------------+---------------------+ | 379369 | insert379369 | 2022-01-31 21:51:59 | 2022-01-31 21:51:59 | | 379368 | update379368 | 2022-01-31 21:51:59 | 2022-01-31 21:51:59 | | 379367 | update379367 | 2022-01-31 21:51:59 | 2022-01-31 21:51:59 | | 379366 | update379366 | 2022-01-31 21:51:59 | 2022-01-31 21:51:59 | | 379365 | update379365 | 2022-01-31 21:51:59 | 2022-01-31 21:51:59 | +--------+--------------+---------------------+---------------------+ 5 rows in set (0.01 sec)
感想
DBを切り戻すんじゃなくて、別途作成してくれるところがいいなぁって思いました!
株式会社エニグモ すべての求人一覧