For those in between, like me with this Ubuntu 16.04:
openxs@ao756:~/git/bcc/build$ cat /etc/lsb-releasethe fancy world of eBPF and more efficient dynamic tracing is still mostly open, as we can try to use BCC tools. BCC is a toolkit for creating efficient kernel tracing and manipulation programs that includes several potentially useful tools and examples for MySQL DBAs. It makes use of extended BPF (Berkeley Packet Filters), formally known as eBPF.
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.6 LTS"
openxs@ao756:~/git/bcc/build$ uname -a
Linux ao756 4.4.0-171-generic #200-Ubuntu SMP Tue Dec 3 11:04:55 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
I have a draft of this blog post hanging around since October 2019, but every time I tried to complete it I was not happy with the content. I wanted to get back, test more, try to present more tools, find out how to be able to access structure members in probes as easy as I can do it with gdb or perf, but then I hit some problem and put the draft aside...
When I started again some time later I often hit some new problem, so today I just decided to finally write down what I already know for sure, and provide at least a very basic example of dynamic tracing along the lines of those used in earlier posts (capturing queries executed by different threads using dynamic probes).
The first problem in case of Ubuntu 16.04 is to get the binaries of BCC tools. One of the ways is to build from GitHub source. The INSTALL.md document is clear enough when describing build dependencies and steps:
but still there is something to note. In recent versions you surely have to update the libbpf submodule, or you'll end up with compilation errors at early stage. My steps today were the following:git clone https://github.com/iovisor/bcc.git mkdir bcc/build; cd bcc/build cmake .. -DCMAKE_INSTALL_PREFIX=/usr make sudo make install
openxs@ao756:~/dbs/maria10.3$ cd ~/git/bcc/Now I can proceed to build subdirectory and complete the build:
openxs@ao756:~/git/bcc$ git pull
Already up-to-date.
openxs@ao756:~/git/bcc$ git log -1
commit dce8e9daf59f44dec4e3500d39a82a8ce59e43ba
Author: Yonghong Song <yhs@fb.com>
Date: Fri Jan 17 22:06:52 2020 -0800
sync with latest libbpf repo
sync libbpf submodule upto the following commit:
commit 033ad7ee78e8f266fdd27ee2675090ccf4402f3f
Author: Andrii Nakryiko <andriin@fb.com>
Date: Fri Jan 17 16:22:23 2020 -0800
sync: latest libbpf changes from kernel
Signed-off-by: Yonghong Song <yhs@fb.com>
openxs@ao756:~/git/bcc$ git submodule init
openxs@ao756:~/git/bcc$ git submodule update
Submodule path 'src/cc/libbpf': checked out '033ad7ee78e8f266fdd27ee2675090ccf4402f3f'
openxs@ao756:~/git/bcc/build$ cmake .. -DCMAKE_INSTALL_PREFIX=/usr...It's always interesting to check if tests pass:
openxs@ao756:~/git/bcc/build$ make
...
[ 99%] Building CXX object tests/cc/CMakeFiles/test_libbcc.dir/test_usdt_probes.cc.o
[100%] Building CXX object tests/cc/CMakeFiles/test_libbcc.dir/utils.cc.o
[100%] Linking CXX executable test_libbcc
[100%] Built target test_libbcc
openxs@ao756:~/git/bcc/build$ make testI've always had some tests failed, and one day I probably have to report the issue for the project, but for the purpose of this post (based on previous experience with older code) I'll get at least trace tool working as expected. So, I decided to process with installation:
Running tests...
Test project /home/openxs/git/bcc/build
Start 1: style-check
1/40 Test #1: style-check ...................... Passed 0.01 sec
Start 2: c_test_static
2/40 Test #2: c_test_static .................... Passed 0.30 sec
...
40/40 Test #40: lua_test_standalone ..............***Failed 0.06 sec
75% tests passed, 10 tests failed out of 40
Total Test time (real) = 450.78 sec
The following tests FAILED:
3 - test_libbcc (Failed)
4 - py_test_stat1_b (Failed)
5 - py_test_bpf_log (Failed)
6 - py_test_stat1_c (Failed)
7 - py_test_xlate1_c (Failed)
8 - py_test_call1 (Failed)
16 - py_test_brb (Failed)
17 - py_test_brb2 (Failed)
18 - py_test_clang (Failed)
40 - lua_test_standalone (Failed)
Errors while running CTest
Makefile:105: recipe for target 'test' failed
make: *** [test] Error 8
openxs@ao756:~/git/bcc/build$ sudo make installThe tools are installed by default to /usr/share/bcc/tools.
...
-- Up-to-date: /usr/share/bcc/tools/old/stackcount
-- Up-to-date: /usr/share/bcc/tools/old/oomkill
For adding dynamic probes I'll use trace tool that probes functions you specify and displays trace messages if a particular condition is met. You can control the message format to display function
arguments and return values.
Brendan Gregg explains the usage of this and other tools here with a lot of details. I'll just add a nice chart from that page here:
There is a separate tutorial with examples. You may want to check section for trace tool there.
For the purpose of this blog post I think it's enough to quickly check help output:
openxs@ao756:~/git/bcc/build$ sudo /usr/share/bcc/tools/traceand note the following basic syntax is used to define probes (see man /usr/share/bcc/man/man8/trace.8.gz after buuilding the tools from source as described above):
usage: trace [-h] [-b BUFFER_PAGES] [-p PID] [-L TID] [-v] [-Z STRING_SIZE]
[-S] [-M MAX_EVENTS] [-t] [-u] [-T] [-C] [-c CGROUP_PATH]
[-n NAME] [-f MSG_FILTER] [-B] [-s SYM_FILE_LIST] [-K] [-U] [-a]
[-I header]
probe [probe ...]
trace: error: too few arguments
PROBE SYNTAXFir simplicity here we do not consider conditional probes, so predicate is skipped. At the moment we are not interested in kernel or or user defined static tracepoints (the are not defined in default recent builds of MySQL or MariaDB server anway and require -DENABLE_DTRACE=ON to be explictly added to cmake command line used). For user defined dynamic probes in the mysqld process we need p (for probe at function entry) and maybe r (for function return).
The general probe syntax is as follows:
[{p,r}]:[library]:function[(signature)] [(predicate)] ["format
string"[, arguments]]
{t:category:event,u:library:probe} [(predicate)] ["format string"[,
arguments]]
{[{p,r}],t,u}
Probe type - "p" for function entry, "r" for function return,
"t" for kernel tracepoint, "u" for USDT probe. The default probe
type is "p".
...
We need to refer to library, and in our case this is a full path name to the mysqld binary (or just mysqld if it's in PATH). We also need to refer to some function by names. Quick test will show you that by default trace does NOT accept plain function names in MySQL or MariaDB code (as perf does), and require mangled ones to be used (same as bpftrace). We can find the names with nm command:
openxs@ao756:~/git/bcc/build$ nm -na /home/openxs/dbs/maria10.3/bin/mysqld | grep dispatch_commandIn the example above I was specifically looking for dispatch_command() function of MariaDB server version 10.3.x that I assume (see previous post) has a string with SQL statement as the third argument, packet. So, I can refer to this function in probe as "_Z16dispatch_command19enum_server_commandP3THDPcjbb".
00000000004a1eef t _Z16dispatch_command19enum_server_commandP3THDPcjbb.cold.344
00000000005c5180 T _Z16dispatch_command19enum_server_commandP3THDPcjbb
00000000005c5180 t _Z16dispatch_command19enum_server_commandP3THDPcjbb.localalias.256
The "format string" that define how to output arguments of probe is a printf-style format string. You can use the following format specifiers: %s, %d, %u, ... with the same semantics as printf's. In our case for zero-terminating string we'll use "%s".
Arguments of the function traced are named arg1, arg2, ... argN (unless we provide a signature for function), and are numbered starting from 1. So, in out case we can add a probe to print third argument of the dispatch_command() function upon entry as follows:
openxs@ao756:~/dbs/maria10.3$ sudo /usr/share/bcc/tools/trace -T 'p:/home/openxs/dbs/maria10.3/bin/mysqld:_Z16dispatch_command19enum_server_commandP3THDPcjbb "%s" arg3'I've got the output above for this sample session:
[sudo] password for openxs:
TIME PID TID COMM FUNC -
16:16:53 26585 29133 mysqld _Z16dispatch_command19enum_server_commandP3THDPcjbb select @@version_comment limit 1
16:17:02 26585 29133 mysqld _Z16dispatch_command19enum_server_commandP3THDPcjbb select 1
16:17:05 26585 29133 mysqld _Z16dispatch_command19enum_server_commandP3THDPcjbb select 2
16:17:07 26585 29133 mysqld _Z16dispatch_command19enum_server_commandP3THDPcjbb
^C
openxs@ao756:~/dbs/maria10.3$ bin/mysql -uroot --socket=/tmp/mariadb.sockNote that I've added -T option to the command line to output timestamp.
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 16
Server version: 10.3.22-MariaDB Source distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> select 1;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0,000 sec)
MariaDB [(none)]> select 2;
+---+
| 2 |
+---+
| 2 |
+---+
1 row in set (0,001 sec)
MariaDB [(none)]> exit
Bye
It's a bit more complex with recent versions of Percona Server or MySQL (or any function parameters that are complex structures). It's also more complex if we want to process prepared statements and process packet content depending on the first argument (the above is correct only for COM_QUERY) and so on. But these are basic steps to get a log of SQL queries with timestamps by adding a dynamic probe with BCC trace tool. Enjoy!
No comments:
Post a Comment