Amazon Auroraのポイントインタイムリカバリ(特定時点へのリストア)を触りました。

こんにちは、インフラエンジニア の 加藤(@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 |
+------------+-------------+------+-----+-------------------+-----------------------------+

外部のサーバから、任意の数のトランザクションを発生させるスクリプトです。
※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

f:id:enigmo7:20220304153959p:plain

  • リストア後のテーブル
    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を切り戻すんじゃなくて、別途作成してくれるところがいいなぁって思いました!

株式会社エニグモ すべての求人一覧

hrmos.co