MySQL のデータの偶発的な削除の解決策と kill ステートメントの原則

MySQL のデータの偶発的な削除の解決策と kill ステートメントの原則

mysql が誤ってデータを削除しました

  • 削除ステートメントを使用して誤ってデータ行を削除する
  • 誤ってデータテーブルを削除するには、drop table または truncate table を使用します。
  • drop database ステートメントを使用して誤ってデータベースを削除する
  • rm を使用して誤って mysql インスタンス全体を削除する

誤って削除された行

  • フラッシュバック ツールを使用して、データをフラッシュバックして復元します。原則としては、binlogの内容を変更し、元のデータベースから取得して再生します。binlog_format=rowおよびbinlog_row_imsge=Fullであることを確認する必要があります。
  • 具体的な回復時間
    • 挿入の場合は、binlog イベント タイプを write_rows イベントから delete_rows イベントに変更します。
    • 削除の場合はその逆になります。
    • 更新の場合、binlog にはデータが変更される前と後の値が含まれます。この 2 行を入れ替えるだけです。
  • 上記の原則に従って、複数の事柄も逆の順序で実行されます。
  • 防止策: sql_safe_updates パラメータをオンに設定します。このように、delete または update ステートメントで where 条件を記述し忘れた場合、または where 条件にインデックス フィールドが含まれていない場合、このステートメントを実行するとエラーが報告されます。

誤って削除されたデータベース/テーブルの場合

完全バックアップと増分ログを使用する必要があります。定期的にオンラインで完全バックアップを実行し、バイナリログをリアルタイムでバックアップする必要がありますか?

誰かが午後 12 時に誤ってデータベースを削除した場合、データを復元するプロセスは次のようになります。

最新の完全バックアップを取得します。データベースは 1 日に 1 回バックアップされ、最後のバックアップは同じ日の 0:00 に行われたと仮定します。

バックアップから一時ライブラリを復元します。

ログバックアップから午前0時以降のログを取り出す

誤ってデータを削除するステートメントを除くすべてのログを一時データベースに適用します。

知らせ:

データの回復を高速化するために、この一時ライブラリに複数のデータベースがある場合は、mysqlbinlog コマンドを使用するときに –database パラメータを追加して、誤って削除されたテーブルが配置されているライブラリを指定できます。これにより、データを復元するときに他のライブラリ ログを適用する必要がなくなります。

ログを適用するときは、12 時の誤った操作を含むステートメントの binlog をスキップする必要があります。

リカバリを高速化する方法: 一時インスタンスをバックアップして復元した後、この一時インスタンスをオンライン バックアップ データベースのスレーブ データベースとして設定します。

システムで無制限にログをバックアップすることは不可能です。コストとディスク容量のリソースに基づいて、ログを保持する日数も設定する必要があります。 DBA チームが、インスタンスを半月以内の任意の時点に復元できることを保証できると言った場合、これはバックアップ システムが少なくとも半月分のログを保持することを意味します。

「誰もこんなことが起きてほしくない」とはいえ、誤って削除してしまった場合でも、すぐにデータを復元して損失を最小限に抑えることができるので、逃げる必要はありません。しかし、急いで手作業で作業を進め、ミスを犯してしまい、業務に二次的な損害を与えてしまうようなことがあっては困ります。

スタンバイデータベースの遅延レプリケーション

  • データベースのバックアップが特に大きい場合、または誤った操作と最後の完全バックアップの間の時間が長い場合、たとえば、週次バックアップのインスタンスで、バックアップの 6 日後に誤った操作が発生した場合、6 日分のログを復元する必要があり、リカバリ時間は日単位で計算される場合があります。
  • 遅延レプリケーション スタンバイ データベースは、特別なスタンバイ データベースです。CHANGE MASTER TO MASTER_DELAY = N コマンドを使用すると、スタンバイ データベースがマスター データベースに対して N 秒の遅延を維持するように指定できます。
  • たとえば、N を 3600 に設定すると、プライマリ データベースでデータが誤って削除され、誤った操作コマンドが 1 時間以内に検出された場合、そのコマンドは遅延レプリケーション スタンバイ データベースではまだ実行されていないことになります。このとき、スタンバイ データベースでstopslaveを実行し、先に紹介した方法を使用してエラーのある操作コマンドをスキップし、必要なデータを復元します。

rmでデータを削除する

クラスター全体が悪意を持って削除されず、ノードの 1 つのデータのみが削除されない限り、HA システムは動作を開始し、新しいマスター データベースを選択して、クラスター全体の正常な動作を保証します。この時点では、このノード上のデータを復元し、それをクラスター全体に接続するだけです。

もちろん、現在では DBA だけでなく SA (システム管理者) も自動化システムを備えているため、マシンを一括してオフラインにする操作によって、MySQL クラスター全体のすべてのノードが消去される可能性があります。この状況に対処するための私の唯一のアドバイスは、バックアップをデータセンター間、できれば都市間で保存することです。 SQL文を強制終了する

セッション B はスレッドを直接終了し、何もせずに終了しますか?明らかに、これはうまくいきません。

テーブルを追加、削除、変更、またはクエリすると、テーブルに MDL 読み取りロックが追加されます。したがって、セッション B はブロックされた状態ですが、MDL 読み取りロックを保持し続けます。スレッドが強制終了された場合、スレッドは直接終了し、MDL 読み取りロックが解放される機会がなくなります。

Kill は、すぐに停止するという意味ではなく、このステートメントはもう実行する必要がなくなり、「実行停止ロジック」を開始できることを実行スレッドに伝えるという意味です。

実際、kill query thread_id_b を実行すると、MySQL で kill コマンドを処理するスレッドは次の処理を実行します。

  • セッションBの実行状態をTHD::KILL_QUERYに変更する
  • セッション B の実行スレッドにシグナルが送信されます。

図1の例では、セッションBはロック待機状態にあります。セッションBのスレッド状態を
THD::KILL_QUERY、スレッド B はこの状態の変化を認識せず、待機を続けます。シグナルを送信する目的は、セッション B を待機状態から終了させて​​、THD::KILL_QUERY 状態を処理することです。

上記には3つの意味が含まれています。

  • 文の実行中には複数の埋め込みポイントがあります。スレッドの状態はこれらの「埋め込みポイント」で決定されます。スレッドの状態が見つかった場合
  • ステートメント終了ロジックを開始するのは THD::KILL_QUERY です。
  • 待機状態の場合は、復帰可能な待機状態でなければなりません。そうでない場合は、「埋もれたポイント」までまったく実行されません。
  • 終了ロジックに入るステートメントの開始から終了ロジックの完了までのプロセスがあります。

殺害の例

set global innodb_thread_concurrency=2 を実行して、InnoDB 同時スレッドの上限を 2 に設定し、次のシーケンスを実行します。

以下が見られます:

実行中にセッション C がブロックされました。

ただし、セッション D によって実行された kill query C コマンドは効果がありません。

セッション E が kill connection コマンドを実行するまで、セッション C は切断されず、「クエリ中に MySQL サーバーへの接続が失われました」というメッセージが表示されます。

しかしこの時点で、セッション E で show processlist を実行すると、次の図が表示されます。

id=12 のスレッドの Commnad 列に Killed と表示されます。つまり、クライアントが切断されていても、ステートメントはサーバー上で引き続き実行されます。

この例では、スレッド12の待機ロジックは次のようになります。10ミリ秒ごとに、InnoDB実行に入ることができるかどうかを確認します。
失敗した場合は、nanosleep 関数を呼び出してスリープ状態に入ります。

つまり、スレッド 12 のステータスは KILL_QUERY に設定されていますが、InnoDB に入るのを待つループ中にスレッドのステータスが判断されないため、終了ロジック ステージにはまったく入りません。

セッション E が kill connection コマンドを実行すると、次の処理が実行されます。

  • スレッド 12 の状態を KILL_CONNECTION に設定します。
  • スレッド 12 のネットワーク接続を閉じます。この操作により、セッション C が切断プロンプトを受信することがわかります。

show processlist を実行すると、コマンド列が killed と表示されるのはなぜですか?実際、これは show processlist を実行するときに特別なロジックがあるためです。

スレッドの状態が KILL_CONNECTION の場合、[コマンド] 列には [Killed] と表示されます。

したがって、実際には、クライアントが終了したとしても、このスレッドのステータスはまだ待機中のままです。 InnoDB に入る条件が満たされ、セッション C のクエリ ステートメントが実行を継続した場合にのみ、スレッド状態が KILL_QUERY または KILL_CONNECTION になったと判断でき、終了ロジック ステージに入ることができます。

kill が無効になる最初のタイプの状況は、スレッドがスレッド ステータスを決定するロジックを実行していない場合です。また、過度の IO 負荷により、読み取りおよび書き込み IO 関数が返されず、スレッドの状態を時間内に判断できなくなる可能性もあります。

  • 2番目のケースでは、終了ロジックに長い時間がかかります
  • 実行中に非常に大きなトランザクションが強制終了され、ロールバック操作に長い時間がかかりました。
  • クエリ処理中に生成される大きな一時ファイルなどの大規模なローリング操作では、一時ファイルを削除するために IO リソースを待機する必要があり、結果として長い時間がかかります。
  • DDL が最終段階まで実行されて強制終了されると、中間プロセスの一時ファイルを削除する必要があり、これにも IO リソースが必要になります。

ctrl+C の場合、mysql は実際に接続プロセスを開始し、kill query コマンドを送信します。

低速クライアント接続に関する誤解

データベースにテーブルが多数ある場合、接続は遅くなります。たとえば、数万のテーブルを持つライブラリがある場合、デフォルトのパラメータを使用して接続すると、MySQL はローカル ライブラリ名とテーブル名の補完機能を提供します。

  • show databasesを実行する
  • db1に切り替えてshow tablesを実行します。
  • これら 2 つのコマンドの結果は、ローカル ハッシュ テーブルを構築するために使用されます。

3 番目のステップは時間のかかる操作です。つまり、私たちが感じる遅さは、接続が完全であるかサーバーが遅いためではなく、クライアントが遅いためであるということです。このリンクに -A を追加すると、自動補完機能を解除して素早く戻ることができます。

自動補完の効果は、ライブラリ名またはテーブル名を入力するときにプレフィックスが入力され、タブを使用して自動的に補完したりプロンプトを表示したりできることです。実際、自動補完をあまり使用しない場合は、使用するたびに -A を追加できます。

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • MySQL killコマンドの実行原理の詳細な説明
  • MySQL kill コマンドの使用ガイド
  • Mysql は、デッドロック問題を解決するために kill コマンドを使用します (実行中の特定の SQL ステートメントを強制終了します)。
  • MySQL スレーブが oom-killer をトリガーする問題の解決方法
  • MySQL OOM シリーズ 3: MySQL が殺されるという不運から逃れる
  • MySQL OOM システム 2 OOM キラー
  • percona-toolkit の pt-kill メソッドを使用して、mysql クエリまたは接続を強制終了します。
  • MySQL で長時間実行される SQL をバッチで強制終了する
  • MySQLのkillがスレッドをkillできない理由

<<:  Webpack で環境変数を使用するためのさまざまな正しい姿勢

>>:  Linux インストール Redis 実装プロセスとエラー解決

推薦する

CSSを使用してTDのINPUTの幅を設定する

最近、C# を使用して Web プログラムを作成していたときに、次のような問題が発生しました。 Te...

Tomcat をアンインストールして再インストールする方法 (画像とテキスト付き)

tomcat9をアンインストールする1. Tomcatのインストールはディレクトリに解凍するだけで...

Linux でファイルを削除するときに「操作は許可されていません」というプロンプトが表示される場合の対処方法

同僚からよく聞かれるのですが、ファイル/ディレクトリを削除すると「操作は許可されていません」というエ...

異なる列を持つテーブルのクエリ結果のSQLマージ操作

2 つの異なるテーブルをクエリするには、結果をマージする必要があります。たとえば、table1 の列...

CSS3 境界効果

CSSとは# CSS (Cascading Style Sheets の略) は、「カスケーディング...

Dockerコンテナを停止および削除できない問題の解決策

実行中のコンテナIDを見つける ドッカーps上記のコンテナの物理的な場所を見つける /var/lib...

Linux suse11でルートパスワードを忘れた場合に変更する方法の簡単な分析

SUSE Linuxでルートパスワードを忘れた場合の解決方法SUSE (Linux オペレーティング...

Intellij IDEA による Docker イメージの展開方法の手順の迅速な実装

目次1. Dockerはリモートアクセスを可能にする2. Intellij IDEAにDockerプ...

JavaScript データ型変換の例 (他の型を文字列、数値型、ブール型に変換する)

序文データ型変換とは何ですか?フォームまたはプロンプトを使用して取得されるデフォルトのデータ型は文字...

MySQL カーディナリティ統計の簡単な分析

1. カーディナリティとは何ですか?カーディナリティとは、MySQL テーブルの列内の異なる値の数を...

DIV と画像の水平および垂直の中央揃えは複数のブラウザと互換性があります

最初のタイプ: 完全な CSS コントロール、レイヤーフローティング (ログインページに適しています...

HTML テーブルタグチュートリアル (3): 幅と高さの属性 WIDTH、HEIGHT

デフォルトでは、テーブルの幅と高さはコンテンツに応じて自動的に調整されます。テーブルの幅と高さを手動...

VSCode 構成 Git メソッドの手順

Git は vscode に統合されており、git コマンドをいくつか記述しなくても、クリックするだ...

Vue の自動書式設定の改行保存の詳細な説明

ネットで変更方法をいろいろ調べたのですが、うまくいきませんでした。後で大物から見て削除しました。フォ...

ウェブページの右下隅に「いいね!」カード効果を実現するための CSS (サンプルコード)

効果 HTML を実装するには、まずクリーンな HTML ページを準備し、ノードを記述します。 &l...