Amazon Web Services ブログ

Amazon RDS for MySQLの delayed replicationで障害から復旧を行う

Amazon RDS for MySQLでdelayed replicationをサポートしました。これにより、レプリカデータベースがソースデータベースより遅延する期間を設定できます。標準のMySQLレプリケーション設定では、ソースとレプリカの間の遅延が最小限に抑えられています。今回のアップデートで意図的な遅延を導入するオプションを選べるようになりました。

遅延は、人為的なエラーから復旧させる必要がある場合に非常に役立ちます。たとえば、誤ってプライマリデータベースからテーブルを削除した場合、レプリカで同じクエリを実行する必要はありません。テーブルが削除される直前でレプリケーションを停止し、レプリカをスタンドアロンインスタンスに昇格させることができます。このブログ記事では、delayed replicationを使用して、このようなシナリオから復旧させる方法をご紹介します。

次の図は、遅延が3600秒(1時間)に設定されたレプリカを人為的エラーから回復する方法を示しています。まず、レプリケーションを停止します。次に、ログの問題の箇所を見つけ、問題のクエリが実行される直前までトランザクションを実行し。最後に、レプリカをマスターに昇格させます。

WN_diagram

 

前提条件
delayed replicationをチェックする前に、Amazon RDS for MySQLソースデータベースインスタンスでMySQL 5.6.40または5.7.22以降が必要です。また、インスタンスに接続するためのMySQLクライアントと、データベースにアクセスできる適切なセキュリティグループが必要です。

バイナリログを十分な時間保持していることを確認してください。バイナリログの詳細については、 MySQL Binary Logsを参照してください。次のコマンド例は、保持期限を24時間に設定する方法を示しています。

call mysql.rds_set_configuration('binlog retention hours', 24);

 

シナリオの設定
既存のAmazon RDS for MySQLデータベースを既存のリードレプリカで使用するか、新しいデータベースを作成します。このブログ記事では、既存のRDS MySQLデータベースを利用し、新しい読み取りレプリカを作成します。

データベースの作成
MySQLインスタンス用のAmazon RDSをまだお持ちでない場合は、作成をしてください。クライアントマシンからのアクセスを許可するセキュリティグループを使用してデータベースを構成してください。作業したいMySQLデータベースがすでにある場合は、この手順をスキップしてください。

AWSマネージメントコンソール、AWS CLI、AWS SDK、またはAWS CloudFormationテンプレートを使用して、MySQLデータベース用のRDSを作成します。MySQLインスタンスの作成を支援する必要がある場合は、Create and Connect to a MySQL Database with Amazon RDSの手順に従ってください。次のスクリーンショットは、すでに設定されて使用可能な1つのデータベースインスタンスを示しています。

InstanceName

データベースに接続する
マスターデータベース・インスタンスが作成されて使用可能になったら、そのデータベースインスタンスに接続します。Amazon EC2 Linuxマシンを使用している場合は、次のコマンドに示すように、いくつかの環境変数を設定して余分なタイピングを省くことができます。

export REGION="us-west-2"
export DBUSER="master"
export RDSMASTER="blogger-mm.us-west-2.rds.amazonaws.com"
export DBNAME="mydb"

MySQLコマンドラインツールを利用し、以下の用に MySQL に接続します。

mysql -h ${RDSMASTER%%:*} -P 3306 --user=$DBUSER --password=$DBPASSWORD

接続したら、いくつかのテストテーブルといくつかのデータを作成します。デモンストレーションとして、myschemaというスキーマにいくつかのテーブルを追加しました。 私は次のコードを追加しました。

SELECT table_name, table_rows, table_type, engine FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema = 'myschema';

+---------------+------------+------------+--------+
| table_name    | table_rows | table_type | engine |
+---------------+------------+------------+--------+
| mytesttable   |   24534685 | BASE TABLE | InnoDB |
| mytesttable01 |      10000 | BASE TABLE | InnoDB |
| mytesttable02 |       9928 | BASE TABLE | InnoDB |
| mytesttable11 |       9928 | BASE TABLE | InnoDB |
| mytesttable12 |       9928 | BASE TABLE | InnoDB |
| mytesttable13 |       9928 | BASE TABLE | InnoDB |
| mytesttable14 |       9928 | BASE TABLE | InnoDB |
| mytesttable15 |       9676 | BASE TABLE | InnoDB |
| mytesttable16 |       9676 | BASE TABLE | InnoDB |
| mytesttable17 |      10000 | BASE TABLE | InnoDB |
| mytesttable18 |      10000 | BASE TABLE | InnoDB |
| mytesttable19 |      10000 | BASE TABLE | InnoDB |
+---------------+------------+------------+--------+
12 rows in set (0.00 sec)

 

リードレプリカを作成する
ディザスタリカバリ用の読み取りレプリカを追加します。AWS CLIまたはAWS Management Consoleを使用して、リードレプリカを追加します。レプリカは、同じアベイラビリティゾーン、異なるアベイラビリティゾーン、または異なるAWSリージョン内に作成することができます。ここでは、リードレプリカの作成方法を示します。

aws rds create-db-instance-read-replica --db-instance-identifier blogger-mm-rr \
    --source-db-instance-identifier blogger-mm --db-instance-class db.m4.large \
    --port 3306 --auto-minor-version-upgrade --multi-az --publicly-accessible

レプリカが使用可能な状態になったら、マスターインスタンスとの間のレプリケーション遅延を設定します。

レプリケーション遅延を設定する
リードレプリカが作成される前または後に、ソースインスタンスの複製遅延を構成します。 delayed replicationでは、ソースからレプリカへのレプリケーションを遅延させる最小時間を秒単位で指定します。レプリケーション遅延を設定するには、レプリカに接続し、mysql.rds_set_source_delayストアドプロシージャを実行します(パラメータ値は0〜86400で最大値は1日(86400秒です) 。誤ったSQL文を判断して回復するのに十分な時間を確保するには、値を少なくとも3600秒(1時間)に設定することをお勧めします。以下が設定方法です:

call mysql.rds_set_source_delay (3600);

+-----------------------------------+
| Message                           |
+-----------------------------------+
| source delay is set successfully. |
+-----------------------------------+
1 row in set (0.02 sec)

削除されたテーブルからのリカバリ
この例では、レプリカを作成してから3時間後に、mytesttable01を削除しようとしたときにmytesttable11テーブルを削除しました。レプリカは1時間遅れているので、何が起こったか把握し、そのミスがレプリカに伝播するのを防ぐ時間があります。私は間違いを直ちに認識したので、次の復旧手順を取りました。

  1. リードレプリカblogger-mm-rrに接続し、ストアドプロシージャrds_stop_replicationを呼び出します。
    call mysql.rds_stop_replication;
    
    +---------------------------+
    | Message                   |
    +---------------------------+
    | Slave is down or disabled |
    +---------------------------+
    1 row in set (1.01 sec)

    最初に問題を認識したときにレプリケーションを停止することができれば、間違いのあるログを見つけてレプリカで再生されないようにすることができます。

  2. mysqlbinlogユーティリティを使用して、問題のあるbinlogの場所を探します。RDSによるmysqlbinlogの詳細については、Log Access Conceptsを参照してください。
  3. この時点からの複製ができるだけ迅速に行われるように、レプリケーション遅延を0に設定します。 これを行うには、rds_set_source_delay(0)を実行します。
  4. ログと変更が含まれている場所を見つけたら、ログ名と場所を書き留めます。 mysql-bin-changelog.000263120の直後にエラーが発生しました。バイナリログファイル内の先程の場所に到達するまでレプリケーションを開始するには、call.rds_start_replication_untilプロシージャを使用します。 警告 – リカバリで指定された場所の後に行われた変更は、手動で再適用するか、永久に失われます。以下がこのシナリオの設定方法です:
    call mysql.rds_start_replication_until('mysql-bin-changelog.000263', 120);
    
    +---------------------------------------------------------------------------------------------+
    | Message                                                                                     |
    +---------------------------------------------------------------------------------------------+
    | Slave started until MASTER_LOG_FILE = "mysql-bin-changelog.000263'" and MASTER_LOG_POS = 120 |
    +---------------------------------------------------------------------------------------------+
    1 row in set (0.00 sec)
    
    Query OK, 0 rows affected (0.00 sec)
  5. RDSイベントの”Replication has been stopped since the replica reached the stop point specified by the rds_start_replication_until stored procedure. Use rds_start_replication to resume replication. “まで待機します。レプリカに接続し、Relay_Master_Log_FileとExec_Master_Log_Posが少なくとも経過した位置にあるかどうかを確認して、すべての変更が適用されていることを確認します。チェック方法は以下のとおりです:
    show slave status;
  6. ドロップされた表にすべての変更が行われた後、レプリカを昇格します:
    aws rds promote-read-replica --db-instance-identifier blogger-mm-rr
  7. 古いマスターインスタンスを削除します:
    aws rds delete-db-instance --db-instance-identifier blogger-mm --skip-final-snapshot
  8. 次のコマンドを使用して、古いマスターが削除されたあとにレプリカの名前を変更します:
    aws rds modify-db-instance \
        --db-instance-identifier blogger-mm-rr --multi-az \
        --new-db-instance-identifier blogger-mm --apply-immediately
  9. 新しいマスターデータベースに接続し、通常の操作を再開します

他のシナリオとの柔軟性
既存のRDS for RDPレプリカのレプリケーション遅延を設定することに加えて、新しい読み取りレプリカを作成する前に、ソースデータベースインスタンスに遅延値を設定することもできます。 非RDSソースデータベースがありますか? また、非RDSソースを使用して、遅延レプリカをRDSに構成することもできます。 同様に、遅延した非RDSレプリカを使用してレプリケーション用にRDSソースを構成することも可能です。


About the Author

Wendy Neu has worked as a Data Architect with Amazon since January 2015. Prior to joining Amazon, she worked as a consultant in Cincinnati, OH, helping customers integrate and manage their data from different unrelated data sources.

 

 

翻訳は星野が担当しました。原文はこちら