本文作者:夏克
OceanBase 社区文档贡献者,曾多次参与 OceanBase 技术征文比赛,获得优秀名次。从事金融行业核心系统设计开发工作多年,服务于某交易所子公司,现阶段负责国产数据库调研。
本文为 OceanBase 第七期技术征文活动「小鱼快跑|OceanBase 4.1 上手体验」的优秀投稿文章之一,分享给大家,欢迎大家评论区一起交流。
Kprobe:Kprobe 是一种内核级别追踪方式,可以在内核函数入口或出口处插入跟踪点,从而收集内核函数的参数和返回值等信息。Kprobe 可以用于跟踪内核函数的性能和行为,帮助进行系统性能分析和故障排除。
Uprobe:Uprobe是一种用户空间追踪方式,可以在用户空间程序的函数入口或出口处插入跟踪点,从而收集用户空间程序的性能数据和其他有用信息。与 Kprobe 类似,Uprobe 也可以用于跟踪用户空间程序的性能和行为,帮助进行系统性能分析和故障排除。
Tracepoint:Tracepoint 是一种内核级别追踪方式,它会在内核代码中预定义的位置插入跟踪点,从而收集内核函数的性能数据和其他有用信息。Tracepoint 的优势在于它可以在不修改内核源代码的情况下进行跟踪。
Perf:Perf 是一种内核级别追踪工具,可以用于在内核中插入跟踪点,从而收集性能数据和其他有用信息。Perf 可以用于跟踪 CPU 事件、内存事件、磁盘 I/O 事件等。
USDT(User-Level Statically Defined Tracing):USDT 是一种用户空间追踪方式,可以通过在应用程序中插入特殊的跟踪点,从而在运行时收集应用程序的性能数据和其他有用信息。USDT 使用静态定义的方式在应用程序中插入跟踪点,从而可以在应用程序不需要重新编译的情况下进行追踪。
在应用程序中添加 USDT 跟踪点:在应用程序中,通过添加类似于以下代码的宏定义,在代码中定义自己的跟踪点;
#include <sys/sdt.h>int main() {DTRACE_PROBE(MyProvider, myprobe);return 0;}
编写 eBPF 程序:编写一个 eBPF 程序,用于捕获和处理 USDT 跟踪点生成的事件。可以使用 libbpf 等工具来简化 eBPF 程序的编写和管理;
加载 eBPF 程序:通过 BPF_MAP_TYPE_PERF_EVENT_ARRAY 类型的 BPF map,将 eBPF 程序与 USDT 跟踪点关联起来,从而在跟踪点生成事件时,将事件发送到 eBPF 程序中处理。可以使用 BCC 等工具来简化 eBPF 程序的加载和管理。
分析数据:在 eBPF 程序中,可以使用 BPF_PERF_OUTPUT 类型的 BPF map,将处理后的事件发送到用户空间,并使用 BCC 等工具进行数据分析和可视化。
mkdir -p /home/frank/data/clogmkdir -p /home/frank/data/slog/servermkdir -p /home/frank/data/sstable./observer -r 127.0.0.1:2882:2881 -p 2881 -P 2882 -z zone1 -n obcluster -c 1 -d /home/frank/data -i lo -l INFO -o ob_trx_idle_timeout=120,__min_full_resource_pool_memory=2147483648,enable_syslog_recycle=True,enable_syslog_wf=True,max_syslog_file_count=4,memory_limit=6G,datafile_size=20G,log_disk_size=24G,system_memory=1G,cpu_count=16 -l ERRORobclient -h 127.0.0.1 -P 2881 -uroot
报错:ld.lld: error: undefined symbol: pthread_mutex_consistent_np
Consolidate compiler generated dependencies of target obcdc_staticConsolidate compiler generated dependencies of target obcdc[ 97%] Built target obcdc_static[ 97%] Linking CXX executable observer[ 97%] Linking CXX shared library libobcdc.sold.lld: error: undefined symbol: pthread_mutexattr_setrobust_np>>> referenced by proc_mutex.c>>> proc_mutex.o:(proc_mutex_pthread_create) in archive ../../../deps/3rd/usr/local/oceanbase/deps/devel/lib/libapr-1.a>>> did you mean: pthread_mutexattr_setrobust_np@GLIBC_2.4>>> defined in: /lib/x86_64-linux-gnu/libc.so.6ld.lld: error: undefined symbol: pthread_mutex_consistent_np>>> referenced by proc_mutex.c>>> proc_mutex.o:(proc_mutex_pthread_acquire) in archive ../../../deps/3rd/usr/local/oceanbase/deps/devel/lib/libapr-1.a>>> referenced by proc_mutex.c>>> proc_mutex.o:(proc_mutex_pthread_tryacquire) in archive ../../../deps/3rd/usr/local/oceanbase/deps/devel/lib/libapr-1.a>>> did you mean: pthread_mutex_consistent_np@GLIBC_2.4>>> defined in: /lib/x86_64-linux-gnu/libc.so.6ld.lld: error: undefined symbol: sys_siglist>>> referenced by signals.c>>> signals.o:(apr_signal_description_get) in archive ../../../deps/3rd/usr/local/oceanbase/deps/devel/lib/libapr-1.ald.lld: error: undefined symbol: pthread_yield>>> referenced by thread.c>>> thread.o:(apr_thread_yield) in archive ../../../deps/3rd/usr/local/oceanbase/deps/devel/lib/libapr-1.aclang-11: error: linker command failed with exit code 1 (use -v to see invocation)make[2]: *** [src/observer/CMakeFiles/observer.dir/build.make:154: src/observer/observer] Error 1make[1]: *** [CMakeFiles/Makefile2:10163: src/observer/CMakeFiles/observer.dir/all] Error 2make[1]: *** Waiting for unfinished jobs....[ 97%] Built target obcdcmake: *** [Makefile:166: all] Error 2
解决方法:用系统的 libapr 0.7.0 库替换依赖包中的 libapr 0.6.5 库。
# 编译内核apt-get install flex bison libssl-dev libelf-dev dwarvesgit clone https://github.com/microsoft/WSL2-Linux-Kernel.gitcd WSL2-Linux-KernelKERNEL_VERSION=$(uname -r | cut -d '-' -f 1)git checkout linux-msft-wsl-$KERNEL_VERSIONcp Microsoft/config-wsl .configmake oldconfig && make preparemake scriptsmake modulessudo make modules_installsudo mv /lib/modules/$KERNEL_VERSION-microsoft-standard-WSL2+/ /lib/modules/$KERNEL_VERSION-microsoft-standard-WSL2
CONFIG_BPF=yCONFIG_BPF_SYSCALL=y# [optional, for tc filters]CONFIG_NET_CLS_BPF=m# [optional, for tc actions]CONFIG_NET_ACT_BPF=mCONFIG_BPF_JIT=y# [for Linux kernel versions 4.1 through 4.6]CONFIG_HAVE_BPF_JIT=y# [for Linux kernel versions 4.7 and later]CONFIG_HAVE_EBPF_JIT=y# [optional, for kprobes]CONFIG_BPF_EVENTS=y# Need kernel headers through /sys/kernel/kheaders.tar.xzCONFIG_IKHEADERS=y
sudo apt install liblzma-devsudo apt install libclang-14-devgit clone https://github.com/iovisor/bcc.gitmkdir bcc/build; cd bcc/buildcmake ..makesudo make installcmake -DPYTHON_CMD=python3 .. # build python3 bindingpushd src/python/makesudo make installpopd
增加头文件,包含必要的静态跟踪点;
增加探针;
注意,目前 DTRACE_PROBE 函数最多支持 12 个参数。
重新编译 observer
$ tplist-bpfcc -l /home/frank/github/oceanbase/build_debug/src/observer/observer# 注意:要使用绝对路径
$ readelf -n observer#!/usr/bin/pythonfrom __future__ import print_functionfrom bcc import BPF, USDTfrom bcc.utils import printbimport sysif len(sys.argv) < 2:print("USAGE: OceanBase_latency PID")exit()pid = sys.argv[1]debug = 0# load BPF programbpf_text = """#include <uapi/linux/ptrace.h>int do_trace(struct pt_regs *ctx) {uint64_t addr;char query[128];bpf_usdt_readarg(1, ctx, &addr);bpf_probe_read_user(&query, sizeof(query), (void *)addr);bpf_trace_printk("%s\\n", query);return 0;};"""# enable USDT probe from given PIDu = USDT(pid=int(pid))u.enable_probe(probe="stmt_query", fn_name="do_trace")if debug:print(u.get_text())print(bpf_text)# initialize BPFb = BPF(text=bpf_text, usdt_contexts=[u])# headerprint("%-18s %-16s %-6s %-6s %s" % ("TIME(s)", "COMM", "PID", "CPU", "QUERY"))# format outputwhile 1:try:(task, pid, cpu, flags, ts, msg) = b.trace_fields()except ValueError:print("value error")continueexcept KeyboardInterrupt:exit()printb(b"%-18.9f %-16s %-6d %-6d %s" % (ts, task, pid, cpu, msg))
bpf_text :该变量保存的是在内核空间执行的C代码,主要功能是捕获并打印query信息。 u.enable_probe(probe="stmt_query", fn_name="do_trace"):stmt_query是OceanBase中我们埋下的probe观察点。do_trace是观察点出发时要执行的跟踪函数。 上面代码的功能是,当OceanBase进程收到sql时触发观察点,并将获取的sql文本传递给观察者。
需要root权限执行,sudo。 参数是observer的进程id,pidof observer
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




