Azure Database for MySQLのリストア検証のお時間です。
Azure Database for MySQLのリストア前提
Azure Database for MySQLにおいては、データベースのバックアップは自動的に取得されます。 ユーザとして、このバックアップにはアクセスできず、リストアのみ可能というのが仕様です。
これらのバックアップ ファイルはユーザーに公開されておらず、エクスポートできません。 これらのバックアップは、Azure Database for MySQLの復元操作にのみ使用できます
Azure Database for MySQLでは、このバックアップを利用して以下の2種類のリストアが可能です。
- ポイントインタイムリストア
- Geoリストア
ポイントインタイムリストアは、元のサーバが存在するリージョンに、その名の通り指定した日時のデータベースの状態に復旧できるリストアです。 バックアップ保有期間は7〜35日(ユーザが指定可能)で、そこまでの日時に対してはポイントインタイムリストアが可能です。
一方でGeoリストアは、別のリージョンにデータベースを復旧するリストアです。 Geoリストアの目的はリージョン障害からの復帰であるため、指定日時の状態ではなく、最新バックアップの状態に復旧します。
準備
というわけで、まずはリストア対象のMySQLサーバーを用意します。
まずはリストア対象のテーブルが必要ですので、以下のような雑なテーブルを用意しました。
いずれも、Now()
で現在時刻をinsertしています。
mysql> select * from hoge.mydb; +---------------------+ | dt | +---------------------+ | 2021-07-31 15:33:22 | | 2021-07-31 15:33:40 | | 2021-07-31 15:33:46 | | 2021-07-31 15:39:22 | | 2021-07-31 15:43:19 | | 2021-07-31 15:46:56 | | 2021-07-31 15:49:59 | | 2021-07-31 15:50:54 | | 2021-07-31 15:53:20 | | 2021-07-31 16:52:31 | | 2021-07-31 16:52:32 | | 2021-07-31 16:52:33 | +---------------------+
PointInTimeRestore
7/31 15:50:00をターゲットにポイントインタイムリストアを実施してみましょう。 想定している結果は、リストア後のMySQLサーバーに15:50までのデータが存在しており、15:50以降のデータが存在していないことです。
azurerm_mysql_server
には、リストアに直接関連する設定として以下の3つがあります。
create_mode
: どのような形でリストアを行うのかを指定するrestore_point_in_time
: ポイントインタイムリストアの場合、リストアの対象日時を指定するcreation_source_server_id
: リストア元となる既存のMySQLサーバのIDを指定する
Terraformで指定すると、おおよそ以下のような形になるでしょう。
restore_point_in_time
はRFC 3339形式を解釈するため、タイムゾーンの指定が可能です。
server_name = "kiririmode-mysql-restore" (snip) create_mode = "PointInTimeRestore" restore_point_in_time = "2021-07-31T15:50:00+09:00" creation_source_server_id = module.mysql.id
これでTerraformをapplyすると、バックアップからリストアが実行され、新しいMySQLサーバーが立ち上がります。 この「新しい」というところがポイントで、リストア後に構築されるMySQLサーバーは、既存のMySQLサーバーとは別インスタンスです。 アプリケーションが接続先のデータベースを切り替えるためには、何らかの仕掛けが必要でしょう。
リストア後、実際にmysqlでクエリを投げてみました。以下の通り、15:50までのデータしか入っておらず、 想定通りのポイントインタイムリストアが実行できているようです。
$ mysql -h kiririmode-mysql-restore.mysql.database.azure.com -u 'kiririmode@kiririmode-mysql-restore' -p mysql> select * from hoge.mydb; +---------------------+ | dt | +---------------------+ | 2021-07-31 15:33:22 | | 2021-07-31 15:33:40 | | 2021-07-31 15:33:46 | | 2021-07-31 15:39:22 | | 2021-07-31 15:43:19 | | 2021-07-31 15:46:56 | | 2021-07-31 15:49:59 | +---------------------+ 7 rows in set (0.03 sec)
Geoリストア
では、Geoリストアも実施してみましょう。 Geoリストアの場合は、指定日時という概念がなく、最新バックアップからのリストアになります。 このため、指定はPointInTimeRestoreよりはシンプルです。
server_name = "kiririmode-mysql-georestore" (snip) create_mode = "GeoRestore" creation_source_server_id = module.mysql.id
最新のデータまで復元されていました。
$ mysql -h kiririmode-mysql-georestore.mysql.database.azure.com -u 'kiririmode@kiririmode-mysql-georestore' -p mysql> select * from hoge.mydb; +---------------------+ | dt | +---------------------+ | 2021-07-31 15:33:22 | | 2021-07-31 15:33:40 | | 2021-07-31 15:33:46 | | 2021-07-31 15:39:22 | | 2021-07-31 15:43:19 | | 2021-07-31 15:46:56 | | 2021-07-31 15:49:59 | | 2021-07-31 15:50:54 | | 2021-07-31 15:53:20 | | 2021-07-31 16:52:31 | | 2021-07-31 16:52:32 | | 2021-07-31 16:52:33 | +---------------------+
注意点
リストアはMySQLサーバー単位で行われます。 MySQLデータベースはMySQLサーバー「内」の概念なので、リストアとともに復元されます。 が、Terraformユーザーへの落とし穴としてMySQLデータベースはTerraform管理下に入りません。
これまでデータベースもTerraformで管理していた場合、リストアの結果として、いわゆる「構成ドリフト」が発生します。
Terraformにおける構成ドリフトの解決策の1つはterraform import
です。
mysql_database
resourceはimportをサポートしています。
MySQLサーバー内のデータベースとそのIDはaz mysql db list
で取得できるので、自分で作ったデータベースをimportしていけば良いでしょう。
$ az mysql db list --resource-group rg_kiririmode_mysql --server-name kiririmode-mysql-restore --output table --query '[].[name,id]' Column1 Column2 ------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- mysql /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/rg_kiririmode_mysql/providers/Microsoft.DBforMySQL/servers/kiririmode-mysql-georestore/databases/mysql information_schema /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/rg_kiririmode_mysql/providers/Microsoft.DBforMySQL/servers/kiririmode-mysql-georestore/databases/information_schema performance_schema /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/rg_kiririmode_mysql/providers/Microsoft.DBforMySQL/servers/kiririmode-mysql-georestore/databases/performance_schema sys /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/rg_kiririmode_mysql/providers/Microsoft.DBforMySQL/servers/kiririmode-mysql-georestore/databases/sys hoge /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/rg_kiririmode_mysql/providers/Microsoft.DBforMySQL/servers/kiririmode-mysql-georestore/databases/hoge kiririmode-database /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/rg_kiririmode_mysql/providers/Microsoft.DBforMySQL/servers/kiririmode-mysql-georestore/databases/kiririmode-database