MYSQLソースコードの読み取り6

プレシーズン

1つを読み取るMYSQLソースコード

2つを読み取るMYSQLソースコード

3つを読み取るMYSQLソースコード

4つを読み取るMYSQLソースコード

5つを読み取るMYSQLソースコード

前回は2つの質問がわかりませんでした

1デバッグスレッドをオンにする必要があるのはなぜですか?MYSQLはスレッドモデルであるため、MYSQLDサービスプロセス全体をデバッグすることもできます。

GDBを使用するには、最初にブレークポイントを設定する必要があります。MYSQLDでブレークポイントが検出され、すべてのスレッドとサービスが停止します。このため、スレッドをデバッグする必要はありません。

しかし、どの関数が実行されるか、スレッドの実行フローを追跡したいですか?デバッグプロセスをキャッチできない場合は、

2 IF(RC){...}のコードが実行されなかったのはなぜですか?しばらく投げていたのですが、数日後に考えてみたところ、RC条件を満たしていないことが推定されました。

[root@localhost ~]# gdp -p 6041
(gdb) b do_command
Breakpoint 1 at 0x3616c8e: file /u01/mysql/source/mysql-8.0.20/sql/sql_parse.cc, line 1161.
(gdb) n
Single stepping until exit from function poll,
which has no line number information.

GDBは死んでいます!

GDBを再度強制終了し、最大でシステムを再起動します

デバッグウィンドウ:


(gdb) b do_command
Breakpoint 1 at 0x3616c8e: file /u01/mysql/source/mysql-8.0.20/sql/sql_parse.cc, line 1161.
(gdb) c
Continuing.

MySQLクライアントウィンドウ:


mysql> select * from books;

デバッグウィンドウ:


[Switching to Thread 0x7f1f940f5700 (LWP 3398)]
Breakpoint 1, do_command (thd=0x7f1f6c006790)
    at /u01/mysql/source/mysql-8.0.20/sql/sql_parse.cc:1161
1161      NET *net = nullptr;

## どういう意味ですか?

info thread
* 2    Thread 0x7f1f940f5700 (LWP 3398) "mysqld" do_command (thd=0x7f1f6c006790)

了解しました!GDBがサービスプロセスをデバッグしているとき、ブレークポイント関数を設定した後、クライアントはSQL要求を送信し、GDBはこの時点でデッド状態になっています。

このため、ブレークポイントを設定した後、Cコマンドを入力してGDBを続行させ、クライアントにSQL要求を送信させると、GDBはブレークポイント関数をトリガーし、自動的にスレッドに切り替えて、1161行を停止します。 Nはコマンドを追跡できます!

これにより、クライアントのプロセス、スレッド、OSスレッドをチェックする手間が省けます!ただし、実稼働環境、つまり複数のユーザーが同時にSQLステートメントを発行する場合、この方法は難しいと推定されます。

しかし、カーネルのソースコードを学ぶために、同時クライアント操作はそれほど多くありません。

ソースコード:


1158 bool do_command(THD *thd) {
1159   bool return_value;
1160   int rc;
1161   NET *net = nullptr;
1162   enum enum_server_command command;
1163   COM_DATA com_data;
1164   DBUG_TRACE;
1165   DBUG_ASSERT(thd->is_classic_protocol());

それから火花と稲妻Nがずっと下がっていて、私がRC Pに会ったとき、結果は本当に0でした

(gdb) n
1164      DBUG_TRACE;
(gdb) n
1165      DBUG_ASSERT(thd->is_classic_protocol());
(gdb) n
1171      thd->lex->set_current_select(nullptr);
(gdb) n
1179      thd->clear_error();  // Clear error message
(gdb) n
1180      thd->get_stmt_da()->reset_diagnostics_area();
(gdb) n
1188      net = thd->get_protocol_classic()->get_net();
(gdb) n
1189      my_net_set_read_timeout(net, thd->variables.net_wait_timeout);
(gdb) n
1190      net_new_transaction(net);
(gdb) n
1206      DEBUG_SYNC(thd, "before_do_command_net_read");
(gdb) n
1219      thd->m_server_idle = true;
(gdb) n
1220      rc = thd->get_protocol()->get_command(&com_data, &command);
(gdb) n
1221      thd->m_server_idle = false;
(gdb) n
1223      if (rc) {
(gdb) p rc
$1 = 0
(gdb) n
1256      vio_description(net->vio, desc);
(gdb) n
1257      DBUG_PRINT("info", ("Command on %s = %d (%s)", desc, command,
(gdb) n
1260      DBUG_PRINT("info", ("packet: '%*.s'; command: %d",
(gdb) n
1263      if (thd->get_protocol_classic()->bad_packet)
(gdb) n
1267      thd->get_protocol_classic()->get_output_packet()->shrink(
(gdb) n
1268          thd->variables.net_buffer_length);
(gdb) n
1270      my_net_set_read_timeout(net, thd->variables.net_read_timeout);
(gdb) n
1272      DEBUG_SYNC(thd, "before_command_dispatch");
(gdb) n
1274      return_value = dispatch_command(thd, &com_data, command);
(gdb) n
1275      thd->get_protocol_classic()->get_output_packet()->shrink(
(gdb) n
1276          thd->variables.net_buffer_length);
(gdb) n
1280      DBUG_ASSERT(thd->m_digest == nullptr);
(gdb) n
1281      DBUG_ASSERT(thd->m_statement_psi == nullptr);
(gdb) n
1282      return return_value;
(gdb) n
1164      DBUG_TRACE;
(gdb) n
1282      return return_value;
(gdb) n
1283    }
(gdb) n
handle_connection (arg=0xa739020)
    at /u01/mysql/source/mysql-8.0.20/sql/conn_handler/connection_handler_per_thread.cc:301
301          while (thd_connection_alive(thd)) {

1275 1276行目の関数が実行された後、クライアントはデータを受信します


Breakpoint 1, do_command (thd=0x7f1f6c006790)
    at /u01/mysql/source/mysql-8.0.20/sql/sql_parse.cc:1161
1161      NET *net = nullptr;
(gdb) n
1164      DBUG_TRACE;
(gdb) n
1165      DBUG_ASSERT(thd->is_classic_protocol());
(gdb) n
1171      thd->lex->set_current_select(nullptr);
(gdb) n
1179      thd->clear_error();  // Clear error message
(gdb) n
1180      thd->get_stmt_da()->reset_diagnostics_area();
(gdb) n
1188      net = thd->get_protocol_classic()->get_net();
(gdb) n
1189      my_net_set_read_timeout(net, thd->variables.net_wait_timeout);
(gdb) n
1190      net_new_transaction(net);
(gdb) n
1206      DEBUG_SYNC(thd, "before_do_command_net_read");
(gdb) n
1219      thd->m_server_idle = true;
(gdb) n
1220      rc = thd->get_protocol()->get_command(&com_data, &command);
(gdb) n
1221      thd->m_server_idle = false;
(gdb) n
1223      if (rc) {
(gdb) n
1256      vio_description(net->vio, desc);
(gdb) n
1257      DBUG_PRINT("info", ("Command on %s = %d (%s)", desc, command,
(gdb) n
1260      DBUG_PRINT("info", ("packet: '%*.s'; command: %d",
(gdb) n
1263      if (thd->get_protocol_classic()->bad_packet)
(gdb) n
1267      thd->get_protocol_classic()->get_output_packet()->shrink(
(gdb) n
1268          thd->variables.net_buffer_length);
(gdb) n
1270      my_net_set_read_timeout(net, thd->variables.net_read_timeout);
(gdb) n
1272      DEBUG_SYNC(thd, "before_command_dispatch");
(gdb) n
1274      return_value = dispatch_command(thd, &com_data, command);
(gdb) p thd
$17 = (THD *) 0x7f1f6c006790
(gdb) p com_data
$18 = {com_init_db = {db_name = 0x7f1f6c00bbe1 "select * from books", length = 19}, 
  com_refresh = {options = 225 '\341'}, com_kill = {id = 139772932701153}, 
  com_set_option = {opt_command = 1811987425}, com_stmt_execute = {
    stmt_id = 139772932701153, open_cursor = 19, parameters = 0x7f1f6c00bbe8, 
    parameter_count = 139772932688388, has_new_types = 32 ' '}, com_stmt_fetch = {
    stmt_id = 139772932701153, num_rows = 19}, com_stmt_send_long_data = {
    stmt_id = 139772932701153, param_number = 19, longdata = 0x7f1f6c00bbe8 "* from books", 
    length = 139772932688388}, com_stmt_prepare = {
    query = 0x7f1f6c00bbe1 "select * from books", length = 19}, com_stmt_close = {
    stmt_id = 1811987425}, com_stmt_reset = {stmt_id = 1811987425}, com_query = {
    query = 0x7f1f6c00bbe1 "select * from books", length = 19}, com_field_list = {
    table_name = 0x7f1f6c00bbe1 "select * from books", table_name_length = 19, 
    query = 0x7f1f6c00bbe8 "* from books", query_length = 1811974660}}
(gdb) p command
$19 = COM_QUERY
(gdb) n
1275      thd->get_protocol_classic()->get_output_packet()->shrink(
(gdb) n
1276          thd->variables.net_buffer_length);

Dispatch_command(thd、&com_data、command); 1274行目でこれはコマンドディスパッチャーですか?

THDはスレッドと推定され、COM_DATAはコマンドパケット、COMMANDはコマンドタイプです。

おすすめ

転載: blog.51cto.com/15080028/2643041