標籤:
http://www.actionsky.com/docs/archives/168#Systemtap
目錄
- 1 Systemtap
- 2 Systemtap 觀測點的支援程度
- 2.1 官方編譯的MySQL 5.7.11
- 2.2 編譯MySQL 5.7.11
- 3 Systemtap 使用舉例
- 4 雜項
Systemtap
MySQL 支援 Dtrace probe, 即提供了一些Dtrace用的有用的觀測點(probe). Systemtap同樣也可以利用這些觀測點, 可以作為一種低成本的觀測MySQL的手段.
常用的幾種觀測點:
1. function, 可以觀測函數的訪問/返回
2. statement, 可以直接觀測源碼中的某一行
3. marker, 由源碼提供的觀測點
日常常用的是function和marker. 尤其是marker, MySQL源碼提供的觀測點對於學習MySQL行為有所協助.
Systemtap 觀測點的支援程度官方編譯的MySQL 5.7.11
官方編譯的MySQL支援function觀測點
> stap -L ‘process("/opt/mysql-5.7.11-linux-glibc2.5-x86_64/bin/mysqld").function("dispatch_command")‘process("/opt/mysql-5.7.11-linux-glibc2.5-x86_64/bin/mysqld").function("[email protected]/export/home/pb2/build/sb_0-17781605-1454370718.35/mysql-5.7.11/sql/sql_parse.cc:1183") $thd:struct THD* $com_data:union COM_DATA const* $command:enum enum_server_command
官方編譯的MySQL不支援mark觀測點
> stap -v -L ‘process("/opt/mysql-5.7.11-linux-glibc2.5-x86_64/bin/mysqld").mark("*")‘Pass 1: parsed user script and 109 library script(s) using 96972virt/38616res/5780shr/32800data kb, in 150usr/10sys/164real ms.Pass 2: analyzed script: 0 probe(s), 0 function(s), 0 embed(s), 0 global(s) using 97764virt/40340res/6684shr/33592data kb, in 10usr/0sys/4real ms.Tip: /usr/share/doc/systemtap/README.Debian should help you get started
編譯MySQL 5.7.11
在MySQL源碼dtrace.cmake
中可以找到定義:
Check if OS supports DTraceMACRO(CHECK_DTRACE) FIND_PROGRAM(DTRACE dtrace) MARK_AS_ADVANCED(DTRACE) # On FreeBSD, dtrace does not handle userland tracing yet IF(DTRACE AND NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD") SET(ENABLE_DTRACE ON CACHE BOOL "Enable dtrace") ENDIF()
可知Linux環境下, 只要環境中存在dtrace
就會開啟ENABLE_DTRACE
. 於是裝好systemtap-sdt-dev
包, 再進行cmake就可以了. 不需要額外的配置選項, 也不需要開啟WITH_DEBUG
.
(說明: 按照手冊, systemtap-sdt-dev
中的dtrace
用於將file.d
檔案轉成標頭檔參與編譯, 並非真正的dtrace
.)
> apt-get install -sdt-dev> cmake -DBUILD_CONFIG=mysql_release -DDOWNLOAD_BOOST=1 -DDOWNLOAD_BOOST_TIMEOUT=3600 -DWITH_BOOST=/opt/boost -L .
檢查cmake
的輸出變數 (輸出經過截斷):
...ENABLE_DTRACE:BOOL=ON...WITH_DEBUG:BOOL=OFF...
ENABLE_DTRACE
編譯的MySQL支援mark觀測點 (輸出經過截斷)
> stap -L ‘process("/usr/local/mysql/bin/mysqld").mark("*")‘process("/usr/local/mysql/bin/mysqld").mark("command__done") $arg1:longprocess("/usr/local/mysql/bin/mysqld").mark("command__start") $arg1:long $arg2:long $arg3:long $arg4:longprocess("/usr/local/mysql/bin/mysqld").mark("connection__done") $arg1:long $arg2:long...process("/usr/local/mysql/bin/mysqld").mark("update__start") $arg1:long
Systemtap 使用舉例
舉例使用Systemtap的mark觀測點, 觀測SQL的解析.
Systemtap指令碼
global latencyprobe process("/usr/local/mysql/bin/mysqld").mark("query__parse__start") { printf ("parsing %s\n", user_string($arg1)) latency[tid()] = gettimeofday_ns()}probe process("/usr/local/mysql/bin/mysqld").mark("query__parse__done") { printf ("parse latency: %dns\n", gettimeofday_ns() - latency[tid()])}
運行
此例中, 在Docker 容器中進行systemtap的編譯, 再放到生產環境執行, 所以分成編譯和執行兩步. 也可以直接使用stap
執行.
> stap -v /opt/test_mysql_sql_parse.stp -m test_mysql_sql_parse.ko...$ sudo staprun -v test_mysql_sql_parse.kostaprun:insert_module:183 Module test_mysql_sql_parse inserted from file /opt/test_mysql_sql_parse.koparsing select @@version_comment limit 1parse latency: 54094nsparsing create database test.a(a int)parse latency: 48596ns
可以看到輸出中包含SQL解析的語句和解析時間.
雜項
- Systemtap的觀測成本低, 且成本變高時會自動斷開觀測, 而不影響被觀測程式運行, 因此可以考慮在生產環境作為必殺技使用.
- 在Docker容器中, 可以觀測到kernel probe, 但觀測不到同容器的userspace probe. 原因不詳.
- 如果MySQL的路徑上有軟串連, 則可能無法進行userspace probe, 原因不詳
用Systemtap探索MySQL