MYSQL sql执行过程的一些跟踪分析(一)
发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,与oracle或其他的数据库都差不多,一条sql的执行主要还是要经历了解析、优化、执行这几个过程,稍微具体下总结,MYSQL的主要过程如下: 客户端发起连接-----连接器,主要分配线程,验证权限--
千家信息网最后更新 2025年02月01日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安全错误
数据库的锁怎样保障安全
计算机服务器运算速度
服务器管理培训心得
科技企业 转型 互联网
服务器177端口访问不了
服务器查看mysql状态
计算机网络安全防护毕业论文
ssh怎么和数据库关联
净网2019网络安全宣传活动
电网技术中心 网络安全项目
通证互联网科技有限公司
崩坏三安卓服务器可以转官服吗
高一必修一信息技术数据库
注册服务器占用大量cpu
学校网络安全专题党课
nba2k22服务器很卡
网络安全任务场景
数据库开发工程师面试题
西宁网络技术哪家好
网络安全和数字化的便利性
cnki中国学术期刊数据库
天津铁路公安处网络安全部门
流媒体服务器图片
网络安全宣传工作实施方案
数据库如何插入数据和换位置
网络安全法基本内容涉及
在sql中怎么还原数据库
小霸王软件开发
amd服务器内存
广州个性化软件开发
网吧服务器有什么系统