ステータスが「データの送信中」の状態で、クエリがプロセスリストに長時間留まるのを目にしています。このステータスはどういう意味ですか?
誰かがもっと知っているなら、ギャップを埋めてください。
TL; DR「データの送信」は、クエリに関するデータを、その情報を収集する関数に送信することを意味しているようです。 MySQLまたはMariaDBクライアントにデータを送信していません。これはおそらく、JOINコマンドのアセンブリに関係しています。
インターネットで明確な説明がほとんど見つからなかったので、MariaDB 10.2のコードで「データの送信」を探し始めました(そうです、オープンソース)。私はC++ハッカーではないので、これらすべてに注意してください。
それは、 sql/mysqld.ccの行10155 にあり、_stage_sending_data
_に関連付けられています。これは sql_select.cc Line 3561 にあり、JOIN :: exec_inner関数の最後にあります。この関数は、関数JOIN :: exec()から呼び出されます。 JOIN :: execは関数mysql_select()から呼び出されます。これは、handle_select()から呼び出されます。 「データの送信」はJOINを使用したクエリでのみ表示されるようです。
私はmysql_select()がステータス「Init」またはstage_initを設定しているのを見ていると思います。次に、JOIN :: exec_inner()で「実行」またはstage_executingを実行しますが、JOINの中断や特別な注意を払っていると想定しているさまざまなことをチェックします。
次に、そのステータスを「データの送信中」またはstage_sending_dataに設定します。このステータスが設定された後の数行で、do_select(this, procedure);
が実行されます。この時点で、クエリへの回答を提供するために必要な情報の収集が実際に開始されたようです。私の期待に反して、 "データの送信"がデータをクライアントに(ネットワーク経由などで)送信するのではなく、別の機能に送信することは明らかです。まだ回答する準備ができていません。 do_select() は、一時テーブルのソート、HAVING、WHEREなどに関する条件の評価などを行います。また、ロックを解除します。 「データ送信中」以降の設定となります。
実際にデータを返す前の最後のステータス設定である可能性があります。私はそれを明確に述べるのに十分なほど掘り出していません。 do_select()で多くのことが起きるので、ステータスがどこかで変更されると思いますが、それはおそらくさまざまな要因に依存しています。 mysql_selectの最後に、ステータスを「end」またはstage_endに設定します。