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)
スーパーユーザー権限がないためですか、それともこの問題を解決する方法ですか?誰かが私を提案してください。
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_format
がROW
に設定されている場合、これは機能するはずです。ただし、いくつかの初期エラーをスキップする必要がありますが、その後エラーが発生する必要はありません。これが機能するのは、行ベースのレプリケーションが非常に決定論的であり、すでに存在するものを挿入しようとしたり、すでになくなったものを削除しようとしたりすると停止するためです。エラーを過ぎると、一貫性のあるスナップショットが実際に開始された真の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 STATUS
Exec_Master_Log_Pos
およびRelay_Master_Log_File
からのRDS読み取りレプリカのマスター座標をCHANGE MASTER TO
座標として使用します。
スレーブのExec_Master_Log_Pos
に表示される値は、 処理される次のトランザクションまたはイベントの開始 であり、これがまさに新しいスレーブの場所です。マスターで読み取りを開始する必要があります。
次に、外部スレーブが稼働し始めたら、RDSリードレプリカを廃止できます。
rDSのbinlog位置の場合、mydumper
を--lock-all-tables
とともに使用できます。これは、LOCK TABLES ... READ
を使用して、binlog座標を取得し、FTWRL
の代わりにそれを解放します。
Michaelに感謝します。最も正しい解決策であり、AWSが推奨するのは、説明されているように、ソースとしてリードレプリカを使用してレプリケーションを行うことです ここ 。
RDSマスター、RDSリードレプリカ、およびMySQLの準備ができているインスタンスがある場合、外部スレーブを取得する手順は次のとおりです。
mysql> CALL mysql.rds_set_configuration('binlog retention hours', 12);
mysql> CALL mysql.rds_stop_replication;
mysql> SHOW SLAVE STATUS;
mysqldump -h RDS_READ_REPLICA_IP -u root -p YOUR_DATABASE > backup.sql
mysql -u root -p YOUR_DATABASE < backup.sql
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;
mysql> SHOW SLAVE STATUS;
mysql> CALL mysql.rds_start_replication;
Michaelの回答は非常に役立ち、主な問題点に焦点を当てています。RDSで必要なSUPER特権を付与できないため、非常に簡単になる--master-dataフラグを使用できません。
APIを介してデータベースパラメータグループを作成または変更することでこれを回避できる可能性があることを読みましたが、RDSプロシージャを使用する方が良いオプションだと思います。
ただし、マルチティアレプリケーションアプローチは適切に機能し、RDS/VPCの外部にティアを含めることができるため、この方法を使用して「クラシック」EC2からVPCにレプリケーションすることができます。
必要な機能の多くは、MySQL 5.5および5.6の以降のリリースにのみ含まれています。レプリケーションスタックに含まれるすべてのDBで同じバージョンを実行することを強くお勧めします。そのため、すべての前に古いDBのアップグレードを行う必要があります。これは、さらに面倒で複製などを意味します。
私は同様の問題に直面していましたが、これに対する簡単な回避策は次のとおりです。
EBSボリュームを作成して、スペースを追加するか、EC2で現在のEBSボリュームを拡張します。 (または、余分なスペースがある場合は、それを使用できます)。
--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名も指定します。
DBサイズが大きい場合は、追加料金が発生することに注意してください。完全なDBダンプを作成するためです。
お役に立てれば