加入收藏 | 设为首页 | 会员中心 | 我要投稿 大连站长网 (https://www.0411zz.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

MYSQL sql执行过程的一些追踪分析

发布时间:2022-03-30 23:09:10 所属栏目:MySql教程 来源:互联网
导读:与oracle或其他的数据库都差不多,一条sql的执行主要还是要经历了解析、优化、执行这几个过程,稍微具体下总结,MYSQL的主要过程如下: 客户端发起连接-----连接器,主要分配线程,验证权限----分析器,对sql语句语法进行分析-----优化器,生成准确的执行
         与oracle或其他的数据库都差不多,一条sql的执行主要还是要经历了解析、优化、执行这几个过程,稍微具体下总结,MYSQL的主要过程如下:
        客户端发起连接-----连接器,主要分配线程,验证权限----分析器,对sql语句语法进行分析-----优化器,生成准确的执行计划-----执行器,执行语句,发起读写数据,返回结果--之后对数据读写是io线程与存储引擎的交互
        在客户端连接部分,涉及到TCP三次握手过程,我已在《MYSQL 连接登录过程分析》中尝试进行分析。 http://blog.itpub.net/29863023/viewspace-2216731/
        尝试用strace追踪mysqld进程,观察发起一个连接去执行sql时的情况:
[root@cwdtest1 ~]# strace -f -F -ff -o mysqld-strace -s 1024 -p 62509
strace: Process 62509 attached with 32 threads
....
strace: Process 33059 attached
[root@cwdtest1 /]# mysql -uroot -pcwdroot
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 24
Server version: 5.7.23-23-log Source distribution
Copyright (c) 2009-2018 Percona LLC and/or its affiliates
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
mysql> select * from cwdtest.test;
+---------+----------+
| col1    | col2     |
+---------+----------+
|         | aaaaaaaa |
| ccccccc | NULL     |
+---------+----------+
2 rows in set (0.00 sec)
mysql> exit
Bye
从performance_schema.threads中可以看到新增的54号前台线程thread/sql/one_connection,其os 线程id是33059
 
*************************** 31. row ***************************
          THREAD_ID: 54
               NAME: thread/sql/one_connection
               TYPE: FOREGROUND
     PROCESSLIST_ID: 28
   PROCESSLIST_USER: root
   PROCESSLIST_HOST: localhost
     PROCESSLIST_DB: NULL
PROCESSLIST_COMMAND: Sleep
   PROCESSLIST_TIME: 10
  PROCESSLIST_STATE: NULL
   PROCESSLIST_INFO: NULL
   PARENT_THREAD_ID: 1
               ROLE: NULL
       INSTRUMENTED: YES
            HISTORY: YES
    CONNECTION_TYPE: Socket
       THREAD_OS_ID: 33059 《======
31 rows in set (0.00 sec)
分析strace的过程信息:
获取线程id33059,之后设置 setsockopt状态。这里看到open  /dev/urandom,这是获取一个随机编号
set_robust_list(0x7f9aa60ea9e0, 24) = 0
gettid() = 33059
setsockopt(67, SOL_TCP, TCP_NODELAY, [1], 4) = -1 EOPNOTSUPP (Operation not supported)
setsockopt(67, SOL_SOCKET, SO_KEEPALIVE, [1], 4) = 0
open("/dev/urandom", O_RDONLY) = 68
read(68, "'275|274277200Uw22053)M4E364C37221022223534533I216252206M336C;372", 32) = 32
close(68) = 0
之后是密码验证,以及一些版本消息等
 
sendto(67, "Qn5.7.23-23-log34{PR&1|0 377367!237720125426:5.h34U"G%amysql_native_password", 85, MSG_DONTWAIT, NULL, 0) = 85
recvfrom(67, "2721", 4, MSG_DONTWAIT, NULL, NULL) = 4
recvfrom(67, "20524637711!root24v10A216"344i31'331UMa"35643640!331mysql_native_passwordi3_os5Linuxf_client_name10libmysql4_pid053305817_client_versiont5.7.23-23t_platform6x86_64fprogram_name5mysql", 186, MSG_DONTWAIT, NULL, NULL) = 186
sendto(67, "722", 11, MSG_DONTWAIT, NULL, 0) = 11
recvfrom(67, "!", 4, MSG_DONTWAIT, NULL, NULL) = 4
recvfrom(67, "3select @@version_comment limit 1", 33, MSG_DONTWAIT, NULL, NULL) = 33
sendto(67, "111'23def21@@version_commentf!0093753724323Source distribution743762", 83, MSG_DONTWAIT, NULL, 0) = 83
recvfrom(67, 0x7f9a9000a730, 4, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=67, events=POLLIN|POLLPRI}], 1, 28800000) = 1 ([{fd=67, revents=POLLIN}])
接受到shelect 的查询语句,我们可以看到 会stat ./cwdtest/test.frm 这个文件,这里是 获取文件信息,并在去访问./cwdtest/test.TRG,发现提示No such file or directory。
 
recvfrom(67, "33", 4, MSG_DONTWAIT, NULL, NULL) = 4
recvfrom(67, "3select * from cwdtest.test", 27, MSG_DONTWAIT, NULL, NULL) = 27
stat("./cwdtest/test.frm", {st_mode=S_IFREG|0640, st_size=8590, ...}) = 0
access("./cwdtest/test.TRG", F_OK) = -1 ENOENT (No such file or directory)
sendto(67, "112-23def7cwdtest4test4test4col14col1f!36375120-33def7cwdtest4test4test4col24col2f!36375n410aaaaaaaat57ccccccc37376376"", 141, MSG_DONTWAIT, NULL, 0) = 141
recvfrom(67, 0x7f9a9000a730, 4, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=67, events=POLLIN|POLLPRI}], 1, 28800000) = 1 ([{fd=67, revents=POLLIN|POLLHUP}])
recvfrom(67, "1", 4, MSG_DONTWAIT, NULL, NULL) = 4
recvfrom(67, "1", 1, MSG_DONTWAIT, NULL, NULL) = 1
shutdown(67, SHUT_RDWR) = 0
close(67) = 0
futex(0x1dca184, FUTEX_WAIT_PRIVATE, 46, NULL <detached ...>
(END)
来看看./cwdtest/test.frm  和 ./cwdtest/test.TRG两个文件:
frm是MySQL的表结构定义文件,通过hexdump可以查看其中16进制数据
[root@cwdtest1 cwdtest]# hexdump -C -v test.frm
00002130  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |                |
00002140  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 00  |               .|
00002150  04 00 05 63 6f 6c 31 00  05 00 05 63 6f 6c 32 00  |...col1....col2.|
00002160  04 05 1e 1e 00 02 00 00  00 40 00 00 00 0f 21 00  |.........@....!.|
00002170  00 05 05 1e 1e 00 21 00  00 00 80 00 00 00 0f 21  |......!........!|
00002180  00 00 ff 63 6f 6c 31 ff  63 6f 6c 32 ff 00        |...col1.col2..|
以上列信息整理可得:
04 05 1e 1e 00 02 00 00 00 40 00 00 00 0f 21 00 00 --- 字段col1
05 05 1e 1e 00 21 00 00 00 80 00 00 00 0f 21 00 00-----字段col2
以col1字段为例:
其中04代表 列序号(初始列序号为4),
1e 表示字段长度,1e转化成十进制是30,表中是字是 varchar( 10 ),字符集是utf8占3bit,所以长度是10*3=30.
40表示不可为空,(DEFAULT NULL 80,NOT NULL 40,DEFAULT 'VALUE' 00)
0f表示字段类型是varhcar    
21表示字符集是utf8
表创建语句:
| test | CREATE TABLE `test` (
  `col1` varchar(10) NOT NULL,
  `col2` varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
TRG文件是mysql中记录触发器的定义,很明显这里test表并没有创建触发器。
sendto(67, "112-23def7cwdtest4test4test4col14col1f!36375120-33def7cwdtest4test4test4col24col2f!36375n410aaaaaaaat57ccccccc37376376"", 141, MSG_DONTWAIT, NULL, 0) = 141
之后便是调用sendto函数,往客户端发送结果。
当退出时便是关闭。
shutdown(67, SHUT_RDWR) = 0
close(67) = 0
在以上的trace日志里每个函数操作的对象基本都是67,67则是文件描述符,而这里对应的是socket。
[root@cwdtest1 fd]# ls -rtl 672
lrwx------ 1 root root 64 Jan 19 11:19 67 -> socket:[16206507]

(编辑:大连站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!