EBSスナップショットからのMySQLデータの回復

この短いガイドはおそらく、AWS(特にEC2インスタンスのMySQL)を使用してEBSスナップショットからデータをMySQLに復元するのに役立つでしょう(もちろん、慎重なシステム管理者が事前に定期的に作成します- ec2 ‑整合性‑スナップショット 、たとえば)

まず、 EC2 Management Consoleを開く必要があり、ELASTIC BLOCK STORE→Snapshotsセクションで適切なスナップショットを見つけます(通常、これはセクションの最後のスナップショットです)。

次に、画像を右クリックし、「ボリュームの作成」を選択します。 アベイラビリティーゾーンでは、EC2インスタンスが配置されているのと同じリージョンを選択する必要があります。

その後、ELASTIC BLOCK STORE→Volumesセクションに移動し、表示されるセクションを再度右クリックします。 メニューで[ボリュームのアタッチ]アイテムを選択し、表示されるモーダルウィンドウでEC2インスタンスを選択して[はい、アタッチ]をクリックします。

それだけです-新しいブロックデバイスがサーバーに表示されるはずです。 これでdmesg | tailを実行できますdmesg | tail 接続されたブロックデバイスに割り当てられている識別子を確認します。 これがxvdgだとしましょう。 FSは、たとえば、/ dev / xvdg1に配置できます(パーティションテーブルを作成した人の好みによって異なります)。

新しいディレクトリを作成し、その中のセクションをマウントします。

 mkdir /mnt/backup mount /dev/xvdg1 /mnt/backup 

バックアップから必要なデータを取得するために、別のデータディレクトリで動作するMySQLの追加インスタンスを含めます。

 sudo -u mysql /usr/libexec/mysqld --basedir=/usr --datadir=/mnt/backup/mysql --plugin-dir=/usr/lib64/mysql/plugin --log-error=/var/log/mysqld_backup.log --pid-file=/var/run/mysqld/mysqld_backup.pid --socket=/var/lib/mysql/mysql_backup.sock --port=5523 

次に、実行中のMySQLインスタンスに接続してみます。

 mysql -h 127.0.0.1 -P 5523 

接続できる場合は、データ回復のプロセスを開始できます。

たとえば、かなり単純なシナリオを考えてみましょう。本番環境の管理者-研修生は、特定のオブジェクトの特定のフィールドの値を変更しましたが、永遠についての考えに気を取られ、誤ってSQLクエリにWHEREを書くのを忘れました。 まあ、それは大丈夫です-誰とそれが起こりません。

そこで、website.profileの性別フィールドの値を復元します。 そして、すべてのレコードでさえもではなく、3分の1の場所です(もちろん、管理者は思慮深く、しかしCtrl + Cを押さないほどではないので、明らかにリクエストが疑わしく長く実行されていることに気付きました)。 これを行うには、メインデータベースのシェルで、必要な識別子を含むファイルを作成します。

 select id from profile where sex="test" into outfile '/tmp/profile_id_list'; 

したがって、ファイル/ tmp / profile_id_listが作成されます。このフィールドには、バックアップから性別フィールドを復元する必要があるレコードの識別子があります。

次に、このようなスクリプトを作成し、restore.pyという名前で保存します。

 import MySQLdb db = MySQLdb.connect(host="127.0.0.1", port=5523, user="user", passwd="password", db="website") c = db.cursor() f = open("/tmp/profile_id_list") for profile_id in f.readlines(): c.execute( "select sex from profile where id=%s", (profile_id,) ) print "update profile set sex=\"%s\" where id=%s;" % ( c.fetchone()[0], profile_id[:-1] ) 

そして、SQLファイルを作成して性別を復元します。

 python restore.py > restore.sql 

ファイルの順序を確認し(たとえば、行数はwc -l restore.sqlを使用して表示できます)、ファイルからSQLクエリを実行します。

 mysql website < restore.sql 

すべてが正常に復元されたことを確認します。

/ tmp / profile_id_listおよびその他のファイルを削除し、それに応じてMySQLサーバーをオフにできます。

 mysqladmin -u root -p -h 127.0.0.1 -P 5523 shutdown 

次に、パーティションをアンマウントし、マウントされたディレクトリを削除します。

 umount /mnt/backup rm -r /mnt/backup 

また、AWSマネジメントコンソールで、それぞれ、[ELASTIC BLOCK STORE]→[ボリューム]セクションに移動し、仮想ブロックデバイス(ボリュームの切断)をオフにします。 その後、削除できます(ボリュームの削除)。

また、写真のあるセクションに戻り(ELASTIC BLOCK STORE→Snapshots)、何らかの方法でそれらの写真にマークを付けることができます(写真が撮影された時間までに判断すると)間違ったデータがあります(たとえば、これを写真名に反映します)。 別の方法は、スナップショットを完全に削除することです。 しかし、このソリューションは、他の誰かが必要とする可能性があるのはこのイメージであるという観点からはより悪いです(このイメージで完全に異なる完全に異なるデータを復元するため)。 したがって、デフォルトでは、最新の(さらに最新の)スナップショットには貴重なデータが含まれている可能性があり、念のため、しばらく(たとえば1週間)削除しないでください。

そして最後に、アドバイス。 MySQLには、特定のオブジェクトが一意に指定されているWHERE句を指定しない場合、DELETEまたはUPDATEクエリを実行できないモードがあります。 したがって、誤ってWHEREを追加するのを忘れた場合、エラーが発生します。
エラー1175(HY000):安全な更新モードを使用しており、KEY列を使用するWHEREなしでテーブルを更新しようとしました
このモードを有効にするには、mysqlコマンドをオプションに追加して、好みに合わせてください:‑ ‑ ‑‑i‑am‑a‑dummyまたは‑‑safe‑updates

safe‑updates行を〜/ .my.cnfファイルに追加することで、同様の効果を実現できます(たとえば、オプションをまったく指定せずにmysqlコマンドを実行すると、すべてが〜/ .my.cnfから自動的に取得されます)。

ちなみに、デフォルトでは、このモードはさらにいくつかの制限を追加します(ただし、これは無効にできますが、実際にはこれはほとんど必要ありません):select_limitの場合は1000に設定され、max_join_sizeの場合は1,000,000に設定されます。

Source: https://habr.com/ru/post/J218821/


All Articles