MYSQL sql执行过程的一些跟踪分析(一)
发表于:2024-09-30 作者:千家信息网编辑
千家信息网最后更新 2024年09月30日,与oracle或其他的数据库都差不多,一条sql的执行主要还是要经历了解析、优化、执行这几个过程,稍微具体下总结,MYSQL的主要过程如下: 客户端发起连接-----连接器,主要分配线程,验证权限--
千家信息网最后更新 2024年09月30日MYSQL sql执行过程的一些跟踪分析(一)与oracle或其他的数据库都差不多,一条sql的执行主要还是要经历了解析、优化、执行这几个过程,稍微具体下总结,MYSQL的主要过程如下: 客户端发起连接-----连接器,主要分配线程,验证权限----分析器,对sql语句语法进行分析-----优化器,生成准确的执行计划-----执行器,执行语句,发起读写数据,返回结果--之后对数据读写是io线程与存储引擎的交互 在客户端连接部分,涉及到TCP三次握手过程,我已在《MYSQL 连接登录过程分析》中尝试进行分析。 http://blog.itpub.net/29863023/viewspace-2216731/ 尝试用strace追踪mysqld进程,观察发起一个连接去执行sql时的情况:
frm是MySQL的表结构定义文件,通过hexdump可以查看其中16进制数据
sendto(67, "\1\0\0\1\2-\0\0\2\3def\7cwdtest\4test\4test\4col1\4col1\f!\0\36\0\0\0\375\1\20\0\0\0-\0\0\3\3def\7cwdtest\4test\4test\4col2\4col2\f!\0\36\0\0\0\375\0\0\0\0\0\n\0\0\4\0\10aaaaaaaa\t\0\0\5\7ccccccc\373\7\0\0\6\376\0\0\"\0\0\0", 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]
[root@cwdtest1 ~]# strace -f -F -ff -o mysqld-strace -s 1024 -p 62509strace: Process 62509 attached with 32 threads....strace: Process 33059 attached
[root@cwdtest1 /]# mysql -uroot -pcwdrootmysql: [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 24Server version: 5.7.23-23-log Source distributionCopyright (c) 2009-2018 Percona LLC and/or its affiliatesCopyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or itsaffiliates. Other names may be trademarks of their respectiveowners.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> exitBye
从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: NULLPROCESSLIST_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) = 0gettid() = 33059setsockopt(67, SOL_TCP, TCP_NODELAY, [1], 4) = -1 EOPNOTSUPP (Operation not supported)setsockopt(67, SOL_SOCKET, SO_KEEPALIVE, [1], 4) = 0open("/dev/urandom", O_RDONLY) = 68read(68, "'\275|\274\277\200Uw\2205\3)M\4E\364C\372\210\222\235\345\33I\216\252\206M\336C;\372", 32) = 32close(68) = 0
之后是密码验证,以及一些版本消息等
sendto(67, "Q\0\0\0\n5.7.23-23-log\0\34\0\0\0{PR&1|0 \0\377\367!\2\0\377\201\25\0\0\0\0\0\0\0\0\0\0\4\26:5.h\34U\"G%a\0mysql_native_password\0", 85, MSG_DONTWAIT, NULL, 0) = 85recvfrom(67, "\272\0\0\1", 4, MSG_DONTWAIT, NULL, NULL) = 4recvfrom(67, "\205\246\377\1\0\0\0\1!\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0root\0\24\v\10A\216\"\344i\31'\331UMa\"\356\4\3640!\331mysql_native_password\0i\3_os\5Linux\f_client_name\10libmysql\4_pid\00533058\17_client_version\t5.7.23-23\t_platform\6x86_64\fprogram_name\5mysql", 186, MSG_DONTWAIT, NULL, NULL) = 186sendto(67, "\7\0\0\2\0\0\0\2\0\0\0", 11, MSG_DONTWAIT, NULL, 0) = 11recvfrom(67, "!\0\0\0", 4, MSG_DONTWAIT, NULL, NULL) = 4recvfrom(67, "\3select @@version_comment limit 1", 33, MSG_DONTWAIT, NULL, NULL) = 33sendto(67, "\1\0\0\1\1'\0\0\2\3def\0\0\0\21@@version_comment\0\f!\0009\0\0\0\375\0\0\37\0\0\24\0\0\3\23Source distribution\7\0\0\4\376\0\0\2\0\0\0", 83, MSG_DONTWAIT, NULL, 0) = 83recvfrom(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\0\0\0", 4, MSG_DONTWAIT, NULL, NULL) = 4recvfrom(67, "\3select * from cwdtest.test", 27, MSG_DONTWAIT, NULL, NULL) = 27stat("./cwdtest/test.frm", {st_mode=S_IFREG|0640, st_size=8590, ...}) = 0access("./cwdtest/test.TRG", F_OK) = -1 ENOENT (No such file or directory)sendto(67, "\1\0\0\1\2-\0\0\2\3def\7cwdtest\4test\4test\4col1\4col1\f!\0\36\0\0\0\375\1\20\0\0\0-\0\0\3\3def\7cwdtest\4test\4test\4col2\4col2\f!\0\36\0\0\0\375\0\0\0\0\0\n\0\0\4\0\10aaaaaaaa\t\0\0\5\7ccccccc\373\7\0\0\6\376\0\0\"\0\0\0", 141, MSG_DONTWAIT, NULL, 0) = 141recvfrom(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\0\0\0", 4, MSG_DONTWAIT, NULL, NULL) = 4recvfrom(67, "\1", 1, MSG_DONTWAIT, NULL, NULL) = 1shutdown(67, SHUT_RDWR) = 0close(67) = 0futex(0x1dca184, FUTEX_WAIT_PRIVATE, 46, NULL来看看./cwdtest/test.frm 和 ./cwdtest/test.TRG两个文件:(END)
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, "\1\0\0\1\2-\0\0\2\3def\7cwdtest\4test\4test\4col1\4col1\f!\0\36\0\0\0\375\1\20\0\0\0-\0\0\3\3def\7cwdtest\4test\4test\4col2\4col2\f!\0\36\0\0\0\375\0\0\0\0\0\n\0\0\4\0\10aaaaaaaa\t\0\0\5\7ccccccc\373\7\0\0\6\376\0\0\"\0\0\0", 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]
文件
过程
分析
字段
线程
数据
语句
信息
客户
客户端
函数
字符
字符集
序号
结果
触发器
长度
尝试
验证
明显
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
psql 恢复数据库
三级数据库技术报名
庐阳区专业性网络技术咨询介绍
wpf数据库项目
网络安全的插图简笔画
2020年安徽省网络安全
adas软件开发培训
数据库操作什么情况需要用
服务器的电源适配器是什么
金仓数据库认证专家资格笔试答案
局域网 服务器 搭建
某网上书店后台数据库的部分
cs服务器如何提高fps
软件和计算机网络技术区别
怎么查看服务器时间
排序更新数据库
在数据库中存储多媒体信息
nodejs与数据库连接修改
动漫人物需要什么服务器
网络安全监控器
阿复康网络技术有限公司
数据库text带小数点
默纳克服务器怎么封门封外呼
上海京师网络技术有限公司电话
侵犯网络安全
软件开发规范的编程原则
越秀区软件开发中专
阳江自主可控软件开发价钱
南京酷盾网络安全学院
昆山培训软件开发