当前位置: 首页 > news >正文

MySQL黑盒子研究工具 strace

strace是什么?
按照 strace 官网的描述, strace 是一个可用于诊断、调试和教学的 Linux 用户空间跟踪器。我们用它来监控用户空间进程和内核的交互,比如系统调用、信号传递、进程状态变更等。

strace 底层使用内核的 ptrace 特性来实现其功能。
strace能做什么?

strace 常用来跟踪进程执行时的系统调用和所接收的信号。

在 Linux 世界,进程不能直接访问硬件设备,当进程需要访问硬件设备(比如读取磁盘文件,接收网络数据等等)时,必须由用户态模式切换至内核态模式,通过系统调用访问硬件设备。strace 可以跟踪到一个进程产生的系统调用,包括参数,返回值,执行消耗的时间。

在运维的日常工作中,故障处理和问题诊断是个主要的内容,也是必备的技能。strace 作为一种动态跟踪工具,能够帮助运维高效地定位进程和服务故障。它像是一个侦探,通过系统调用的蛛丝马迹,告诉你异常的真相。

输出参数的含义

每一行都是一条系统调用,等号左边是系统调用的函数名及其参数,右边是该调用的返回值。strace 显示这些调用的参数并返回符号形式的值。strace 从内核接收信息,而且不需要以任何特殊的方式来构建内核。

strace cat /dev/null
execve("/usr/bin/cat", ["cat", "/dev/null"], 0x7ffe33612c58 /* 28 vars */) = 0
brk(NULL)                               = 0x716000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f3cd8f60000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=33439, ...}) = 0
mmap(NULL, 33439, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f3cd8f57000
close(3)                                = 0
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`&\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2156592, ...}) = 0
mmap(NULL, 3985920, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f3cd8972000
mprotect(0x7f3cd8b36000, 2093056, PROT_NONE) = 0
mmap(0x7f3cd8d35000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c3000) = 0x7f3cd8d35000
mmap(0x7f3cd8d3b000, 16896, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f3cd8d3b000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f3cd8f56000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f3cd8f54000
arch_prctl(ARCH_SET_FS, 0x7f3cd8f54740) = 0
access("/etc/sysconfig/strcasecmp-nonascii", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/sysconfig/strcasecmp-nonascii", F_OK) = -1 ENOENT (No such file or directory)
mprotect(0x7f3cd8d35000, 16384, PROT_READ) = 0
mprotect(0x60b000, 4096, PROT_READ)     = 0
mprotect(0x7f3cd8f61000, 4096, PROT_READ) = 0
munmap(0x7f3cd8f57000, 33439)           = 0
brk(NULL)                               = 0x716000
brk(0x737000)                           = 0x737000
brk(NULL)                               = 0x737000
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=106176928, ...}) = 0
mmap(NULL, 106176928, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f3cd242f000
close(3)                                = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0
open("/dev/null", O_RDONLY)             = 3
fstat(3, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0
fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0
read(3, "", 65536)                      = 0
close(3)                                = 0
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++

参数

-c 统计每一系统调用的所执行的时间,次数和出错的次数等.
-d 输出strace关于标准错误的调试信息.
-f 跟踪由fork调用所产生的子进程.
-ff 如果提供-o filename,则所有进程的跟踪结果输出到相应的filename.pid中,pid是各进程的进程号.
-F 尝试跟踪vfork调用.在-f时,vfork不被跟踪.
-h 输出简要的帮助信息.
-i 输出系统调用的入口指针.
-q 禁止输出关于脱离的消息.
-r 打印出相对时间关于,,每一个系统调用.
-t 在输出中的每一行前加上时间信息.
-tt 在输出中的每一行前加上时间信息,微秒级.
-ttt 微秒级输出,以秒了表示时间.
-T 显示每一调用所耗的时间.
-v 输出所有的系统调用.一些调用关于环境变量,状态,输入输出等调用由于使用频繁,默认不输出.
-V 输出strace的版本信息.
-x 以十六进制形式输出非标准字符串
-xx 所有字符串以十六进制形式输出.
-a column
设置返回值的输出位置.默认 为40.
-e expr
指定一个表达式,用来控制如何跟踪.格式如下:
[qualifier=][!]value1[,value2]...
qualifier只能是 trace,abbrev,verbose,raw,signal,read,write其中之一.value是用来限定的符号或数字.默认的 qualifier是 trace.感叹号是否定符号.例如:
-eopen等价于 -e trace=open,表示只跟踪open调用.而-etrace!=open表示跟踪除了open以外的其他调用.有两个特殊的符号 all 和 none.
注意有些shell使用!来执行历史记录里的命令,所以要使用\\.
-e trace=set
只跟踪指定的系统 调用.例如:-e trace=open,close,rean,write表示只跟踪这四个系统调用.默认的为set=all.
-e trace=file
只跟踪有关文件操作的系统调用.
-e trace=process
只跟踪有关进程控制的系统调用.
-e trace=network
跟踪与网络有关的所有系统调用.
-e strace=signal
跟踪所有与系统信号有关的 系统调用
-e trace=ipc
跟踪所有与进程通讯有关的系统调用
-e abbrev=set
设定 strace输出的系统调用的结果集.-v 等与 abbrev=none.默认为abbrev=all.
-e raw=set
将指 定的系统调用的参数以十六进制显示.
-e signal=set
指定跟踪的系统信号.默认为all.如 signal=!SIGIO(或者signal=!io),表示不跟踪SIGIO信号.
-e read=set
输出从指定文件中读出 的数据.例如:
-e read=3,5
-e write=set
输出写入到指定文件中的数据.
-o filename
将strace的输出写入文件filename
-p pid
跟踪指定的进程pid.
-s strsize
指定输出的字符串的最大长度.默认为32.文件名一直全部输出.
-u username
以username 的UID和GID执行被跟踪的命令

安装

yum list|grep strace
strace.x86_64 4.24-6.el7 base

yum -y install strace.x86_64
主要用法有两种:

1.从命令行调试一个新开始的程序
strace /etc/init.d/mysqld start

2.绑定到一个已有的PID上来调试一个正在运行的程序
strace -c -p 12541

3.strace -T -tt -s 100 -o /tmp/strace.log CMD

常用命令举例:

strace -o ~/mysqld.strace -T -tt -e trace=all -p
strace -p
strace -cp

实用例子:
一、mysqld启动时读了的哪个配置文件?

我们学习 MySQL 时,从官方文档(https://dev.mysql.com/doc/refman/5.7/en/option-files.html)知道,MySQL5.7 如果不指定读取的配置文件,他是会按次序搜寻和读取加载 my.cnf 的,如下:

sequenceFile NamePurpose
1/etc/my.cnfGlobal options
2/etc/mysql/my.cnfGlobal options
3SYSCONFDIR
/my.cnf
Global options
4$MYSQL_HOME
/my.cnf
Server-specific options (server only)
5defaults-extra-fileThe file specified with --defaults-extra-file, if any
6~/.my.cnfUser-specific options
7~/.mylogin.cnfUser-specific login path options (clients only)

上面这个表格包含了 server(mysqld)、client(mysqladmin、mysqldump、mysql、mysqlbinlog 等等)的 my.cnf 搜寻顺序,还包含了编译版安装,特殊参数下的路径搜寻顺序,更准确的 mysqld 搜寻路径见下面这个:

mysqld --verbose --help |less

在第一页找到以下这两行

Default options are read from the following files in the given order:
/etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql/etc/my.cnf ~/.my.cnf

能看出 mysqld 对 my.cnf 文件的搜寻和载入顺序如下:

序号文件路径
1/etc/my.cnf
2/etc/mysql/my.cnf
3/usr/local/mysql/etc/my.cnf
4~/.my.cnf

下面我们用 strace 来调试一下看是不是,见标蓝色部分,完全一致。

[root@host-1x2-1x-1x-179 bin]# pwd
/usr/local/mysql/bin
[root@host-1x2-1x-1x-179 bin]#
[root@host-1x2-1x-1x-179 bin]# ./mysqld --version
/opt/mysql-8.0.28-linux-glibc2.12-x86_64/bin/mysqld Ver 8.0.28 for Linux on x86_64 (MySQL Community Server - GPL)
[root@host-1x2-1x-1x-179 bin]#
[root@host-1x2-1x-1x-179 bin]# strace ./mysqld 2>&1|grep my.cnf
stat(“/etc/my.cnf”, {st_mode=S_IFREG|0644, st_size=5539, …}) = 0
open(“/etc/my.cnf”, O_RDONLY) = 3
stat(“/etc/mysql/my.cnf”, 0x7ffe1c295180) = -1 ENOENT (No such file or directory)
stat(“/usr/local/mysql/etc/my.cnf”, 0x7ffe1c295180) = -1 ENOENT (No such file or directory)
stat(“/root/.my.cnf”, 0x7ffe1c295180) = -1 ENOENT (No such file or directory)
二、利⽤strace观察client端SQL执⾏

select thd_id, conn_id,user, pid, program_name,command,current_statement from sys.processlist where conn_id>0 and pid>0;

strace -T -tt -s 100 -o /tmp/strace.log -p $PID

10:51:49.814118 gettimeofday({1524192709, 814130}, NULL) = 0 <0.000009>
10:51:49.814266 write(4, "<158>2018-04-20 10:51:49 worker001 info[9185]: topic=log.xxx.xxxx_sync EAGAIN (Resource temporarily unavailable) <0.099912>
10:51:49.914265 write(4, “\n”, 1) = -1 EAGAIN (Resource temporarily unavailable) <0.100881>
10:51:50.015595 sendto(38, “|\0\0\0\3/master/SELECT * FROM idx_update_time WHERE 1 and order_no = ‘20180420104827060300005’ and kdt_id = ‘110’”, 128, MSG_DONTWAIT, NULL, 0) = 128 <0.000023>
10:51:50.015655 poll([{fd=38, events=POLLIN|POLLERR|POLLHUP}], 1, 12000) = 1 ([{fd=38, revents=POLLIN}]) <0.000526>
10:51:50.016213 recvfrom(38, “\1\0\0\1\7I\0\0\2\3def\5db”, 24, MSG_DONTWAIT, NULL, NULL) = 24 <0.000007> 10:51:50.016243 poll([{fd=38, events=POLLIN|POLLERR|POLLHUP}], 1, 12000) = 1 ([{fd=38, revents=POLLIN}]) <0.000006>
10:51:50.016262 recvfrom(38, “idx_update_time\25idx_update_time\2id\2id\f? \0\n\0\0\0\3\3B\0\0\0Q\0\0\3\3def\5xxx\25idx_update_time\25idx_update_time\6kdt_id\6kdt_id\f? \0\v\0\0\0\3)@\0\0\0U\0\0\4\3def\5xxx\25idx_update_time\25order_idx_upd”, 193, MSG_DONTWAIT, NULL, NULL) = 193 <0.000005> 10:51:50.016282 poll([{fd=38, events=POLLIN|POLLERR|POLLHUP}], 1, 12000) = 1 ([{fd=38, revents=POLLIN}]) <0.000005>

http://www.dtcms.com/a/336723.html

相关文章:

  • 基于因果性的深层语义知识图谱对文本预处理的积极影响
  • Perf使用详解
  • AI系统性思维复盘概述
  • 【FreeRTOS】事件组
  • 电力设备状态监测与健康管理:从数据感知到智能决策的技术实践​
  • 通达信【牛股妖股埋伏】副图+选股指标
  • 报错注入原理与全方法总结
  • HAL-ADC配置
  • 快速了解均值滤波处理
  • 关于动态代理的个人记录
  • CF2121B Above the Clouds
  • 【Java】多线程Thread类
  • 什么是AIGC(人工智能生成内容)
  • 牛客周赛 Round 104(小红的树不动点)
  • 人工智能入门②:AI基础知识(下)
  • 计算机程序编程软件开发设计之node..js语言开发的基于Vue框架的选课管理系统的设计与实现、基于express框架的在线选课系统的设计与实现
  • STM32——软硬件I2C
  • Font Awesome Kit 使用详解
  • OTA升级
  • Vue Router 嵌套路由与布局系统详解:从新手到精通
  • 【牛客刷题】随机加减操作:两种高效解法详解(DFS记忆化搜索和动态规划集合更新法)
  • java序列化和反序列化
  • FX10/20 (CYUSB401X)开发笔记5 固件架构
  • 【个人项目】跑者天地—测试报告
  • 深入解析二维数组传参的本质
  • 运动场和光流-动手学计算机视觉17
  • 正则表达式实用面试题与代码解析专栏
  • 【Nginx】限流设置
  • 二三层交换转发业务~基础汇总
  • Mysql笔记-错误条件\处理程序