MYSQL source code reading 6

Pre-season

MYSQL source code reading one

MYSQL source code reading two

MYSQL source code reading three

MYSQL source code reading four

MYSQL source code reading five

I didn’t understand two questions last time

1 Why must the debugging thread be turned on? Because MYSQL is a threading model, you can also debug the entire MYSQLD service process

To use GDB, you must first set a breakpoint. MYSQLD encounters a breakpoint and all threads and services stop. For this reason, you don't need to debug the thread.

But we want to track the execution flow of a thread, which functions are executed? If the debugging process cannot be caught,

2 Why didn't the code in IF(RC) {...} be executed? I was tossing for a while, and then I thought of it a few days later and it was estimated that it did not meet the RC conditions

[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 is dead!

Kill GDB again, restart the system at most

Debug window:


(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 client window:


mysql> select * from books;

Debug window:


[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;

## What do you mean?

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

Understood! When GDB is debugging the service process, after setting the breakpoint function, the client sends an SQL request, and GDB is in a dead state at this time.

For this reason, after setting a breakpoint, enter the C command to let GDB continue. Then let the client send an SQL request, then GDB triggers the breakpoint function, and automatically switches to the thread, and stops the 1161 line, as long as N is The command can be tracked down!

This saves us the trouble of checking the client's processes, threads, and OS threads! But in a production environment, that is, when multiple users issue SQL statements at the same time, this method is estimated to be difficult.

But for us to learn the kernel source code, there are not so many concurrent client operations!

Source code:


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());

Then all the way sparks bring lightning N down, and when I meet RC P, the result is really 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)) {

After the function on line 1275 1276 is executed, the client receives the data


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); in line 1274 is this a command dispatcher?

THD is estimated to be a thread, COM_DATA is a command packet, and COMMAND is a command type

Guess you like

Origin blog.51cto.com/15080028/2643041