この記事では、MySQL が誤ってデータを削除するいくつかの状況と、その対処方法を紹介します。
- 誤ってデータ行を削除するには、delete ステートメントを使用します。
- 誤ってデータテーブルを削除するには、drop table または truncate table ステートメントを使用します。
- 誤ってデータベースを削除するには、drop database ステートメントを使用します。
- 誤って MySQL インスタンス全体を削除するには、rm コマンドを使用します。
誤ってデータ行を削除するには、delete ステートメントを使用します。
delete ステートメントを使用してデータ行を誤って削除した場合は、フラッシュバック ツールを使用してフラッシュバックを通じてデータを復元できます。
データを復元するフラッシュバックの原理は、binlog の内容を変更し、それを元のライブラリに再生して戻すことです。このソリューションを使用する前提は、binlog_format=row および binlog_row_image=FULL であることを確認することです。
binlog_format
- binlog_format=statement の場合、SQL ステートメントの元のテキストは、コメントを含めて binlog に記録されます。ステートメント形式では、ステートメントに制限がある場合、このコマンドは、ステートメントを実行するときに、delete+limit など安全ではない可能性があります。インデックスが異なると、実行結果も異なります。したがって、ステートメント形式には少量のログが含まれ、IO が節約されますが、マスターとバックアップの間で不整合が発生する可能性があります。
- binlog_format=row の場合、実際に削除された行の主キー ID が binlog に記録され、マスターとバックアップで異なる行を削除しても問題はありませんが、大量のログが生成され、より多くの IO リソースが消費されます。 ;
- MYSQL は妥協策を採用しており、この SQL ステートメントがマスターとバックアップの間で不一致を引き起こす可能性があるかどうかを判断するための混合形式のログも提供します。可能であれば行形式を使用し、そうでない場合はステートメント形式を使用します。 format はステートメントを使用できます。データの不整合のリスクを回避しながら、フォーマットのログ容量が小さいという利点があります。
MYSQL は混合フォーマットでログを提供しますが、MySQL の binlog フォーマットを行に設定することも推奨されます。重要な利点の 1 つは、データのリカバリです。変更されたレコードを正確に見つけて、元の SQL に従って復元できます。
binlog_row_image
- before image: before image、つまり変更前のデータベーステーブルの内容。
- after image: ミラーリング後、つまりデータベーステーブル内の変更されたコンテンツ。
- binlog_row_image の 3 つの設定と類似点と相違点 binlog_row_image パラメータは、FULL、MINIMAL、NOBLOB の 3 つの有効な値に設定できます。FULL が設定されている場合、ビフォアイメージとアフター イメージの両方にあるすべての列をログに記録します。つまり、binlog ログにはすべての列が記録されます。前後の画像。データ変更の前後のコンテンツを保持してリカバリを容易にします。
データを復元するときは、単一のトランザクションに対して次の手順を実行します。
- insert ステートメントの場合、対応する binlogevent タイプは Write_rowsevent です。これを Delete_rowsevent に変更するだけです。
- delete ステートメントの場合は、Delete_rowsevent を Write_rowsevent に変更します。
- Update_rows の場合、ビンログには変更前後のデータ行の値が記録されます。これら 2 つの行の位置を入れ替えるだけです。
たとえば、次の 3 つのトランザクションについて考えてみましょう。
(A) delete...
(B) insert...
(C) update...
データを復元するには、フラッシュバック ツールで binlog を解析した後、メイン ライブラリに書き戻すコマンドは次のとおりです。
(reverseC) update...
(reverseB) delete...
(reverseA) insert...
つまり、データの誤った削除に複数のトランザクションが含まれる場合、実行前にトランザクションの順序を逆にする必要があります。
提案: バイナリログに基づいてメインデータベース上でデータリカバリのための SQL コマンドを直接実行することはお勧めしません。
これは、オンラインロジックを実行しているメインライブラリの場合、データの状態変化が関係している場合が多く、データ誤操作の問題が少し遅れて発見され、前回の誤操作が結果として発生する可能性があるためです。その他のデータ。
したがって、現時点で確認せずにこれらのデータ行を個別にリカバリすると、データに二次的な損害が発生する可能性があります。
実稼働環境でデータを復元するための推奨ソリューション
- 複雑なデータ復旧の場合、業務担当者はデータ復旧計画を決定する必要があります。誤操作データだけでなく、関連データの復旧計画も十分に考慮する必要があります。それに応じて待機運用データのキャッシュも復元し、A書き込みを行う必要があります。データ回復を実行するデータ回復タスク スクリプト。
- 単純なデータ リカバリの場合は、テスト環境で SQL コマンドの正しさを検証してビジネスに追加の影響がないことを確認してから、本番環境で実行できます。つまり、オンライン MYSQL データの直接操作には注意が必要です。
SQL DELETEコマンドによるデータ誤削除の防止
- sql_safe_updates パラメータを on に設定します。この方法では、delete または update ステートメントに where 条件を書き忘れた場合、または where 条件にインデックス フィールドが含まれていない場合、このステートメントの実行でエラーが報告されます。
- コードがオンラインになる前に、SQL 監査に合格する必要があります。
誤ってデータテーブルを削除するには、drop table または truncate table ステートメントを使用します。
テーブルデータを削除するにはどうすればよいですか?
最も直接的な方法は、SQL DELETE コマンドを使用して項目を 1 つずつ削除することです。削除操作が正常であることが確実な場合は、delete ステートメントに where id>=0 条件を追加できます。
ただし、テーブル全体の削除は非常に時間がかかり、ロールバック ログの生成、REDO の書き込み、および binlog の書き込みが必要となるため、パフォーマンスの観点から、truncate table またはdrop table コマンドの使用を優先する必要があります。
フラッシュバックを使用すると、delete コマンドを使用して削除されたデータを復元できますが、truncate table/drop table/drop database コマンドを使用して削除されたデータはフラッシュバックでは復元できません。なぜですか?
これは、binlog_format=row を設定したとしても、上記の 3 つのテーブル削除コマンドが実行されると、記録された binlog は依然としてステートメント形式のままであるためです。つまり、binlog には truncate/drop ステートメントが 1 つだけ存在し、情報は回復できません。
テーブルの削除/切り捨て後に回復するにはどうすればよいですか? ——完全データバックアップ + 増分ログバックアップ
テーブル データを削除するには、ドロップ/トランケートを使用します。この場合、データを復元するには、完全データ バックアップを使用し、増分 binlog ログを追加する必要があります。このソリューションには、オンラインでの定期的な完全バックアップと binlog のリアルタイム バックアップが必要です。
両方の条件が満たされている場合、誰かが正午に誤ってデータベースを削除した場合、データを復元するプロセスは次のようになります。
- ライブラリが 1 日に 1 回バックアップされ、最後のバックアップがその日の 0:00 であると仮定して、最新の完全データ バックアップを作成します。
- バックアップを使用して一時ライブラリを復元します。
- binlog ログ バックアップから、午前 0 時以降のログを取り出します。
- 誤ってデータを削除した場合の記述を除き、これらのログを一時ライブラリに適用します。
誤って削除されたデータステートメントに対応するバイナリログをスキップするにはどうすればよいですか?
- 元のインスタンスが GTID モードを使用していない場合は、12 時を含む binlog ファイルに適用するときに、誤操作の前にログを実行するには --stop-position パラメータのみを使用し、その後 --start-position を使用して開始します。誤操作後のログからは実行が継続されます。
- インスタンスが GTID モードを使用している場合は、さらに便利です。誤操作コマンドの GTID が gtid1 であるとすると、setgtid_next=gtid1;begin;commit を実行するだけで済みます。まず、この GTID を一時インスタンスの GTID セットに追加します。をクリックしてから、 を押します。 binlog が連続して実行されると、誤操作ステートメントは自動的にスキップされます。
誤ってデータベースを削除するには、drop database ステートメントを使用します。
バイナリログはデータベース全体のレベルにあるため、上記の解決策はデータベースを削除するときのデータ回復にも使用できます。
並列レプリケーションを使用することでデータの復元プロセスを高速化できますが、この解決策でも、ライブラリのバックアップが特に大きい場合や誤操作の時間が最後の完全バックアップよりも長い場合など、 「制御不能な回復時間」という問題が依然としてあります。, たとえば、週に 1 回バックアップされるインスタンスの場合、バックアップ後 6 日目に誤操作が発生した場合、6 日間のログを復元する必要があり、復旧にかかる時間が日数で計算されることがあります。
では、データの復元にかかる時間を短縮するにはどうすればよいでしょうか?
遅延レプリケーションのスタンバイ
非常に中核的なビジネスで、あまり長い復旧時間を許容できない場合は、遅延レプリケーション用のスタンバイ データベースを構築することを検討できます (この機能は MySQL 5.6 で導入されました)。
一般的なマスター/スレーブ レプリケーション構造の問題は、マスター データベース上のテーブルが誤って削除された場合、このコマンドがすぐにすべてのスレーブ データベースに送信され、すべてのスレーブ データベース テーブルが誤って削除されてしまうことです。
遅延レプリケーション用のスタンバイ・データベースは、特別な種類のスタンバイ・データベースです。CHANGE MASTER TO MASTER_DELAY=Nコマンドを使用して、このスタンバイ・データベースがメイン・データベースに対して N 秒の遅延を維持し続けるように指定できます。
たとえば、N を 3600 に設定すると、メイン データベース上のデータが誤って削除され、誤操作コマンドが 1 時間以内に見つかった場合、そのコマンドは遅延レプリケーション スタンバイ データベース上で実行されていないことを意味します。今度は、スタンバイ データベースで stop SLAVE を実行し、上記の「バックアップ + 増分ログ」方法を使用して、binlog 内の誤操作コマンドをスキップすると、必要なデータを回復できます。
この遅延レプリケーション スタンバイ データベース (N=3600) を使用すると、いつでもデータベースを取得でき、データの一時インスタンスを回復するために最大でさらに 1 時間追跡するだけで済み、データ全体に必要な時間が短縮されます。回復;
データベース/テーブルの誤った削除を防ぐ方法
- 最初の提案は、アカウントの権限を分離することです。
この目的は、間違ったコマンドの作成を避けることです。たとえば、ビジネス開発者にのみ DML 権限を与え、切り捨て/削除権限は与えません。また、ビジネス開発者に DDL のニーズがある場合は、開発管理システムを通じてサポートすることもできます。 DBA チームのメンバーである場合、日常的には読み取り専用アカウントのみを使用し、必要に応じて更新権限のあるアカウントを使用することも規定されています。
- 2 番目の提案は、実践規範を作成することです。
この目的は、削除するテーブルの名前を誤って書き込まないようにすることです。たとえば、データ テーブルを削除する前に、まずテーブルの名前を変更する必要があります。その後、一定期間観察して、データ テーブルに影響がないことを確認します。このテーブルを削除する前に業務を変更するテーブル名に固定のサフィックスを追加する必要があり (たとえば、_to_be_deleted を追加する)、その後テーブルを削除するアクションが管理システムを通じて実行される必要があります。 、管理システムがテーブルを削除する場合、固定サフィックスを持つテーブルのみを削除できます。
rm コマンドを使用して、誤って MySQL インスタンス全体を削除する
実際、高可用性メカニズムを備えた MySQL クラスターの場合、最も恐れられるのは rm によるデータの削除です。クラスター全体が悪意を持って削除されず、いずれかのノードのデータのみが削除される限り、HA はシステムは作業を開始し、クラスター全体の正常な動作を保証するために新しいメイン ライブラリを選択します。
現時点で必要なのは、このノード上のデータを復元し、クラスター全体にアクセスすることだけです。
もちろん、現在では DBA だけでなく SA (システム管理者) も自動システムを持っているため、バッチ オフライン マシンの操作によって MySQL クラスター全体のすべてのノードが消去される可能性があります。
実際、上記の誤って削除されたデータの問題については、どのような種類のデータ回復スキームが使用されるとしても、その前提となる中心的な考え方は、データのバックアップを適切に実行することです。クラスター rm コマンドの場合、次の提案が行われます。バックアップは複数のコンピュータ ルームまたは複数の場所に保存されます。
この記事の参考文献:31 | 誤ってデータを削除して逃げる以外に何ができるでしょうか?