技術ぎじゅつ本部ほんぶ サービスリライアビリティグループ(SRG)の長谷川はせがわ @rarirureluis です。
#SRG(Service Reliability Group)は、おも弊社へいしゃメディアサービスのインフラまわりを横断おうだんてきにサポートしており、既存きそんサービスの改善かいぜん新規しんきげ、OSS貢献こうけんなどをおこなっているグループです。

また Amazon Aurora MySQL(以下いか:Aurora MySQL)のはなしです。なんでこんなに Aurora MySQL にかんする記事きじばっかいてるのかぼくかりません。

前回ぜんかいの Aurora MySQL のアップグレード方法ほうほうのベストプラクティスはこちらです。
RDS Graviton2 にすくないリスクでえる方法ほうほうかんがえてみる【アップグレードへん】 | CyberAgent Developers Blog

今回こんかいはバックアップについてです。

そのクラスター、間違まちがったクエリながしたときに直前ちょくぜんまでもどせますか?

たとえばテーブルを間違まちがえて DROP してしまったとき、DROP する直前ちょくぜんまでの状態じょうたいもどすことはできますか?
もしくは直前ちょくぜんまでもど方法ほうほうはドキュメントされていますか?

これは AWS などのパブリッククラウドにかぎったはなしではないのですが、フルバックアップだけをっていてもある特定とくていのクエリまでもどことはできません。
そこで必要ひつようになるのがバイナリログです。

最新さいしんのフルバックアップと、そのバックアップ以降いこうられたバイナリログさえあれば、特定とくていのクエリまで復元ふくげんすることができます。

 

バックトラックと、ポイントインタイムリカバリ

Aurora MySQL には復元ふくげんかんする機能きのうバックトラックポイントインタイムリカバリふた機能きのうがあります。

これらふたつの機能きのう特定とくていのクエリの時点じてん復元ふくげんするのではなく、日時にちじ指定してい復元ふくげんする機能きのうです。
そのため間違まちがったクエリの直前ちょくぜんまでもどすといったことはできません。

バックトラック

バックトラックは指定していした時間じかんまでクラスターをそのまま「もどす」機能きのうです。

バックトラックは最大さいだい72あいだまえまでもどすことができ、5.6.10a もしくは 2.06 以降いこうのバージョンで利用りよう可能かのうです。
バックトラックを有効ゆうこうにしてクラスターを作成さくせいする必要ひつようがあり、既存きそんのクラスターを有効ゆうこうすることはできません。

また、バックトラックを利用りようするのに $0.014 / 変更へんこうレコード 100まんけん発生はっせいします。
これが見積みつもれない場合ばあい、Web じょうでクラスターを作成さくせい変更へんこう)するさいいままでのワークロードからある程度ていど料金りょうきん表示ひょうじしてくれます。

t3.small で sysbench をながし 24あいだのターゲットバックトラックウィンドウを設定せっていした場合ばあい

Aurora DB クラスターのバックトラック – Amazon Aurora

ポイントインタイムリカバリ

ポイントインタイムリカバリはバックアップ保持ほじ期間きかんない特定とくてい時点じてんのクラスターをべつのクラスターとして作成さくせいする機能きのうです。
バックトラックとのは、既存きそんのクラスターか、あらたにつくるかのです。

特定とくてい時点じてんへの DB クラスターの復元ふくげん – Amazon Aurora

 

バイナリログの必要ひつようせい

バイナリログは特定とくていのクエリの直前ちょくぜんまで復元ふくげんする場合ばあい必須ひっすになります。

Aurora MySQL はデフォルトでバイナリログは保存ほぞんされません。

もし有効ゆうこうしていない場合ばあいは、間違まちがったクエリを発行はっこうした日時にちじ以前いぜん最新さいしんのスナップショット、もしくはバックトラック、ポイントインタイムリカバリから復元ふくげんするしか方法ほうほうがありません。(あいだちがったクエリの直前ちょくぜんまでもどすことができない)

バイナリログを有効ゆうこうしている場合ばあいデフォルトでは 24あいだ保存ほぞん期限きげんがあります。

バイナリログの有効ゆうこうはこちらをごらんください。
MySQL を実行じっこうする Amazon Aurora インスタンスのバイナリログを有効ゆうこうにする

binlog_format は MySQL 5.7 からデフォルトで ROW になったため、ROW がいとおもいます。一番いちばんあつかいやすいです。

 

バイナリログを有効ゆうこうするとみのパフォーマンスがちるらしい

公式こうしきドキュメントにも記載きさいされています。

ちゅう: Aurora MySQL 互換ごかん DB クラスターでバイナリログを有効ゆうこうにすると、パフォーマンスに以下いか影響えいきょうしょうじます。

  • 追加ついかみオーバーヘッドが発生はっせいする (必要ひつよう場合ばあいにのみ有効ゆうこうにしてください)
  • バイナリログのリカバリプロセスにより、さい起動きどうのエンジンの起動きどう時間じかんながくなる

Amazon Aurora MySQL 互換ごかん DB クラスターのバイナリログの保持ほじ期間きかんながくする

 

ベンチマーク

db.r6g.large(2.09.2) にたいして sysbench で oltp_write_only をながしてみます。コマンドは下記かきとおり 5分間ふんかんを 5かい実行じっこうした平均へいきんの TPS を計測けいそくします。

$ for i in {1..5}; do /usr/local/bin/sysbench --db-driver=mysql --mysql-host= --mysql-user= --mysql-password='' --mysql-db=benchmark oltp_write_only --threads=64 --time=300 run

バイナリログの ON_OFF による書き込みパフォーマンスの差 2.09.2

一般いっぱんてきにバイナリログが有効ゆうこうになるとパフォーマンスは劣化れっかしますが、それでも OFF にたいして 96.5%という結果けっかになりました。

5/25 にリリースされたエンジンバージョン 2.10.0 では比較ひかくしてみるとバイナリログが有効ゆうこう無効むこうがない結果けっかられました。

バイナリログの ON_OFF による書き込みパフォーマンスの差

2.10.0 以前いぜん使つかっていて 3.5% の性能せいのう劣化れっか無視むしできない場合ばあいは 2.0.0 へのアップグレードをオススメします。
アップグレードの方法ほうほう比較ひかくした記事きじをアップしているのでよろしければごらんください。
RDS Graviton2 にすくないリスクでえる方法ほうほうかんがえてみる【アップグレードへん】 | CyberAgent Developers Blog

 

バックアップと、バイナリログの保持ほじ期間きかん

クラスターの設定せっていてみると「バックアップの保持ほじ期間きかん」という項目こうもくがあります。
この保持ほじ期間きかんポイントインタイムリカバリを実行じっこうできる期間きかんまります。(バックトラックはまたべつ設定せっていにあります。> ターゲットバックトラックウィンドウ)

たとえば保持ほじ期間きかんがデフォルトの 1日間にちかんで、間違まちがったクエリをながしたことにづいたのが 3にちだった場合ばあい、バックアップ(ポイントインタイムリカバリ)でもどせるもっとふる日時にちじでもすで間違まちがったクエリが適用てきようされている状態じょうたいになってしまいます。

保持ほじ期間きかんどうするかは構むずかしいところですがぼくているところでは 7日間にちかんおおいです。

バイナリログの保持ほじ期間きかんはバイナリログを有効ゆうこうにするとデフォルトで 24あいだとなります。

この保持ほじ期間きかん間違まちがったクエリをながしたことにづいたのが 3にちだった場合ばあい

  • 現在げんざい運用うんようちゅうのクラスターにあるバイナリログは 1にちぶんしかない
  • ポイントインタイムリカバリまたは、バックトラックから 3にちまえ状態じょうたいもど
  • 3にちまえから現在げんざい(- 1にち)までのバイナリログが存在そんざいせず

という状況じょうきょうになり、もどせるのが 3にちまえとなり間違まちがったクエリをスキップして最新さいしん状態じょうたいまでもどすことができません。

じゃあどうすればいいかとわれればバックアップの保持ほじ期間きかんも、バイナリログの保持ほじ期間きかんも 7日間にちかんとしておけばとりあえずは安心あんしんではないでしょうか。

 

バイナリログの保持ほじ期間きかん

確認かくにん

mysql> call mysql.rds_show_configuration;
+------------------------+-------+------------------------------------------------------------------------------------------------------+
| name | value | description |
+------------------------+-------+------------------------------------------------------------------------------------------------------+
| binlog retention hours | NULL | binlog retention hours specifies the duration in hours before binary logs are automatically deleted. |
+------------------------+-------+------------------------------------------------------------------------------------------------------+

設定せってい

mysql> call mysql.rds_set_configuration('binlog retention hours', 168);
Query OK, 0 rows affected (0.05 sec)

 

 

実際じっさいにやってみる

DB が d1, d2 の2つがあり、d1.t1 には下記かきのレコードがはいってる状態じょうたいで d2 は DB のみが作成さくせいされている状況じょうきょうです。

Aurora MySQL のバックアップは本当にそれでいいのだろうか?

障害しょうがいきました

としましょう。

Aさんがサービスクリティカルなテーブル t1 を間違まちがえて DROP してしまいました。

mysql> DROP TABLE d1.t1;

じゅんって解決かいけつしていきます。

 

1. まずは DB へのみを停止ていしする

あいだちがったクエリの直前ちょくぜんもどすため、できるだけ更新こうしんされないように(ユーザー影響えいきょうちいさくするため)緊急きんきゅうメンテナンスをおこない、DB への更新こうしんはしらないようにします。

強制きょうせいてきにアプリからのみを停止ていしするには権限けんげん剥奪はくだつするのもアリですがあまりオススメしません。
理由りゆうは 3. で説明せつめいします。

mysql> REVOKE INSERT,UPDATE ON d1.* FROM app@'%'

 

2. バイナリログを救出きゅうしゅつする

バイナリログをローカルに保存ほぞんするには下記かきのスクリプトを参考さんこうにしてみてください。

 

3. クラスターを復元ふくげんする

最新さいしんのスナップショット、またはバックトラック、もしくはポイントインタイムリカバリであいだちがったクエリ以前いぜん時間じかん最新さいしんのを使用しようしてクラスターを復元ふくげんします。

DB へのみを禁止きんしにしたさい権限けんげん剥奪はくだつ方法ほうほうおこなった場合ばあいはバックトラックがわると権限けんげん剥奪はくだつまえ状態じょうたいもどってしまうためアプリやバッチをめていない場合ばあい更新こうしんされてしまいます。そのためどこから DB が参照さんしょうされよくからない状態じょうたい場合ばあいはバックトラックではなく、ポイントインタイムリカバリで復元ふくげんするのがいかとおもいます。(バックトラックはそのクラスターをもとにもどす、ポイントインタイムリカバリはあたらしくクラスターが作成さくせいされるためです)

バックトラックについてはこちらが参考さんこうになります。
Aurora MySQL のバックトラック機能きのう使つかってDROP DATABASEをなかったことにしてみた | DevelopersIO
Aurora MySQL 5.7 でポイントインタイムリカバリをやってみた | DevelopersIO

 

4. 復元ふくげんしたクラスターの現在げんざいのポジションを確認かくにんする

Aurora MySQL のバックアップは本当にそれでいいのだろうか?

バックトラックから復元ふくげんした DB には d2 はない状態じょうたいです。

 

mysql> show binary logs;
+----------------------------+-----------+
| Log_name | File_size |
+----------------------------+-----------+
| mysql-bin-changelog.000002 | 154 |
| mysql-bin-changelog.000003 | 154 |
+----------------------------+-----------+
2 rows in set (0.01 sec)

show binary logs復元ふくげんされたクラスターの現在げんざいのバイナリログのポジションを確認かくにんしておきます。

 

5. 救出きゅうしゅつしたバイナリログから間違まちがったクエリのポジションを調しらべる

2. バイナリログを救出きゅうしゅつする救出きゅうしゅつしたバイナリログを調しらべます。

$ mysqlbinlog --base64-output=DECODE-ROWS -vv mysql-bin-changelog.000004

Aurora MySQL のバックアップは本当にそれでいいのだろうか?

4. 復元ふくげんしたクラスターの現在げんざいのポジションを確認かくにんするmysql-bin-changelog.000003 154 まで適用てきようされていることが確認かくにんできています。
抽出ちゅうしゅつしたバイナリログをてみると 372間違まちがったクエリをながしていることがかります。

 

6. 救出きゅうしゅつしたバイナリログから復元ふくげんおこな

下記かきのコマンドを実行じっこうし、4. 復元ふくげんしたクラスターの現在げんざいのポジションを確認かくにんする のポジションから、5. 救出きゅうしゅつしたバイナリログから間違まちがったクエリのポジションを調しらべる のポジションあいだのバイナリログを作成さくせいします。

$ mysqlbinlog --start-position=154 --stop-position=372 --skip-gtids -vv --base64-output=DECODE-ROWS mysql-bin-changelog.000004 > recovery.sql

 

復元ふくげんしたバイナリログの中身なかみ確認かくにんし、間違まちがったクエリが反映はんえいされていないことを確認かくにんします。

Aurora MySQL のバックアップは本当にそれでいいのだろうか?

RDS では一部いちぶ権限けんげん問題もんだい上記じょうき作成さくせいしたバイナリログは実行じっこうできません。
今回こんかい下記かき箇所かしょ削除さくじょする必要ひつようがありました。

Aurora MySQL のバックアップは本当にそれでいいのだろうか?

下記かきのコマンドで実際じっさい適用てきようします。

$ mysql -h hoge.cluster-random.ap-northeast-1.rds.amazonaws.com -uroot -p < recovery.sql

 

適用てきよう確認かくにんしてみるとしてしまった d1.t1 テーブルと、d2 データベースがあるのが確認かくにんできます。

Aurora MySQL のバックアップは本当にそれでいいのだろうか?

まとめ

今回こんかいも Aurora MySQL にかんする記事きじでした。

バイナリログから復元ふくげんする一連いちれんながれを予習よしゅうしておくと必要ひつようになったときにあせらずに対応たいおうすることができるのでみなさんもぜひ!

(コマンドが <code></code> だったり画像がぞうだったりしてにくかったかとおもいますが、セキュリティにっかかっちゃうのでこんなかんじになってしまいました。)