web-dev-qa-db-ja.com

MySQL AmazonRDSのバックアップ

AWSの外部でレプリカをセットアップしようとしていますが、マスターはAWSRDSで実行されています。そして、私は私のマスターでダウンタイムを望んでいません。そこで、スレーブノードをセットアップし、AWSにある現在のデータベースをバックアップしたいと思います。

_mysqldump -h RDS ENDPOINT -u root -p --skip-lock-tables --single-transaction --flush-logs --hex-blob --master-data=2 --all-databases > /root/dump.sql_

VMでテストしましたが、正常に機能しましたが、RDSと接続するとエラーが発生します

mysqldump: Couldn't execute 'FLUSH TABLES WITH READ LOCK': Access denied for user 'root'@'%' (using password: YES) (1045)

スーパーユーザー権限がないためですか、それともこの問題を解決する方法ですか?誰かが私を提案してください。

18
JavaGuy

RDSは、マスターユーザーでさえSUPER特権を許可しません。これは、FLUSH TABLES WITH READ LOCKを実行するために必要です。 (これはRDSの残念な制限です)。

失敗したステートメントは、--master-dataオプションによって生成されています。これは、もちろん、バックアップが開始される正確なbinlog座標を学習できるようにする場合に必要です。 FLUSH TABLES WITH READ LOCKは、すべてのテーブルのグローバル読み取りロックを取得します。これにより、mysqldumpはSTART TRANSACTION WITH CONSISTENT SNAPSHOT--single-transactionの場合と同様)、次にSHOW MASTER STATUSを実行して、バイナリログ座標を取得できます。可視データをそのログ位置と一致する状態に保つトランザクションがあるため、グローバル読み取りロックを解放します。

RDSは、SUPER特権を拒否し、明らかな回避策を提供しないことにより、このメカニズムを破ります。

これを適切に回避するために利用できるハッキーなオプションがいくつかありますが、どれも特に魅力的ではない可能性があります。

  • トラフィックが少ない時間帯にバックアップを実行します。バックアップを開始してからバックアップが出力ファイルまたは宛先サーバーへのデータの書き込みを開始した後(--single-transactionを使用したと仮定)の間にbinlog座標が変更されていない場合、座標が変更されていないことがわかっているため、これは機能します。プロセスの実行中に変更します。

  • バックアップを開始する直前にマスターのbinlogの位置を確認し、これらの座標をCHANGE MASTER TOで使用します。マスターのbinlog_formatROWに設定されている場合、これは機能するはずです。ただし、いくつかの初期エラーをスキップする必要がありますが、その後エラーが発生する必要はありません。これが機能するのは、行ベースのレプリケーションが非常に決定論的であり、すでに存在するものを挿入しようとしたり、すでになくなったものを削除しようとしたりすると停止するためです。エラーを過ぎると、一貫性のあるスナップショットが実際に開始された真のbinlog座標になります。

  • 前の項目と同じですが、バックアップを復元した後、mysqlbinlog --base64-output=decode-rows --verboseを使用して取得した座標でマスターのビンログを読み取り、新しいスレーブをチェックして、どのイベントがすでに発生している必要があるかを確認して、正しい位置を特定してください。スナップショットが実際に開始される前に実行され、この方法で決定された座標を使用してCHANGE MASTER TOになります。

  • 外部プロセスを使用して、サーバー上のすべてのテーブルの読み取りロックを取得します。これにより、すべての書き込みが停止します。 SHOW MASTER STATUSからのbinlog位置がインクリメントを停止していることを確認し、バックアップを開始して、それらのロックを解放します。

おそらく最後のアプローチ以外のこれらのアプローチのいずれかを使用する場合は、テーブルの比較を行って、実行後にスレーブがマスターと同一であることを確認することが特に重要です。その後のレプリケーションエラーが発生した場合は、そうではありませんでした。

おそらく最も安全なオプションですが、おそらく最も厄介なオプションでもあります 必要ではないように思われるので、RDSマスターのRDS読み取りレプリカを作成することから始めます。起動してマスターに同期したら、RDS5.6.13で導入されたRDS提供のストアドプロシージャCALL mysql.rds_stop_replicationを実行することで、RDSリードレプリカでのレプリケーションを停止できます。および5.5.33 は、SUPER特権を必要としません。

RDSレプリカスレーブが停止した状態で、RDSリードレプリカからmysqldumpを取得します。これにより、特定のマスター座標のセットの時点で不変のデータセットが保存されます。このバックアップをオフサイトスレーブに復元してから、SHOW SLAVE STATUSExec_Master_Log_PosおよびRelay_Master_Log_FileからのRDS読み取りレプリカのマスター座標をCHANGE MASTER TO座標として使用します。

スレーブのExec_Master_Log_Posに表示される値は、 処理される次のトランザクションまたはイベントの開始 であり、これがまさに新しいスレーブの場所です。マスターで読み取りを開始する必要があります。

次に、外部スレーブが稼働し始めたら、RDSリードレプリカを廃止できます。

45

rDSのbinlog位置の場合、mydumper--lock-all-tablesとともに使用できます。これは、LOCK TABLES ... READを使用して、binlog座標を取得し、FTWRLの代わりにそれを解放します。

3
Max Bube

Michaelに感謝します。最も正しい解決策であり、AWSが推奨するのは、説明されているように、ソースとしてリードレプリカを使用してレプリケーションを行うことです ここ

RDSマスター、RDSリードレプリカ、およびMySQLの準備ができているインスタンスがある場合、外部スレーブを取得する手順は次のとおりです。

  1. マスターで、binlogの保持期間を増やします。

mysql> CALL mysql.rds_set_configuration('binlog retention hours', 12);

  1. リードレプリカでは、バックアップ中の変更を回避するためにレプリケーションを停止します。

mysql> CALL mysql.rds_stop_replication;

  1. レプリカの読み取り時に、binlogステータス(Master_Log_FileおよびRead_Master_Log_Pos)に注釈を付けます

mysql> SHOW SLAVE STATUS;

  1. サーバーインスタンスでバックアップを実行してインポートします(Maxが提案するmydumperを使用すると、プロセスを高速化できます)。

mysqldump -h RDS_READ_REPLICA_IP -u root -p YOUR_DATABASE > backup.sql

mysql -u root -p YOUR_DATABASE < backup.sql

  1. サーバーインスタンスで、RDSマスターのスレーブとして設定します。

mysql> CHANGE MASTER TO MASTER_Host='RDS_MASTER_IP',MASTER_USER='myrepladmin', MASTER_PASSWORD='pass', MASTER_LOG_FILE='mysql-bin-changelog.313534', MASTER_LOG_POS=1097;

MASTER_LOG_FILEとMASTER_LOG_POSを以前に保存したMaster_Log_FileRead_Master_Log_Posの値に再レースします。また、スレーブレプリケーションで使用するにはRDSマスターのユーザーが必要です。

mysql> START SLAVE;

  1. サーバーインスタンスで、レプリケーションが成功したかどうかを確認します。

mysql> SHOW SLAVE STATUS;

  1. RDSで、レプリカの読み取りがレプリケーションを再開します。 mysql> CALL mysql.rds_start_replication;
2
Chemary

Michaelの回答は非常に役立ち、主な問題点に焦点を当てています。RDSで必要なSUPER特権を付与できないため、非常に簡単になる--master-dataフラグを使用できません。

APIを介してデータベースパラメータグループを作成または変更することでこれを回避できる可能性があることを読みましたが、RDSプロシージャを使用する方が良いオプションだと思います。

ただし、マルチティアレプリケーションアプローチは適切に機能し、RDS/VPCの外部にティアを含めることができるため、この方法を使用して「クラシック」EC2からVPCにレプリケーションすることができます。

必要な機能の多くは、MySQL 5.5および5.6の以降のリリースにのみ含まれています。レプリケーションスタックに含まれるすべてのDBで同じバージョンを実行することを強くお勧めします。そのため、すべての前に古いDBのアップグレードを行う必要があります。これは、さらに面倒で複製などを意味します。

1
Ben Walsh

私は同様の問題に直面していましたが、これに対する簡単な回避策は次のとおりです。

  1. EBSボリュームを作成して、スペースを追加するか、EC2で現在のEBSボリュームを拡張します。 (または、余分なスペースがある場合は、それを使用できます)。

  2. --master-dataまたは--flush-dataディレクティブを指定せずにmysqldumpコマンドを使用して、dbの完全(FULL)バックアップを生成します。

    mysqldump -h hostname --routines -uadmin -p12344 test_db> filename.sql

adminはDB名、12344はパスワードです

上記は単一のDBのバックアップを取るためのものであり、すべてのDBを取得する必要がある場合は、-all-databasesを指定し、DB名も指定します。

  1. このコマンドのcronを作成して、ダンプを自動的に生成する1日1回実行します。

DBサイズが大きい場合は、追加料金が発生することに注意してください。完全なDBダンプを作成するためです。

お役に立てれば

0
Qayed