MySQL killコマンドの実行原理の詳細な説明

MySQL killコマンドの実行原理の詳細な説明

kill コマンドを記述する方法は、「kill クエリ + スレッド ID」と「kill 接続 (オプション) + スレッド ID」の 2 つがあります。これらはそれぞれ、指定されたスレッドによって実行されているステートメントを閉じることと、指定されたスレッドに接続されているクライアントを切断することを示します (実行中の操作がある場合は、接続が閉じられる前に操作が停止されます)。しかし、場合によっては、kill query を使用した後、show processlist を使用してコマンド列を表示すると、killed と表示されます (つまり、リサイクル スレッドがリサイクルされるのを待機していますが、まだリサイクルされていません)。これはなぜでしょうか。

この質問に答える前に、サーバー上でリクエストを処理するスレッドがどのように実行されるか、および kill コマンドがどのように機能するかを知っておく必要があります。

キル命令実行原理

命令実行特性

1. ステートメントの実行中に複数の「埋め込みポイント」があります。これらの「埋め込みポイント」でスレッドの状態が判断されます。スレッドの状態が THD:KILL_QUERY であると判断された場合、ステートメント終了ロジックに入ります。

2. 待機状態の場合、それは覚醒可能な待機状態である必要があり、そうでない場合は「埋もれたポイント」までまったく実行されません。

3. 文の先頭から終了ロジックに入り、終了ロジックが完了するまでのプロセスがあります。

クエリ実行の強制終了の原則

kill クエリは主に 2 つのステップを実行します。

1. スレッドの実行状態を THD::KILL_QUERY に変更します (変数 killed を THD::KILL_QUERY に割り当てます)。

2. セッションの実行スレッドに信号を送信して、ブロッキング状態を終了し、この状態を処理します。

接続終了の実装原則

1. スレッド 12 のステータスを KILL_CONNECTION に設定します。

2. スレッド 12 のネットワーク接続をオフにします。

中断される可能性はありますか?

1. 通常、kill query を実行すると、正常に実行されたステートメントのステータスは killed から KILL_QUERY に変更され、その後、「埋め込みポイント」に到達すると実行が中断されます。

2. ブロックされたステートメントの場合は、現在のブロックされた待機状態を解除できるかどうかを確認する必要があります。解除できる場合は、現在のステートメントを中断する可能性があります。

中断される可能性のあるシナリオ: 通常の実行、または起動可能なブロックされた待機状態。

行ロックを待機するときに pthread_cond_timedwait 関数が使用されるため、この待機状態が解除される可能性があります。キルクエリで直接起動し、「埋め込みポイント」判定まで実行を継続することができます。

中断できないシナリオ: ブロックされており、起動できません。

例: 同時スレッドが不足しているためにブロックされる。

パラメータ innodb_thread_concurrency (MySQL の同時スレッド数) を 2 に設定します。次に、次の操作を実行します。

セッション D が kill query C を実行した後、セッション C はブロッキング状態を終了しません。

  • 質問 1: クエリを強制終了してもブロッキング プロセスが中断されないのはなぜですか?

回答:この種の閉塞は、微視的な観点から見た閉塞ではなく、循環的な判断だからです。 10 ミリ秒ごとに、Innodb が実行可能かどうかが判断されます。実行可能でない場合は、nanosleep 関数が呼び出され、スリープ状態に入ります。つまり、スレッドステータスが KILL_QUERY (THD::KILL_QUERY) に設定されているにもかかわらず、InnoDB に入るのを待つループ中に「埋め込みポイント」が実行されず、スレッドステータスが判定されないため、終了ロジックステージにはまったく入らなくなります。したがって中断されることはありません。

  • 質問 2: show processlist を使用して表示すると、コマンドが強制終了されたものとしてリストされます。これはなぜですか?

回答: kill query 文はスレッドの状態を KILL_QUERY に設定します。このとき、この状態のため割り込みロジックを実行していると判断されるため、Command 値は強制終了されます。

  • 質問 3: 接続を切断すると、ブロック プロセスが中断されるのはなぜですか?

回答: kill connection はスレッドのネットワーク接続を直接閉じて強制的に閉じるため、この時点でセッション C は切断を求めるプロンプトを受け取ります。

  • 質問 4: キル クエリのみを使用する場合、ブロッキングを中断できるのはいつですか?

回答: スレッドがセッションに割り当てられ、実行が「埋め込みポイント」に到達し、割り込みロジックが実行されるまで、プログラムは終了しません。ただし、スレッドが割り当てられた後に、必ずしも中断されるわけではありません。実行が「埋め込みポイント」に到達する前にスレッドが解放された場合、スレッドは再び待機します。 MySQL スレッドは多重化されています。

他の

1. 実際、kill コマンドを使用してブロッキング状態を終了するだけでなく、セッション内で直接「ctrl+c」を使用してブロッキングを終了することもできます。その原理は何ですか?

回答: まず、クライアントがサーバーを操作するには、クライアント上でスレッドを開き、このスレッドに処理をさせて、リクエスト データを送信し、それをネットワーク経由でサーバーに送信し、サーバーがそれを処理するためのスレッドを割り当てるということを知っておく必要があります。 「ctrl + c」は、クライアントに別の接続を開いて kill query コマンドを送信するように指示します。したがって、ブロッキングを中断したように見えますが、以前の接続を処理したサーバー スレッドが必ずしも中断されるわけではありません。

2. ライブラリ名を指定して接続するとなぜ遅くなるのでしょうか?以下のように表示されます。

回答: これは、MySQL の自動補完機能がデフォルトで有効になっているためです (テーブル名を入力するときにタブを使用して自動補完できます)。その実装は、データベースに接続するときにさらにいくつかの操作を実行することです。

1. show databasesを実行します。
2. db1 データベースに切り替えて show tables を実行します。
3. これら 2 つのコマンドの結果を使用して、ローカル ハッシュ テーブルを構築します。 (最も時間がかかります)

この機能は、コマンドに -A を追加することで無効にできます。 -quick を使用して無効にすることもできます。ただし、-quick を使用するとクライアントのパフォーマンスが低下する可能性があります。何故ですか?これで、サーバーとクライアント間でデータを送信するプロセスに移ります。

サーバースレッド実行フロー

クライアントは最初にサーバーでユーザー名とパスワードを検証し、合格すると正式に接続が確立されます。次にクライアントがリクエストを送信すると、サーバーはスレッド プールからスレッドを取得して処理します。処理プロセス:

1. 行を取得して net_buffer に書き込みます。このメモリのサイズは、パラメータ net_buffer_length によって定義され、デフォルトは 16k です。
2. net_buffer がいっぱいになるまで行を繰り返しフェッチし、ネットワーク インターフェイスを呼び出して行を送信します。
3. 送信が成功した場合は、net_buffer をクリアし、次の行を取得して net_buffer に書き込みます。
4. 送信関数が EAGAIN または WSAEWOULDBLOCK を返す場合、ローカル ネットワーク スタック (ソケット送信バッファー) がいっぱいであり、待機状態になることを意味します。送信を続行する前に、ネットワーク スタックが再び書き込み可能になるまで待機します。

上記のプロセスから、一度に送信するデータの量がソケットの送信バッファ領域を超えた場合は、分割して送信され、「メモリ爆発」の状況は発生しないことがわかります。このことから、MySQL は読み取りと送信を同時に行っていることがわかります。

1. リクエストによって返されるデータの量が多い場合は、戻りを待つときに show processlist を使用して State 列の値を確認します。その値は「クライアントに送信中」であり、サーバー側のネットワーク スタックがいっぱいであることを示します。

これは、クエリ要求が到着して実行が開始されると、Sate 列の値が変わり、「データを送信中」となるためです。ネットワーク スタックがいっぱいになると、「クライアントに送信中」に切り替わり、「クライアントが結果を受信するのを待機中」となります。 「データの送信」は、ロックによってブロックされるなど、スレッド実行プロセスのどの段階でも発生する可能性があります。

2. show processlistの状態列が常に「クライアントに送信中」の場合は、

1) この SQL ステートメントをチェックして、戻り値を減らすように最適化できるかどうかを確認します。

2) 送信ブロックを回避または時間を短縮するには、net_buffer_length をより大きな値に設定します。

クライアント実行プロセス

最初に、クライアントはサーバーに接続するためのスレッドを作成し、サーバーから返されたデータを受信します。クライアントがサーバーから返されたデータを受信するには、次の 2 つの方法があります。

1. ローカル キャッシュ。メモリの一部をローカルで開き、まず結果を保存します。 API を使用して開発する場合、対応するメソッドは mysql_store_result です。クライアントの処理量が大きい場合は、ローカル キャッシュを使用することをお勧めします。返されたデータを指定したファイルに保存するには、mysql -h$host -P$port -u$user -p$pwd -e "select * from db1.t" > $target_file を使用できます。

2. キャッシュせず、一度に 1 つずつ読み取って処理します。 API を使用して開発する場合、対応するメソッドは mysql_use_result です。

上記の質問に戻りますが、-quick を使用するとクライアントのパフォーマンスが低下する可能性があるのはなぜでしょうか?これは、クライアントがデフォルトでキャッシュを使用して受信するため、クライアントが他のデータを処理しているときに、最初にそれをキャッシュし、後でキャッシュを直接読み取ることができるためです。 quick を使用すると、クライアントはキャッシュを使用せずにデータを受信します。クライアントが他の操作を実行している場合、データはブロックされ、サーバー上の対応するスレッドはクライアントからのフィードバックを受信して​​いないため、トランザクションを中断しません。このトランザクションに関係するリソース ロックは解放されないため、同時実行の問題が発生し、効率に影響します。さらに、クイックにはさらに 3 つの効果があります。

1. 前述の通り、テーブル名の自動補完機能をスキップします。
2. クライアントはキャッシュせずにデータを受信します。 mysql_store_result メソッドは、クエリ結果をキャッシュするためにローカル メモリに適用する必要があります。クエリ結果が大きすぎると、ローカル メモリの消費量が増え、クライアントのローカル マシンのパフォーマンスに影響する可能性があります。
3. 実行されたコマンドはローカルコマンド履歴ファイルに記録されません。

以上がMySQL killコマンドの実行原理の詳細な説明です。MySQL killコマンドの詳細については、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できない理由

<<:  HTMLでカスタムタグを使用する方法

>>:  JS に依存せずにレスポンシブ レイアウトを実現する CSS3 モバイル vw+rem メソッド

推薦する

CSS の overflow: hidden の使い方 (オーバーフローの非表示とフロートのクリア)

オーバーフロー非表示指定された高さを超えるテキストや画像情報を非表示にすることを意味します。 <...

img usemap 属性 中国地図リンク

HTML img タグ: Web ページに導入される画像を定義します。興味深い usemap 属性も...

知っておくべき 25 の Vue のヒント

目次1. プロパティを型リストに制限する2. デフォルトのコンテンツと拡張ポイント3. ネストされた...

nginx設定ファイルの場所を見つける方法の詳細な説明

よく知らないサーバーの場合や、かなり前にインストールした場所を忘れてしまった場合、構成ファイルの場所...

Docker での Redis の永続ストレージの詳細な説明

この章では、dockerの下にあるSpring BootプロジェクトでRedisを操作し始めます。準...

誰もが登録できるようにJiedaibaoを宣伝するにはどうすればよいでしょうか? ジエダイバオのプロモーション方法とスキル

借財宝は最近人気が出ている携帯電話ローンソフトウェアプラットフォームです。知人同士の貸し借りが特徴で...

HTML と CSS を書くための 6 つの最も効果的な方法

この記事では、効率を向上させ、時間を節約することを願って、最も効果的な 6 つの方法を紹介します。 ...

mysqlはルートユーザーと一般ユーザーを作成し、機能を変更および削除します。

方法1: SET PASSWORDコマンドを使用する mysql -u ルート mysql> ...

【Webデザイン】E-WebTemplates の美しい海外の Web ページ テンプレート (FLASH+PSD ソース ファイル+HTML) を共有します

これらはすべて海外のE-WebTemplates WebサイトからのWebページテンプレートであり、...

MySQLがサブクエリと結合の使用を推奨しない理由

ページ分割されたクエリを実行するには: 1. MySQL の場合、サブクエリと結合の使用は推奨されま...

VMware Workstation 14 Pro インストール Ubuntu 16.04 チュートリアル

この記事では、VMware Workstation14 ProにUbuntu 16.04をインストー...

mysql5.7.19 zip 詳細なインストールプロセスと構成

MySQL v5.7.19 正式版(32/64 ビットインストール版および zip 解凍版) 1. ...

ナビゲーションデザインと情報アーキテクチャ

<br />ナビゲーションについて話すときは、ほとんどの場合、ナビゲーションがコンテンツ...

Vueのプラグインの仕組みとインストールの詳細を深く理解する

序文: Vue を使用する場合、多くの場合、カスタム プラグインをいくつか使用して記述し、 Vue....

Windows システムに VirtualBox と Ubuntu 16.04 をインストールするための詳細なチュートリアル

1. ソフトウェアの紹介バーチャルボックスVirtualBox は、無料のオープンソース仮想マシン ...