MYSQL 源码阅读 五
祖仙教小凡仙 海鲨数据库架构师
前期节要 MYSQL源码阅读 一 MYSQL源码阅读 二 MYSQL源码阅读 三 MYSQL 源码阅读 四
第四部分我们调试的是客户端进程的函数,而服务端虽然涉及了些,不过因为MYSQL是线程模型,调试进程反而抓不到!
MYSQL客户端操作:
mysql> show databases; +--------------------+ | Database | +--------------------+ | bookstore | | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 5 rows in set (0.00 sec) mysql> use bookstore; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show tables; +---------------------+ | Tables_in_bookstore | +---------------------+ | books | | books2 | +---------------------+ 2 rows in set (0.00 sec) mysql> select * from books; +----+------------------------+-------+---------------------+ | id | title | price | publishDate | +----+------------------------+-------+---------------------+ | 1 | Java编程思想 | 98.50 | 2005-01-02 0 | | 2 | HeadFirst设计模式 | 55.70 | 2010-11-09 0 | | 3 | 第一行Android代码 | 69.90 | 2015-06-23 0 | | 4 | C++编程思想 | 88.50 | 2004-01-09 0 | | 5 | HeadFirst Java | 55.70 | 2013-12-17 0 | | 6 | 疯狂Android | 19.50 | 2014-07-31 0 | +----+------------------------+-------+---------------------+ 6 rows in set (0.05 sec) mysql> show processlist; +----+-----------------+-----------+-----------+---------+-------+------------------------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+-----------------+-----------+-----------+---------+-------+------------------------+------------------+ | 5 | event_scheduler | localhost | NULL | Daemon | 12096 | Waiting on empty queue | NULL | | 14 | root | localhost | bookstore | Query | 0 | starting | show processlist | +----+-----------------+-----------+-----------+---------+-------+------------------------+------------------+ 2 rows in set (0.00 sec) +-----------+----------------+------------------+------------------+----------------+--------------+------------+ | thread_id | processlist_id | processlist_user | processlist_host | processlist_db | thread_os_id | type | +-----------+----------------+------------------+------------------+----------------+--------------+------------+ | 43 | 5 | NULL | NULL | NULL | 14183 | FOREGROUND | | 46 | 7 | NULL | NULL | NULL | 14187 | FOREGROUND | | 54 | 14 | root | localhost | bookstore | 24760 | FOREGROUND | +-----------+----------------+------------------+------------------+----------------+--------------+------------+ 3 rows in set (0.01 sec)
一顿操作猛如虎 重点就是抓到 进程->MYSQL线程->系统线程 注意这里是 14->54->24760
GDB 操作:
[root@localhost ~]# clear [root@localhost ~]# ps -ef | grep mysqld root 13815 1 0 19:11 pts/1 0 /bin/sh /u01/mysql/mysql8020debug/bin/mysqld_safe --datadir=/u01/mysql/mysql8020debug/data --pid-file=/u01/mysql/mysql8020debug/data/localhost.localdomain.pid mysql 14138 13815 1 19:11 pts/1 00:02:03 /u01/mysql/mysql8020debug/bin/mysqld --basedir=/u01/mysql/mysql8020debug --datadir=/u01/mysql/mysql8020debug/data --plugin-dir=/u01/mysql/mysql8020debug/lib/plugin --user=mysql --log-error=/u01/mysql/mysql8020debug/mysql-error.log --pid-file=/u01/mysql/mysql8020debug/data/localhost.localdomain.pid --socket=/tmp/mysql.sock --port=3306
##使用GDB调试MYSQLD 选择第二个 MYSQL用户下的进程14138 ##为什么不是13185
(gdb) info thread Id Target Id Frame * 1 process 13815 "mysqld_safe" 0x00007f9214a9046c in waitpid () from /lib64/libc.so.6
##因为它是MYSQLD_SAFE
[root@localhost mysql8020debug]# clear [root@localhost mysql8020debug]# gdb -p 14138 GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-51.el7 Copyright (C) 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-redhat- Linux -gnu". For bug reporting instructions, please see: <http://HdhCmsTestgnu.org/software/gdb/bugs/>. Attaching to process 14138 Reading symbols from /u01/mysql/mysql8020debug/bin/mysqld... ##等5秒 它读取进程DEBUG信息 done. (no debugging symbols found)...done. Loaded symbols for /lib64/libnss_dns.so.2 0x00007f868dde1c3d in poll () from /lib64/libc.so.6 Missing separate debuginfos, use: debuginfo-install glibc-2.17-307.el7.1.x86_64 keyutils-libs-1.5.8-3.el7.x86_64 krb5-libs-1.11.3-49.el7.x86_64 krb5-libs-1.15.1-46.el7.x86_64 libcom_err-1.42.9-17.el7.x86_64 libcom_err-1.42.9-4.el7.x86_64 libgcc-4.8.5-39.el7.x86_64 libse Linux -2.2.2-6.el7.x86_64 libse Linux -2.5-15.el7.x86_64 nss-softokn-freebl-3.15.4-2.el7.x86_64 openssl-libs-1.0.1e-34.el7.x86_64 openssl-libs-1.0.2k-19.el7.x86_64 pcre-8.32-12.el7.x86_64 pcre-8.32-17.el7.x86_64 sssd-client-1.11.2-65.el7.x86_64 zlib-1.2.7-13.el7.x86_64 zlib-1.2.7-18.el7.x86_64 (gdb) (gdb) ##等待你输入命令
##查看线程
(gdb) info thread Id Target Id Frame 42 Thread 0x7f867f4a7700 (LWP 14141) "mysqld" 0x00007f868fb47a35 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 41 Thread 0x7f867e29a700 (LWP 14142) "mysqld" 0x00007f868fb47a35 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 40 Thread 0x7f867da99700 (LWP 14143) "mysqld" 0x00007f868fb47a35 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 39 Thread 0x7f867d298700 (LWP 14144) "mysqld" 0x00007f868fb47a35 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 38 Thread 0x7f867ca97700 (LWP 14145) "mysqld" 0x00007f868fb47a35 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 37 Thread 0x7f86679ff700 (LWP 14146) "mysqld" 0x00007f868fb47a35 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 36 Thread 0x7f86671fe700 (LWP 14147) "mysqld" 0x00007f868fb47a35 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 35 Thread 0x7f86669fd700 (LWP 14148) "mysqld" 0x00007f868fb47a35 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 34 Thread 0x7f86661fc700 (LWP 14149) "mysqld" 0x00007f868fb47a35 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 33 Thread 0x7f86659fb700 (LWP 14150) "mysqld" 0x00007f868fb47a35 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 32 Thread 0x7f86651fa700 (LWP 14151) "mysqld" 0x00007f868fb47de2 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 31 Thread 0x7f86649f9700 (LWP 14152) "mysqld" 0x00007f868fb47de2 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 30 Thread 0x7f863dffd700 (LWP 14153) "mysqld" 0x00007f868fb47de2 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 29 Thread 0x7f863d7fc700 (LWP 14154) "mysqld" 0x00007f868fb47de2 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 28 Thread 0x7f863cffb700 (LWP 14155) "mysqld" 0x00007f868fb47de2 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 27 Thread 0x7f863c7fa700 (LWP 14156) "mysqld" 0x00007f868fb47de2 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 26 Thread 0x7f863bff9700 (LWP 14157) "mysqld" 0x00007f868fb47de2 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 25 Thread 0x7f863b7f8700 (LWP 14161) "mysqld" 0x00007f868fb47de2 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 24 Thread 0x7f863aff7700 (LWP 14162) "mysqld" 0x00007f868fb47de2 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 23 Thread 0x7f863a7f6700 (LWP 14163) "mysqld" 0x00007f868fb47de2 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 22 Thread 0x7f8639ff5700 (LWP 14166) "mysqld" 0x00007f868fb47a35 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 21 Thread 0x7f86397f4700 (LWP 14167) "mysqld" 0x00007f868fb4ae9d in nanosleep () from /lib64/libpthread.so.0 20 Thread 0x7f8638ff3700 (LWP 14168) "mysqld" 0x00007f868fb47de2 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 19 Thread 0x7f862bfff700 (LWP 14169) "mysqld" 0x00007f868fb47de2 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 18 Thread 0x7f867ea42700 (LWP 14170) "xpl_worker0" 0x00007f868fb47de2 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 17 Thread 0x7f867e9fb700 (LWP 14171) "xpl_worker1" 0x00007f868fb47de2 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 16 Thread 0x7f867e9b4700 (LWP 14172) "mysqld" 0x00007f868fb47a35 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 15 Thread 0x7f868074c700 (LWP 14177) "mysqld" 0x00007f868fb47a35 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 14 Thread 0x7f862b7fe700 (LWP 14178) "mysqld" 0x00007f868fb47de2 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 13 Thread 0x7f862affd700 (LWP 14179) "mysqld" 0x00007f868fb47a35 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 12 Thread 0x7f862a7fc700 (LWP 14180) "mysqld" 0x00007f868fb47a35 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 11 Thread 0x7f8629ffb700 (LWP 14181) "mysqld" 0x00007f868fb47a35 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 10 Thread 0x7f86297fa700 (LWP 14182) "mysqld" 0x00007f868fb47a35 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 9 Thread 0x7f867e96d700 (LWP 14183) "mysqld" 0x00007f868fb47a35 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 8 Thread 0x7f867e925700 (LWP 14184) "mysqld" 0x00007f868dd2558a in sigwaitinfo () from /lib64/libc.so.6 7 Thread 0x7f867e8dd700 (LWP 14185) "mysqld" 0x00007f868dde6bf9 in syscall () from /lib64/libc.so.6 6 Thread 0x7f8628ff9700 (LWP 14187) "mysqld" 0x00007f868fb47a35 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 5 Thread 0x7f867c275700 (LWP 24685) "mysqld" 0x00007f868fb47a35 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 ---Type <return> to continue, or q <return> to quit--- 4 Thread 0x7f86641f8700 (LWP 24725) "mysqld" 0x00007f868fb47a35 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 3 Thread 0x7f86641b0700 (LWP 24760) "mysqld" 0x00007f868dde1cff in ppoll () from /lib64/libc.so.6 2 Thread 0x7f8664168700 (LWP 25684) "mysqld" 0x00007f868fb47a35 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 * 1 Thread 0x7f868ff58980 (LWP 14138) "mysqld" 0x00007f868dde1c3d in poll () from /lib64/libc.so.6
##在众多线程中哪个是我们的客户端线程呢?
LWP 24760==>THREAD_OS_ID
##切换到对应的线程上 3
(gdb) thread 3 [Switching to thread 3 (Thread 0x7f86641b0700 (LWP 24760))] #0 0x00007f868dde1cff in ppoll () from /lib64/libc.so.6
##打印堆栈信息:
(gdb) bt #0 0x00007f868dde1cff in ppoll () from /lib64/libc.so.6 #1 0x00000000055a00bf in vio_io_wait (vio=0x7f8658001920, event=VIO_IO_EVENT_READ, timeout=28800000) at /u01/mysql/source/mysql-8.0.20/vio/viosocket.cc:842 #2 0x000000000559eb44 in vio_socket_io_wait (vio=0x7f8658001920, event=VIO_IO_EVENT_READ) at /u01/mysql/source/mysql-8.0.20/vio/viosocket.cc:105 #3 0x000000000559ecdd in vio_read (vio=0x7f8658001920, buf=0x7f8658006c50 "\001", size=4) at /u01/mysql/source/mysql-8.0.20/vio/viosocket.cc:168 #4 0x00000000037d61fb in net_read_raw_loop (net=0x7f86580048d8, count=4) at /u01/mysql/source/mysql-8.0.20/sql-common/net_serv.cc:1221 #5 0x00000000037d6512 in net_read_packet_header (net=0x7f86580048d8) at /u01/mysql/source/mysql-8.0.20/sql-common/net_serv.cc:1304 #6 0x00000000037d6e27 in net_read_packet (net=0x7f86580048d8, complen=0x7f86641afa80) at /u01/mysql/source/mysql-8.0.20/sql-common/net_serv.cc:1594 #7 0x00000000037d70c1 in my_net_read (net=0x7f86580048d8) at /u01/mysql/source/mysql-8.0.20/sql-common/net_serv.cc:1684 #8 0x0000000003bff056 in Protocol_classic::read_packet (this=0x7f8658002130) at /u01/mysql/source/mysql-8.0.20/sql/protocol_classic.cc:1404 #9 0x0000000003bffc1d in Protocol_classic::get_command (this=0x7f8658002130, com_data=0x7f86641afbd0, cmd=0x7f86641afbfc) at /u01/mysql/source/mysql-8.0.20/sql/protocol_classic.cc:2809 #10 0x0000000003616dd7 in do_command (thd=0x7f8658002db0) at /u01/mysql/source/mysql-8.0.20/sql/sql_parse.cc:1220 #11 0x00000000037db47f in handle_connection (arg=0xa13d2e0) at /u01/mysql/source/mysql-8.0.20/sql/conn_handler/connection_handler_per_thread.cc:302 #12 0x0000000005330060 in pfs_spawn_thread (arg=0xa161680) at /u01/mysql/source/mysql-8.0.20/storage/perfschema/pfs.cc:2854 #13 0x00007f868fb43ea5 in start_thread () from /lib64/libpthread.so.0 #14 0x00007f868ddec8dd in clone () from /lib64/libc.so.6
##设置断点函数 my_net_read
(gdb) b my_net_read Breakpoint 1 at 0x37d7058: file /u01/mysql/source/mysql-8.0.20/sql-common/net_serv.cc, line 1681.
##客户端发起SQL语句
mysql> select * from books;
##你会发现它卡着,不返回任何数据
##GDB 单步调试 一路火花带闪电 你可以输入C命令 然后碰到断点函数就停下来,我们这里N 过去
(gdb) n Single stepping until exit from function ppoll, which has no line number information. vio_io_wait (vio=0x7f8658001920, event=VIO_IO_EVENT_READ, timeout=28800000) at /u01/mysql/source/mysql-8.0.20/vio/viosocket.cc:846 846 } while (ret < 0 && vio_should_retry(vio) && (gdb) n 834 do { (gdb) n 850 vio->poll_shutdown_flag.clear(); (gdb) n 853 switch (ret) { (gdb) n 866 DBUG_ASSERT(pfd.revents & revents); (gdb) n 867 break; (gdb) n 870 MYSQL_END_SOCKET_WAIT(locker, 0); (gdb) n 871 return ret; (gdb) n 788 DBUG_TRACE; (gdb) n 872 } (gdb) n vio_socket_io_wait (vio=0x7f8658001920, event=VIO_IO_EVENT_READ) at /u01/mysql/source/mysql-8.0.20/vio/viosocket.cc:116 116 ret = 0; (gdb) n 117 break; (gdb) n 120 return ret; (gdb) n 121 } (gdb) n vio_read (vio=0x7f8658001920, buf=0x7f8658006c50 "\001", size=4) at /u01/mysql/source/mysql-8.0.20/vio/viosocket.cc:146 146 while ((ret = mysql_socket_recv(vio->mysql_socket, (SOCKBUF_T *)buf, size, (gdb) n 170 return ret; (gdb) n 138 DBUG_TRACE; (gdb) p buf $1 = (uchar *) 0x7f8658006c50 "\024" (gdb) dislplay Undefined command: "dislplay". Try "help". (gdb) dislpaly Undefined command: "dislpaly". Try "help". (gdb) display (gdb) n 171 } (gdb) n net_read_raw_loop (net=0x7f86580048d8, count=4) at /u01/mysql/source/mysql-8.0.20/sql-common/net_serv.cc:1224 1224 if (recvcnt == VIO_SOCKET_ERROR) { (gdb) n 1232 else if (!recvcnt) { (gdb) n 1237 count -= recvcnt; (gdb) n 1238 buf += recvcnt; (gdb) n 1240 thd_increment_bytes_received(recvcnt); (gdb) p buf $2 = (uchar *) 0x7f8658006c54 "\004-" (gdb) n 1220 while (count) { (gdb) n 1245 if (count) { (gdb) n 1266 return count != 0; (gdb) n 1267 } (gdb) n net_read_packet_header (net=0x7f86580048d8) at /u01/mysql/source/mysql-8.0.20/sql-common/net_serv.cc:1305 1305 server_extension->m_after_header(net, user_data, count, rc); (gdb) p user_data $3 = (void *) 0x7f8658002db0 (gdb) p count $4 = 4 (gdb) n 1312 if (rc) return true; (gdb) n 1314 DBUG_DUMP("packet_header", net->buff + net->where_b, NET_HEADER_SIZE); (gdb) n 1316 pkt_nr = net->buff[net->where_b + 3]; (gdb) n 1322 if (pkt_nr != (uchar)net->pkt_nr) { (gdb) n 1340 net->pkt_nr++; (gdb) n 1342 return false; (gdb) n 1343 } (gdb) n net_read_packet (net=0x7f86580048d8, complen=0x7f86641afa80) at /u01/mysql/source/mysql-8.0.20/sql-common/net_serv.cc:1596 1596 net->compress_pkt_nr = net->pkt_nr; (gdb) n 1598 if (net->compress) { (gdb) n 1614 pkt_len = uint3korr(net->buff + net->where_b); (gdb) n 1617 if (!pkt_len) goto end; (gdb) n 1619 pkt_data_len = max(pkt_len, *complen) + net->where_b; (gdb) n 1622 if ((pkt_data_len >= net->max_packet) && net_realloc(net, pkt_data_len)) (gdb) n 1626 if (net_read_raw_loop(net, pkt_len)) goto error; (gdb) n 1629 DBUG_DUMP("net read", net->buff + net->where_b, pkt_len); (gdb) n 1630 net->reading_or_writing = 0; (gdb) n 1631 return pkt_len; (gdb) n 1636 } (gdb) n my_net_read (net=0x7f86580048d8) at /u01/mysql/source/mysql-8.0.20/sql-common/net_serv.cc:1685 1685 if (len == MAX_PACKET_LENGTH) { (gdb) p len $5 = 20 (gdb) n 1697 net->read_pos = net->buff + net->where_b; (gdb) n 1698 if (len != packet_error)
终于发现了SQL,输入P命令 显示某个变量 值
(gdb) p net->read_pos $6 = (unsigned char *) 0x7f8658006c50 "\003select * from booksore\005books\005books\002id\002id\f?" (gdb)
##继续一路火花带闪电
(gdb) n 1700 return static_cast<ulong>(len); (gdb) p len $7 = 20 (gdb) n 1812 } (gdb) n Protocol_classic::read_packet (this=0x7f8658002130) at /u01/mysql/source/mysql-8.0.20/sql/protocol_classic.cc:1405 1405 if (input_packet_length != packet_error) { (gdb) n 1406 DBUG_ASSERT(!m_thd->net.error); (gdb) n 1407 bad_packet = false; (gdb) n 1408 input_raw_packet = m_thd->net.read_pos; (gdb) n 1409 return 0; (gdb) n 1414 } (gdb) n Protocol_classic::get_command (this=0x7f8658002130, com_data=0x7f86641afbd0, cmd=0x7f86641afbfc) at /u01/mysql/source/mysql-8.0.20/sql/protocol_classic.cc:2819 2819 if (input_packet_length == 0) /* safety */ (gdb) p input_packet_length $8 = 20 (gdb) n 2826 input_raw_packet[input_packet_length] = '\0'; /* safety */ (gdb) n 2828 *cmd = (enum enum_server_command)(uchar)input_raw_packet[0]; (gdb) p cmd $9 = (enum_server_command *) 0x7f86641afbfc (gdb) p *cmd $10 = COM_SLEEP (gdb) n 2830 if (*cmd >= COM_END) *cmd = COM_END; // Wrong command (gdb) p COM_END $11 = COM_END (gdb) p *cmd $12 = COM_QUERY (gdb) p cmd $13 = (enum_server_command *) 0x7f86641afbfc (gdb) p 0x7f86641afbfc $14 = 140215181835260 (gdb) n 2832 DBUG_ASSERT(input_packet_length); (gdb) n 2834 input_packet_length--; (gdb) n 2835 input_raw_packet++; (gdb) n 2837 return parse_packet(com_data, *cmd); (gdb) p com_data $15 = (COM_DATA *) 0x7f86641afbd0 (gdb) n 2838 } (gdb) n do_command (thd=0x7f8658002db0) at /u01/mysql/source/mysql-8.0.20/sql/sql_parse.cc:1221 1221 thd->m_server_idle = false;
##开启源码代码窗口,显示行号并跳到1221行
vim /u01/mysql/source/mysql-8.0.20/sql/sql_parse.cc : set number : 1221G
##定位到C++代码区
1208 /* 1209 Because of networking layer callbacks in place, 1210 this call will maintain the following instrumentation: 1211 - IDLE events 1212 - SOCKET events 1213 - STATEMENT events 1214 - STAGE events 1215 when reading a new network packet. 1216 In particular, a new instrumented statement is started. 1217 See init_net_server_extension() 1218 */ 1219 thd->m_server_idle = true; 1220 rc = thd->get_protocol()->get_command(&com_data, &command); 1221 thd->m_server_idle = false; 1222 1223 if (rc) { 1224 #ifndef DBUG_OFF 1225 char desc[VIO_DESCRIPTION_SIZE]; 1226 vio_description(net->vio, desc); 1227 DBUG_PRINT("info", ("Got error %d reading command from socket %s", 1228 net->error, desc)); 1229 #endif // DBUG_OFF 1230 /* Instrument this broken statement as "statement/com/error" */ 1231 thd->m_statement_psi = MYSQL_REFINE_STATEMENT( 1232 thd->m_statement_psi, com_statement_info[COM_END].m_key); 1233 1234 /* Check if we can continue without closing the connection */ 1235 1236 /* The error must be set. */ 1237 DBUG_ASSERT(thd->is_error()); 1238 thd->send_statement_status(); 1239 1240 /* Mark the statement completed. */ 1241 MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da()); 1242 thd->m_statement_psi = nullptr; 1243 thd->m_digest = nullptr; 1244 1245 if (rc < 0) { 1246 return_value = true; // We have to close it. 1247 goto out; 1248 } 1249 net->error = 0; 1250 return_value = false; 1251 goto out; 1252 } 1253
##GDB端奇怪的事情,执行的不是1221后面的代码 直接跳到1256行
1223 if (rc) { 1256 vio_description(net->vio, desc); 1257 DBUG_PRINT("info", ("Command on %s = %d (%s)", desc, command, 1260 DBUG_PRINT("info", ("packet: '%*.s'; command: %d", 1263 if (thd->get_protocol_classic()->bad_packet) 1267 thd->get_protocol_classic()->get_output_packet()->shrink( 1268 thd->variables.net_buffer_length); 1270 my_net_set_read_timeout(net, thd->variables.net_read_timeout); 1272 DEBUG_SYNC(thd, "before_command_dispatch"); 1274 return_value = dispatch_command(thd, &com_data, command); 1275 thd->get_protocol_classic()->get_output_packet()->shrink( 1276 thd->variables.net_buffer_length); 1280 DBUG_ASSERT(thd->m_digest == nullptr); 1281 DBUG_ASSERT(thd->m_statement_psi == nullptr); 1282 return return_value; 1164 DBUG_TRACE; 1282 return return_value; 1283 } handle_connection (arg=0xa13d2e0) at /u01/mysql/source/mysql-8.0.20/sql/conn_handler/connection_handler_per_thread.cc:301 301 while (thd_connection_alive(thd)) {
##此时MYSQL客户端获得了结果集.
mysql> select * from books; +----+------------------------+-------+---------------------+ | id | title | price | publishDate | +----+------------------------+-------+---------------------+ | 1 | Java编程思想 | 98.50 | 2005-01-02 0 | | 2 | HeadFirst设计模式 | 55.70 | 2010-11-09 0 | | 3 | 第一行Android代码 | 69.90 | 2015-06-23 0 | | 4 | C++编程思想 | 88.50 | 2004-01-09 0 | | 5 | HeadFirst Java | 55.70 | 2013-12-17 0 | | 6 | 疯狂Android | 19.50 | 2014-07-31 0 | +----+------------------------+-------+---------------------+ 6 rows in set (19 min 9.88 sec)
##发现GDB执行的函数是在1221后面的代码
1254 #ifndef DBUG_OFF 1255 char desc[VIO_DESCRIPTION_SIZE]; 1256 vio_description(net->vio, desc); 1257 DBUG_PRINT("info", ("Command on %s = %d (%s)", desc, command, 1258 command_name[command].str)); 1259 #endif // DBUG_OFF 1260 DBUG_PRINT("info", ("packet: '%*.s'; command: %d", 1261 thd->get_protocol_classic()->get_packet_length(), 1262 thd->get_protocol_classic()->get_raw_packet(), command)); 1263 if (thd->get_protocol_classic()->bad_packet) 1264 DBUG_ASSERT(0); // Should be caught earlier 1265 1266 // Reclaim some memory 1267 thd->get_protocol_classic()->get_output_packet()->shrink( 1268 thd->variables.net_buffer_length); 1269 /* Restore read timeout value */ 1270 my_net_set_read_timeout(net, thd->variables.net_read_timeout); 1271 1272 DEBUG_SYNC(thd, "before_command_dispatch"); 1273 1274 return_value = dispatch_command(thd, &com_data, command); 1275 thd->get_protocol_classic()->get_output_packet()->shrink( 1276 thd->variables.net_buffer_length); 1277 1278 out: 1279 /* The statement instrumentation must be closed in all cases. */ 1280 DBUG_ASSERT(thd->m_digest == nullptr); 1281 DBUG_ASSERT(thd->m_statement_psi == nullptr); 1282 return return_value; 1283 }
最后感觉代码量不是很多,或许BT显示堆栈函数比较少,或者N 单步调试NEXT方式没有显示更多的函数调用路径. 当然我们还是掌握了方法!
各位亲,最近微信改了推送规则,公众号文章已不是按时间先后推送文章,而是根据权重推荐文章了。
如果您看我们的推文少了,或者从来不评论、不点赞、不点在看、不转发,那您以后可能就再也收不到我们的推送了。
所以,如果您以后还想收到我们的推送,可以给标个星标,经常点在看和赞,转发分享,给我们评论留言,感谢各位亲们一路支持