好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

MYSQL 源码阅读 五

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方式没有显示更多的函数调用路径. 当然我们还是掌握了方法!

各位亲,最近微信改了推送规则,公众号文章已不是按时间先后推送文章,而是根据权重推荐文章了。

如果您看我们的推文少了,或者从来不评论、不点赞、不点在看、不转发,那您以后可能就再也收不到我们的推送了。

所以,如果您以后还想收到我们的推送,可以给标个星标,经常点在看和赞,转发分享,给我们评论留言,感谢各位亲们一路支持

查看更多关于MYSQL 源码阅读 五的详细内容...

  阅读:44次

上一篇: MYSQL xtrabackup 增量备份

下一篇:中年养生