SlideShare ist ein Scribd-Unternehmen logo
1 von 31
Downloaden Sie, um offline zu lesen
SystemTap/DTrace with
                         MySQL & Drizzle


                                          Padraig O'Sullivan
                            Software Engineer, Akiban Tech.
                                    posullivan@akiban.com
                                 http://posulliv.github.com/




These slides released under the Creative Commons Attribution­Noncommercial­Share Alike 3.0 License
About Padraig

   Software Engineer at Akiban Technologies
    in Boston
   Drizzle contributor for over a year now
   Ported the DTrace probes from MySQL to
    Drizzle...hence this talk!
   Actually going to spend most of this talk
    discussing SystemTap since I'm assuming
    everyone is familiar with DTrace
What is DTrace?

   Observability technology that allows the
    behaviour of systems and applications to
    be investigated easily
   Developed at Sun and runs on Solaris and
    OSX
   Zero probe effect when not enabled and
    system acts as if DTrace not present at all
   Has a scripting language called “D”
   It doesn't work on Linux currently
What is SystemTap?

   Project under development since 2005 for
    dynamic instrumentation of Linux systems
    −   Contributions come from Red Hat, IBM, Oracle,
        etc.
   SystemTap can accomplish the same tasks
    as DTrace
   Static DTrace probes in an application can
    be used with SystemTap
    −   Latest version comes with python script named
        dtrace for this
   Has production support since RHEL 5.4
How SystemTap Works

   SystemTap has a command-line interface
    named stap
        −   Takes script in C-like language
   Basic steps Systemtap performs are:
    −       Translates the .stp script into C source code
    −       Compiles the C code into a kernel module (.ko
            file)
    −       Loads the module into the kernel
    −       Module runs
    −       Module is unloaded when CTRL-C is given or
            module decides it is done
How SystemTap Works
Probe script &
   Debug info


                       Translate
                   (Parse, elaborate
                     And translate)


Generated C file




                        Build



   Generated
 Kernel module


                         Plugin
                       Load and
                                       Probe output
                     Registration
                        execute




                        Unload
Probes

   Essential idea behind a SystemTap script is
    to name “events” and give them
    “handlers”
   When a specified event occurs, the kernel
    runs the handler and then resumes
    execution
   Combination of an event and a handler is
    referred to as a probe in SystemTap
Simple Example – syscall probing

# stap -e 'probe syscall.open
> {
>   log(execname() . “: “ . filename)
> }'




bash: /
bash: /tmp
cat: /etc/ld.so.cache
cat: /tmp/padraig
sendmail: /proc/loadavg
cat: <unknown>
...
iotop in SystemTap

global reads, writes, total_io

probe vfs.read
{
    reads[execname()] += $count
}

probe vfs.write
{
    writes[execname()] += $count
}

# print top 10 IO processes every 5 seconds
probe timer.s(5)
{
    foreach (name in writes)
        total_io[name] += writes[name]
    foreach (name in reads)
        total_io[name] += reads[name]
    printf ("%16st%10st%10sn", "Process", "KB Read", "KB Written")
    foreach (name in total_io- limit 10)
        printf("%16st%10dt%10dn", name,
               reads[name]/1024, writes[name]/1024)
    delete reads
    delete writes
    delete total_io
    print("n")
}
iotop in SystemTap

# stap iotop.sty

       Process KB Read KB Written
       firefox    3200          0
Gnome-terminal    3060          0
         mysql     528         22
        mysqld      23         63
hald-addon-inpu     14          0
gnome-power-man     12          0

#
Getting SystemTap

   Recommend going with Fedora 11/12 or
    RHEL if you want to use SystemTap easily.
    What's needed:
    −   systemtap
    −   systemtap-sdt-devel
    −   systemtap-runtime
    −   Kernel debuginfo
   Quite stable on these platforms and
    usually works just as advertised
SystemTap on Ubuntu/Debian

   This is not as easy! What's needed:
    −   systemtap
    −   systemtap-sdt-dev
    −   A kernel compiled with debug information
    −   A kernel that supports utrace if you want to
        perform user level probing
   In order to perform user-level probing, you
    will need to compile/install a custom kernel
    that supports utrace
Dtrace/SystemTap Comparison

   Obviously there is the licensing difference
    but we won't discuss that here
   Both tools are said to be safe to use in
    production
   DTrace comes by default in Solaris. Not so
    with SystemTap on Linux distributions
   From a user's perspective, SystemTap can
    be a pain to get working (particularly on
    Ubuntu/Debian)
   DTrace just works straight out of the box
MySQL & Drizzle with SystemTap

   Symbolic probing in which function names
    can be used for probes:
    −   Relies on knowledge of the source code of the
        application
   Instrument the application with marks
    −   Only requires us to know what the markers for
        the application are
   Luckily, MySQL and Drizzle have static
    Dtrace probes which correspond to the
    second method listed above
MySQL & Drizzle with SystemTap

   MySQL comes with static DTrace probes
    −       I ported these probes to drizzle
   SystemTap is compatible with static
    DTrace probes
        −    Any probe we define in our application for
             Dtrace can be used by SystemTap also
   In order to build MySQL and Drizzle with
    SystemTap support the systemtap-sdt-dev
    package needs to be installed
MySQL & Drizzle with SystemTap

    To build MySQL and Drizzle for use with
     SystemTap, it's pretty straightforward:



  Drizzle
$ ./config/autorun.sh
$ ./configure –with-debug –enable-dtrace
$ make




  MySQL
$ ./BUILD/autorun.sh
$ ./configure –with-debug –enable-dtrace
$ make
Static Probes in MySQL & Drizzle

    Once MySQL/Drizzle is configured and built
     and we start the server, we can list the
     markers that are present in the server:

# stap -l 'process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("*")'
process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("net__write__start")
process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("net__write__done")
process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("net__read__start")
process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("net__read__done")
process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("connection__done")
process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("connection__start")
process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("query__parse__start")
process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("query__parse__done")
process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("update__start")
process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("update__done")
process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("multi__update__start")
process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("multi__update__done")
process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("insert__start")
process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("insert__done")
process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("insert__select__start")
process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("insert__select__done")
process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("delete__start")
process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("delete__done")
...
MySQL & Drizzle Static Probes

   Approximately 60 probes, 200 locations in
    MySQL
   Query cache (not in drizzle)
   MyISAM key cache (not in drizzle)
   Network I/O
   Query execution
   Drizzle has started inserting probes to the
    optimizer
   Zero overhead when probes disabled
    −   Overhead can get high if lots of probes firing
Measuring Time in Storage Engine

global query_times
global engine_times
global queries

probe process(@1).mark("query__start")
{
  query_times[tid()] = gettimeofday_us()
  engine_times[tid()] = 0
  queries[tid()] = user_string($arg1)
}

probe process(@1).mark("*row__start")
{
  engine_times[tid()] = gettimeofday_us()
}

probe process(@1).mark("*row__done")
{
  engine_times[tid()] = gettimeofday_us() - engine_times[tid()]
}

probe process(@1).mark("query__done")
{
  query_times[tid()] = gettimeofday_us() - query_times[tid()]
  printf("%sn", queries[tid()])
  printf("Total: %dus Engine: %dusn",
         query_times[tid()],
         engine_times[tid()])
}
Measuring Time in Storage Engine

# stap se_time.sty /home/posulliv/repos/mysql/mysql-5.5.2-m2/5.5.2/libexec/mysqld
select @@version_comment limit 1
Total: 1395us Engine: 0us
select USER()
Total: 228us Engine: 0us
SELECT DATABASE()
Total: 586us Engine: 0us
show databases
Total: 753us Engine: 5us
show tables
Total: 893us Engine: 5us
show tables
Total: 3545us Engine: 18us
select * from tables
Total: 22756us Engine: 5us
^C
#
CPU Cycles in Storage Engine

global query_times
global engine_times
global queries

probe process(@1).mark("query__start")
{
  # get_cycles() returns the processor cycle counter value
  query_times[tid()] = get_cycles()
  engine_times[tid()] = 0
  queries[tid()] = user_string($arg1)
}

probe process(@1).mark("*row__start")
{
  engine_times[tid()] = get_cycles()
}

probe process(@1).mark("*row__done")
{
  engine_times[tid()] = get_cycles() - engine_times[tid()]
}

probe process(@1).mark("query__done")
{
  query_times[tid()] = get_cycles() - query_times[tid()]
  printf("%sn", queries[tid()])
  printf("Total: %d Engine: %dn",
         query_times[tid()],
         engine_times[tid()])
}
CPU Cycles in Storage Engine

# stap se_cycles.sty /home/posulliv/repos/mysql/mysql-5.5.2-m2/5.5.2/libexec/mysqld
select @@version_comment limit 1
Total: 370496 Engine: 0
select USER()
Total: 117047 Engine: 0
SELECT DATABASE()
Total: 659163 Engine: 0
show databases
Total: 1189115 Engine: 8348
show tables
Total: 353008 Engine: 8390
show tables
Total: 2659210 Engine: 31185
insert into t1 values (2, 'sarah')
Total: 8745185 Engine: 6257979
select * from t1
Total: 17086400 Engine: 9733
select b from t1 where a = 2
Total: 20495092 Engine: 61660
^C
#
Query Tracing – Lock & Filesort

global lock_times
global filesort_times

probe process(@1).mark(“*lock__start”)
{
  lock_times[tid()] = gettimeofday_us()
}

probe process(@1).mark("*lock__done")
{
  lock_times[tid()] = gettimeofday_us() - lock_times[tid()]
}

probe process(@1).mark("filesort__start")
{
  filesort_times[tid()] = gettimeofday_us()
}

probe process(@1).mark("filesort__done")
{
  filesort_times[tid()] = gettimeofday_us() - filesort_times[tid()]
}
Putting It All Together

# stap query_trace.sty /home/posulliv/repos/mysql/mysql-5.5.2-m2/5.5.2/libexec/mysqld
select @@version_comment limit 1
Total: 287us Locks: 0us Engine: 0us Network: 6us Filesort: 0us
select USER()
Total: 127us Locks: 0us Engine: 0us Network: 6us Filesort: 0us
SELECT DATABASE()
Total: 562us Locks: 0us Engine: 0us Network: 21us Filesort: 0us
show databases
Total: 642us Locks: 0us Engine: 5us Network: 6us Filesort: 0us
show tables
Total: 1148us Locks: 0us Engine: 6us Network: 6us Filesort: 0us
show tables
Total: 6201us Locks: 0us Engine: 19us Network: 23us Filesort: 0us
SELECT DATABASE()
Total: 564us Locks: 0us Engine: 0us Network: 21us Filesort: 0us
show databases
Total: 81us Locks: 0us Engine: 5us Network: 6us Filesort: 0us
show tables
Total: 293us Locks: 0us Engine: 5us Network: 6us Filesort: 0us
select * from t1
Total: 1202us Locks: 32us Engine: 20us Network: 23us Filesort: 0us
select * from t1 where a = 1
Total: 1134us Locks: 30us Engine: 56us Network: 21us Filesort: 0us
select * from t1 order by a desc
Total: 4727us Locks: 26us Engine: 20us Network: 22us Filesort: 3182us
insert into t1 values (3, 'tomas')
Total: 3406us Locks: 146us Engine: 858us Network: 30us Filesort: 0us
select * from t1 order by a desc
Total: 1340us Locks: 27us Engine: 20us Network: 21us Filesort: 228us
^C
#
Hot Tables - Reads

global tables

probe process(@1).mark("*read__row__start")
{
  tables[user_string($arg1), user_string($arg2)]++
}

probe end
{
  foreach ([schema, table] in tables)
  {
    printf("%s.%s %dn", schema, table, tables[schema, table])
  }
}



# stap hot_reads.sty /home/posulliv/repos/mysql/mysql-5.5.2-m2/5.5.2/libexec/mysqld
information_schema./opt/mysql_sandboxes/stap/tmp/#sql_1ecd_0 6
test.t1 8
^C
#
Hot Tables - Updates

global tables

probe
  process(@1).mark("update__row__start"),
  process(@1).mark("insert__row__start"),
  process(@1).mark("delete__row__start")
{
  tables[user_string($arg1), user_string($arg2)]++
}

probe end
{
  foreach ([schema, table] in tables)
  {
    printf("%s.%s %dn", schema, table, tables[schema, table])
  }
}



# stap hot_updates.sty /home/posulliv/repos/mysql/mysql-5.5.2-m2/5.5.2/libexec/mysqld
information_schema./opt/mysql_sandboxes/stap/tmp/#sql_901_0 4
test.t1 3
test.t2 100
^C
#
Queries Accessing Particular Table
global   schema_name
global   table_name
global   queries
global   used

probe begin
{
  schema_name = @1
  table_name = @2
}

probe process(@3).mark("query__exec__start")
{
  queries[tid()] = user_string($arg1)
  used[tid()] = 0
}

probe process(@3).mark("*lock__start")
{
  if (schema_name == user_string($arg1) &&
      table_name == user_string($arg2))
  {
    used[tid()] = 1
  }
}

probe process(@3).mark("query__exec__done")
{
  if (used[tid()])
  {
    printf("%s;n", queries[tid()])
  }
}
Queries Accessing Particular Table

# stap par_table.sty test   t1 /home/posulliv/repos/mysql/mysql-5.5.2-
m2/5.5.2/libexec/mysqld
select * from t1;
insert into t1 values (4,   'gearoid');
insert into t1 values (5,   'domhnall');
select * from t1 order by   a desc;
^C
#
Timing Locks

global rdlocks
global wrlocks

probe process(@1).mark("handler__rdlock__start")
{
  rdlocks[tid()] = get_cycles()
  printf("Start: Lock->Read %s.%sn",
         user_string($arg1), user_string($arg2))
}

probe process(@1).mark("handler__rdlock__done")
{
  printf("End: Lock->Read %d cyclesn",
         get_cycles() - rdlocks[tid()])
}

probe process(@1).mark("handler__wrlock__start")
{
  wrlocks[tid()] = get_cycles()
  printf("Start: Lock->Write %s.%sn",
         user_string($arg1), user_string($arg2))
}

probe process(@1).mark("handler__wrlock__done")
{
  printf("End: Lock->Write %d cyclesn",
         get_cycles() - wrlocks[tid()])
}
Timing Locks

# stap locktime.stp /home/posulliv/repos/mysql/mysql-5.5.2-m2/5.5.2/libexec/mysqld
Start: Lock->Read test.t1
End: Lock->Read 418788 cycles
Start: Lock->Read test.t1
End: Lock->Read 173971 cycles
Start: Lock->Write test.t1
End: Lock->Write 402910 cycles
Start: Lock->Write test.t1
End: Lock->Write 704391 cycles
Start: Lock->Read test.t1
End: Lock->Read 171652 cycles
Start: Lock->Read test.t1
End: Lock->Read 251286 cycles
^C
#
Resources and Thank You!

   SystemTap wiki
    −   Lots of documentation and tutorials on how to
        get started with stap
   SystemTap examples
    −   http://sourceware.org/systemtap/examples/
   My blog has some articles on how to get
    SystemTap up and running on Ubuntu and
    how to configure MySQL/Drizzle for
    SystemTap
   SystemTap script repository
    −   http://github.com/posulliv/stap

Weitere ähnliche Inhalte

Was ist angesagt?

Linux 4.x Tracing Tools: Using BPF Superpowers
Linux 4.x Tracing Tools: Using BPF SuperpowersLinux 4.x Tracing Tools: Using BPF Superpowers
Linux 4.x Tracing Tools: Using BPF Superpowers
Brendan Gregg
 

Was ist angesagt? (20)

MySQL 상태 메시지 분석 및 활용
MySQL 상태 메시지 분석 및 활용MySQL 상태 메시지 분석 및 활용
MySQL 상태 메시지 분석 및 활용
 
New Ways to Find Latency in Linux Using Tracing
New Ways to Find Latency in Linux Using TracingNew Ways to Find Latency in Linux Using Tracing
New Ways to Find Latency in Linux Using Tracing
 
Maria db 이중화구성_고민하기
Maria db 이중화구성_고민하기Maria db 이중화구성_고민하기
Maria db 이중화구성_고민하기
 
Linux 4.x Tracing Tools: Using BPF Superpowers
Linux 4.x Tracing Tools: Using BPF SuperpowersLinux 4.x Tracing Tools: Using BPF Superpowers
Linux 4.x Tracing Tools: Using BPF Superpowers
 
Linux Networking Explained
Linux Networking ExplainedLinux Networking Explained
Linux Networking Explained
 
Galera cluster for high availability
Galera cluster for high availability Galera cluster for high availability
Galera cluster for high availability
 
LinuxCon 2015 Linux Kernel Networking Walkthrough
LinuxCon 2015 Linux Kernel Networking WalkthroughLinuxCon 2015 Linux Kernel Networking Walkthrough
LinuxCon 2015 Linux Kernel Networking Walkthrough
 
Linux Profiling at Netflix
Linux Profiling at NetflixLinux Profiling at Netflix
Linux Profiling at Netflix
 
Linux Network Stack
Linux Network StackLinux Network Stack
Linux Network Stack
 
Reverse Mapping (rmap) in Linux Kernel
Reverse Mapping (rmap) in Linux KernelReverse Mapping (rmap) in Linux Kernel
Reverse Mapping (rmap) in Linux Kernel
 
MyRocks Deep Dive
MyRocks Deep DiveMyRocks Deep Dive
MyRocks Deep Dive
 
MySQL Database Architectures - MySQL InnoDB ClusterSet 2021-11
MySQL Database Architectures - MySQL InnoDB ClusterSet 2021-11MySQL Database Architectures - MySQL InnoDB ClusterSet 2021-11
MySQL Database Architectures - MySQL InnoDB ClusterSet 2021-11
 
Under the Hood of a Shard-per-Core Database Architecture
Under the Hood of a Shard-per-Core Database ArchitectureUnder the Hood of a Shard-per-Core Database Architecture
Under the Hood of a Shard-per-Core Database Architecture
 
Linux Kernel vs DPDK: HTTP Performance Showdown
Linux Kernel vs DPDK: HTTP Performance ShowdownLinux Kernel vs DPDK: HTTP Performance Showdown
Linux Kernel vs DPDK: HTTP Performance Showdown
 
Kernel Recipes 2017 - Understanding the Linux kernel via ftrace - Steven Rostedt
Kernel Recipes 2017 - Understanding the Linux kernel via ftrace - Steven RostedtKernel Recipes 2017 - Understanding the Linux kernel via ftrace - Steven Rostedt
Kernel Recipes 2017 - Understanding the Linux kernel via ftrace - Steven Rostedt
 
Introduction to Linux Kernel by Quontra Solutions
Introduction to Linux Kernel by Quontra SolutionsIntroduction to Linux Kernel by Quontra Solutions
Introduction to Linux Kernel by Quontra Solutions
 
PostgreSQL and RAM usage
PostgreSQL and RAM usagePostgreSQL and RAM usage
PostgreSQL and RAM usage
 
PostgreSQL Deep Internal
PostgreSQL Deep InternalPostgreSQL Deep Internal
PostgreSQL Deep Internal
 
Slab Allocator in Linux Kernel
Slab Allocator in Linux KernelSlab Allocator in Linux Kernel
Slab Allocator in Linux Kernel
 
semaphore & mutex.pdf
semaphore & mutex.pdfsemaphore & mutex.pdf
semaphore & mutex.pdf
 

Andere mochten auch

2011 06-12-lamp-mysql-顾春江
2011 06-12-lamp-mysql-顾春江2011 06-12-lamp-mysql-顾春江
2011 06-12-lamp-mysql-顾春江
thinkinlamp
 
InnoDB Transaction Lock and MVCC
InnoDB Transaction Lock and MVCCInnoDB Transaction Lock and MVCC
InnoDB Transaction Lock and MVCC
frogd
 
MySQL源码分析.01.代码结构与基本流程
MySQL源码分析.01.代码结构与基本流程MySQL源码分析.01.代码结构与基本流程
MySQL源码分析.01.代码结构与基本流程
Lixun Peng
 
The InnoDB Storage Engine for MySQL
The InnoDB Storage Engine for MySQLThe InnoDB Storage Engine for MySQL
The InnoDB Storage Engine for MySQL
Morgan Tocker
 
BPF: Tracing and more
BPF: Tracing and moreBPF: Tracing and more
BPF: Tracing and more
Brendan Gregg
 

Andere mochten auch (20)

2011 06-12-lamp-mysql-顾春江
2011 06-12-lamp-mysql-顾春江2011 06-12-lamp-mysql-顾春江
2011 06-12-lamp-mysql-顾春江
 
MySQL InnoDB 源码实现分析(一)
MySQL InnoDB 源码实现分析(一)MySQL InnoDB 源码实现分析(一)
MySQL InnoDB 源码实现分析(一)
 
InnoDB Transaction Lock and MVCC
InnoDB Transaction Lock and MVCCInnoDB Transaction Lock and MVCC
InnoDB Transaction Lock and MVCC
 
Buffer pool implementaion inno db vs oracle
Buffer pool implementaion inno db vs oracleBuffer pool implementaion inno db vs oracle
Buffer pool implementaion inno db vs oracle
 
My sql 5.6新特性深入剖析——innodb引擎
My sql 5.6新特性深入剖析——innodb引擎My sql 5.6新特性深入剖析——innodb引擎
My sql 5.6新特性深入剖析——innodb引擎
 
Mastering InnoDB Diagnostics
Mastering InnoDB DiagnosticsMastering InnoDB Diagnostics
Mastering InnoDB Diagnostics
 
数据库内核分享第二期(Inno db 日志 回滚段 & 崩溃恢复实现详解)
数据库内核分享第二期(Inno db 日志 回滚段 & 崩溃恢复实现详解)数据库内核分享第二期(Inno db 日志 回滚段 & 崩溃恢复实现详解)
数据库内核分享第二期(Inno db 日志 回滚段 & 崩溃恢复实现详解)
 
MySQL源码分析.01.代码结构与基本流程
MySQL源码分析.01.代码结构与基本流程MySQL源码分析.01.代码结构与基本流程
MySQL源码分析.01.代码结构与基本流程
 
数据库内核分享——第一期
数据库内核分享——第一期数据库内核分享——第一期
数据库内核分享——第一期
 
Mvcc (oracle, innodb, postgres)
Mvcc (oracle, innodb, postgres)Mvcc (oracle, innodb, postgres)
Mvcc (oracle, innodb, postgres)
 
排队论及其应用浅析
排队论及其应用浅析排队论及其应用浅析
排队论及其应用浅析
 
Oracle rac资源管理算法与cache fusion实现浅析
Oracle rac资源管理算法与cache fusion实现浅析Oracle rac资源管理算法与cache fusion实现浅析
Oracle rac资源管理算法与cache fusion实现浅析
 
硬件体系架构浅析
硬件体系架构浅析硬件体系架构浅析
硬件体系架构浅析
 
MySQL查询优化浅析
MySQL查询优化浅析MySQL查询优化浅析
MySQL查询优化浅析
 
Cpu Cache and Memory Ordering——并发程序设计入门
Cpu Cache and Memory Ordering——并发程序设计入门Cpu Cache and Memory Ordering——并发程序设计入门
Cpu Cache and Memory Ordering——并发程序设计入门
 
The InnoDB Storage Engine for MySQL
The InnoDB Storage Engine for MySQLThe InnoDB Storage Engine for MySQL
The InnoDB Storage Engine for MySQL
 
MySql slides (ppt)
MySql slides (ppt)MySql slides (ppt)
MySql slides (ppt)
 
Linux Performance Analysis: New Tools and Old Secrets
Linux Performance Analysis: New Tools and Old SecretsLinux Performance Analysis: New Tools and Old Secrets
Linux Performance Analysis: New Tools and Old Secrets
 
Broken Linux Performance Tools 2016
Broken Linux Performance Tools 2016Broken Linux Performance Tools 2016
Broken Linux Performance Tools 2016
 
BPF: Tracing and more
BPF: Tracing and moreBPF: Tracing and more
BPF: Tracing and more
 

Ähnlich wie Monitoring MySQL with DTrace/SystemTap

X64 Workshop Linux Information Gathering
X64 Workshop Linux Information GatheringX64 Workshop Linux Information Gathering
X64 Workshop Linux Information Gathering
Aero Plane
 
It802 bruning
It802 bruningIt802 bruning
It802 bruning
mrbruning
 

Ähnlich wie Monitoring MySQL with DTrace/SystemTap (20)

Spraykatz installation & basic usage
Spraykatz installation & basic usageSpraykatz installation & basic usage
Spraykatz installation & basic usage
 
Lessons Learned: Running InfluxDB Cloud and Other Cloud Services at Scale | T...
Lessons Learned: Running InfluxDB Cloud and Other Cloud Services at Scale | T...Lessons Learned: Running InfluxDB Cloud and Other Cloud Services at Scale | T...
Lessons Learned: Running InfluxDB Cloud and Other Cloud Services at Scale | T...
 
E bpf and dynamic tracing for mariadb db as (mariadb day during fosdem 2020)
E bpf and dynamic tracing for mariadb db as (mariadb day during fosdem 2020)E bpf and dynamic tracing for mariadb db as (mariadb day during fosdem 2020)
E bpf and dynamic tracing for mariadb db as (mariadb day during fosdem 2020)
 
Managing Large-scale Networks with Trigger
Managing Large-scale Networks with TriggerManaging Large-scale Networks with Trigger
Managing Large-scale Networks with Trigger
 
X64 Workshop Linux Information Gathering
X64 Workshop Linux Information GatheringX64 Workshop Linux Information Gathering
X64 Workshop Linux Information Gathering
 
linux installation.pdf
linux installation.pdflinux installation.pdf
linux installation.pdf
 
Tutorial to setup OpenStreetMap tileserver with customized boundaries of India
Tutorial to setup OpenStreetMap tileserver with customized boundaries of IndiaTutorial to setup OpenStreetMap tileserver with customized boundaries of India
Tutorial to setup OpenStreetMap tileserver with customized boundaries of India
 
Slackware Demystified [SELF 2011]
Slackware Demystified [SELF 2011]Slackware Demystified [SELF 2011]
Slackware Demystified [SELF 2011]
 
It802 bruning
It802 bruningIt802 bruning
It802 bruning
 
A Fabric/Puppet Build/Deploy System
A Fabric/Puppet Build/Deploy SystemA Fabric/Puppet Build/Deploy System
A Fabric/Puppet Build/Deploy System
 
Debug generic process
Debug generic processDebug generic process
Debug generic process
 
How to lock a Python in a cage? Managing Python environment inside an R project
How to lock a Python in a cage?  Managing Python environment inside an R projectHow to lock a Python in a cage?  Managing Python environment inside an R project
How to lock a Python in a cage? Managing Python environment inside an R project
 
Dynamic Hadoop Clusters
Dynamic Hadoop ClustersDynamic Hadoop Clusters
Dynamic Hadoop Clusters
 
MINCS - containers in the shell script (Eng. ver.)
MINCS - containers in the shell script (Eng. ver.)MINCS - containers in the shell script (Eng. ver.)
MINCS - containers in the shell script (Eng. ver.)
 
Containers with systemd-nspawn
Containers with systemd-nspawnContainers with systemd-nspawn
Containers with systemd-nspawn
 
Introduction to JumpStart
Introduction to JumpStartIntroduction to JumpStart
Introduction to JumpStart
 
Lessons Learned Running InfluxDB Cloud and Other Cloud Services at Scale by T...
Lessons Learned Running InfluxDB Cloud and Other Cloud Services at Scale by T...Lessons Learned Running InfluxDB Cloud and Other Cloud Services at Scale by T...
Lessons Learned Running InfluxDB Cloud and Other Cloud Services at Scale by T...
 
Linux
LinuxLinux
Linux
 
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak   CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
 
Dynamic Tracing of your AMP web site
Dynamic Tracing of your AMP web siteDynamic Tracing of your AMP web site
Dynamic Tracing of your AMP web site
 

Kürzlich hochgeladen

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Kürzlich hochgeladen (20)

AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 

Monitoring MySQL with DTrace/SystemTap

  • 1. SystemTap/DTrace with MySQL & Drizzle Padraig O'Sullivan Software Engineer, Akiban Tech. posullivan@akiban.com http://posulliv.github.com/ These slides released under the Creative Commons Attribution­Noncommercial­Share Alike 3.0 License
  • 2. About Padraig  Software Engineer at Akiban Technologies in Boston  Drizzle contributor for over a year now  Ported the DTrace probes from MySQL to Drizzle...hence this talk!  Actually going to spend most of this talk discussing SystemTap since I'm assuming everyone is familiar with DTrace
  • 3. What is DTrace?  Observability technology that allows the behaviour of systems and applications to be investigated easily  Developed at Sun and runs on Solaris and OSX  Zero probe effect when not enabled and system acts as if DTrace not present at all  Has a scripting language called “D”  It doesn't work on Linux currently
  • 4. What is SystemTap?  Project under development since 2005 for dynamic instrumentation of Linux systems − Contributions come from Red Hat, IBM, Oracle, etc.  SystemTap can accomplish the same tasks as DTrace  Static DTrace probes in an application can be used with SystemTap − Latest version comes with python script named dtrace for this  Has production support since RHEL 5.4
  • 5. How SystemTap Works  SystemTap has a command-line interface named stap − Takes script in C-like language  Basic steps Systemtap performs are: − Translates the .stp script into C source code − Compiles the C code into a kernel module (.ko file) − Loads the module into the kernel − Module runs − Module is unloaded when CTRL-C is given or module decides it is done
  • 6. How SystemTap Works Probe script & Debug info Translate (Parse, elaborate And translate) Generated C file Build Generated Kernel module Plugin Load and Probe output Registration execute Unload
  • 7. Probes  Essential idea behind a SystemTap script is to name “events” and give them “handlers”  When a specified event occurs, the kernel runs the handler and then resumes execution  Combination of an event and a handler is referred to as a probe in SystemTap
  • 8. Simple Example – syscall probing # stap -e 'probe syscall.open > { > log(execname() . “: “ . filename) > }' bash: / bash: /tmp cat: /etc/ld.so.cache cat: /tmp/padraig sendmail: /proc/loadavg cat: <unknown> ...
  • 9. iotop in SystemTap global reads, writes, total_io probe vfs.read { reads[execname()] += $count } probe vfs.write { writes[execname()] += $count } # print top 10 IO processes every 5 seconds probe timer.s(5) { foreach (name in writes) total_io[name] += writes[name] foreach (name in reads) total_io[name] += reads[name] printf ("%16st%10st%10sn", "Process", "KB Read", "KB Written") foreach (name in total_io- limit 10) printf("%16st%10dt%10dn", name, reads[name]/1024, writes[name]/1024) delete reads delete writes delete total_io print("n") }
  • 10. iotop in SystemTap # stap iotop.sty Process KB Read KB Written firefox 3200 0 Gnome-terminal 3060 0 mysql 528 22 mysqld 23 63 hald-addon-inpu 14 0 gnome-power-man 12 0 #
  • 11. Getting SystemTap  Recommend going with Fedora 11/12 or RHEL if you want to use SystemTap easily. What's needed: − systemtap − systemtap-sdt-devel − systemtap-runtime − Kernel debuginfo  Quite stable on these platforms and usually works just as advertised
  • 12. SystemTap on Ubuntu/Debian  This is not as easy! What's needed: − systemtap − systemtap-sdt-dev − A kernel compiled with debug information − A kernel that supports utrace if you want to perform user level probing  In order to perform user-level probing, you will need to compile/install a custom kernel that supports utrace
  • 13. Dtrace/SystemTap Comparison  Obviously there is the licensing difference but we won't discuss that here  Both tools are said to be safe to use in production  DTrace comes by default in Solaris. Not so with SystemTap on Linux distributions  From a user's perspective, SystemTap can be a pain to get working (particularly on Ubuntu/Debian)  DTrace just works straight out of the box
  • 14. MySQL & Drizzle with SystemTap  Symbolic probing in which function names can be used for probes: − Relies on knowledge of the source code of the application  Instrument the application with marks − Only requires us to know what the markers for the application are  Luckily, MySQL and Drizzle have static Dtrace probes which correspond to the second method listed above
  • 15. MySQL & Drizzle with SystemTap  MySQL comes with static DTrace probes − I ported these probes to drizzle  SystemTap is compatible with static DTrace probes − Any probe we define in our application for Dtrace can be used by SystemTap also  In order to build MySQL and Drizzle with SystemTap support the systemtap-sdt-dev package needs to be installed
  • 16. MySQL & Drizzle with SystemTap  To build MySQL and Drizzle for use with SystemTap, it's pretty straightforward: Drizzle $ ./config/autorun.sh $ ./configure –with-debug –enable-dtrace $ make MySQL $ ./BUILD/autorun.sh $ ./configure –with-debug –enable-dtrace $ make
  • 17. Static Probes in MySQL & Drizzle  Once MySQL/Drizzle is configured and built and we start the server, we can list the markers that are present in the server: # stap -l 'process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("*")' process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("net__write__start") process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("net__write__done") process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("net__read__start") process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("net__read__done") process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("connection__done") process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("connection__start") process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("query__parse__start") process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("query__parse__done") process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("update__start") process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("update__done") process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("multi__update__start") process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("multi__update__done") process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("insert__start") process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("insert__done") process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("insert__select__start") process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("insert__select__done") process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("delete__start") process("/home/posulliv/repos/mysql/uc/sql/mysqld").mark("delete__done") ...
  • 18. MySQL & Drizzle Static Probes  Approximately 60 probes, 200 locations in MySQL  Query cache (not in drizzle)  MyISAM key cache (not in drizzle)  Network I/O  Query execution  Drizzle has started inserting probes to the optimizer  Zero overhead when probes disabled − Overhead can get high if lots of probes firing
  • 19. Measuring Time in Storage Engine global query_times global engine_times global queries probe process(@1).mark("query__start") { query_times[tid()] = gettimeofday_us() engine_times[tid()] = 0 queries[tid()] = user_string($arg1) } probe process(@1).mark("*row__start") { engine_times[tid()] = gettimeofday_us() } probe process(@1).mark("*row__done") { engine_times[tid()] = gettimeofday_us() - engine_times[tid()] } probe process(@1).mark("query__done") { query_times[tid()] = gettimeofday_us() - query_times[tid()] printf("%sn", queries[tid()]) printf("Total: %dus Engine: %dusn", query_times[tid()], engine_times[tid()]) }
  • 20. Measuring Time in Storage Engine # stap se_time.sty /home/posulliv/repos/mysql/mysql-5.5.2-m2/5.5.2/libexec/mysqld select @@version_comment limit 1 Total: 1395us Engine: 0us select USER() Total: 228us Engine: 0us SELECT DATABASE() Total: 586us Engine: 0us show databases Total: 753us Engine: 5us show tables Total: 893us Engine: 5us show tables Total: 3545us Engine: 18us select * from tables Total: 22756us Engine: 5us ^C #
  • 21. CPU Cycles in Storage Engine global query_times global engine_times global queries probe process(@1).mark("query__start") { # get_cycles() returns the processor cycle counter value query_times[tid()] = get_cycles() engine_times[tid()] = 0 queries[tid()] = user_string($arg1) } probe process(@1).mark("*row__start") { engine_times[tid()] = get_cycles() } probe process(@1).mark("*row__done") { engine_times[tid()] = get_cycles() - engine_times[tid()] } probe process(@1).mark("query__done") { query_times[tid()] = get_cycles() - query_times[tid()] printf("%sn", queries[tid()]) printf("Total: %d Engine: %dn", query_times[tid()], engine_times[tid()]) }
  • 22. CPU Cycles in Storage Engine # stap se_cycles.sty /home/posulliv/repos/mysql/mysql-5.5.2-m2/5.5.2/libexec/mysqld select @@version_comment limit 1 Total: 370496 Engine: 0 select USER() Total: 117047 Engine: 0 SELECT DATABASE() Total: 659163 Engine: 0 show databases Total: 1189115 Engine: 8348 show tables Total: 353008 Engine: 8390 show tables Total: 2659210 Engine: 31185 insert into t1 values (2, 'sarah') Total: 8745185 Engine: 6257979 select * from t1 Total: 17086400 Engine: 9733 select b from t1 where a = 2 Total: 20495092 Engine: 61660 ^C #
  • 23. Query Tracing – Lock & Filesort global lock_times global filesort_times probe process(@1).mark(“*lock__start”) { lock_times[tid()] = gettimeofday_us() } probe process(@1).mark("*lock__done") { lock_times[tid()] = gettimeofday_us() - lock_times[tid()] } probe process(@1).mark("filesort__start") { filesort_times[tid()] = gettimeofday_us() } probe process(@1).mark("filesort__done") { filesort_times[tid()] = gettimeofday_us() - filesort_times[tid()] }
  • 24. Putting It All Together # stap query_trace.sty /home/posulliv/repos/mysql/mysql-5.5.2-m2/5.5.2/libexec/mysqld select @@version_comment limit 1 Total: 287us Locks: 0us Engine: 0us Network: 6us Filesort: 0us select USER() Total: 127us Locks: 0us Engine: 0us Network: 6us Filesort: 0us SELECT DATABASE() Total: 562us Locks: 0us Engine: 0us Network: 21us Filesort: 0us show databases Total: 642us Locks: 0us Engine: 5us Network: 6us Filesort: 0us show tables Total: 1148us Locks: 0us Engine: 6us Network: 6us Filesort: 0us show tables Total: 6201us Locks: 0us Engine: 19us Network: 23us Filesort: 0us SELECT DATABASE() Total: 564us Locks: 0us Engine: 0us Network: 21us Filesort: 0us show databases Total: 81us Locks: 0us Engine: 5us Network: 6us Filesort: 0us show tables Total: 293us Locks: 0us Engine: 5us Network: 6us Filesort: 0us select * from t1 Total: 1202us Locks: 32us Engine: 20us Network: 23us Filesort: 0us select * from t1 where a = 1 Total: 1134us Locks: 30us Engine: 56us Network: 21us Filesort: 0us select * from t1 order by a desc Total: 4727us Locks: 26us Engine: 20us Network: 22us Filesort: 3182us insert into t1 values (3, 'tomas') Total: 3406us Locks: 146us Engine: 858us Network: 30us Filesort: 0us select * from t1 order by a desc Total: 1340us Locks: 27us Engine: 20us Network: 21us Filesort: 228us ^C #
  • 25. Hot Tables - Reads global tables probe process(@1).mark("*read__row__start") { tables[user_string($arg1), user_string($arg2)]++ } probe end { foreach ([schema, table] in tables) { printf("%s.%s %dn", schema, table, tables[schema, table]) } } # stap hot_reads.sty /home/posulliv/repos/mysql/mysql-5.5.2-m2/5.5.2/libexec/mysqld information_schema./opt/mysql_sandboxes/stap/tmp/#sql_1ecd_0 6 test.t1 8 ^C #
  • 26. Hot Tables - Updates global tables probe process(@1).mark("update__row__start"), process(@1).mark("insert__row__start"), process(@1).mark("delete__row__start") { tables[user_string($arg1), user_string($arg2)]++ } probe end { foreach ([schema, table] in tables) { printf("%s.%s %dn", schema, table, tables[schema, table]) } } # stap hot_updates.sty /home/posulliv/repos/mysql/mysql-5.5.2-m2/5.5.2/libexec/mysqld information_schema./opt/mysql_sandboxes/stap/tmp/#sql_901_0 4 test.t1 3 test.t2 100 ^C #
  • 27. Queries Accessing Particular Table global schema_name global table_name global queries global used probe begin { schema_name = @1 table_name = @2 } probe process(@3).mark("query__exec__start") { queries[tid()] = user_string($arg1) used[tid()] = 0 } probe process(@3).mark("*lock__start") { if (schema_name == user_string($arg1) && table_name == user_string($arg2)) { used[tid()] = 1 } } probe process(@3).mark("query__exec__done") { if (used[tid()]) { printf("%s;n", queries[tid()]) } }
  • 28. Queries Accessing Particular Table # stap par_table.sty test t1 /home/posulliv/repos/mysql/mysql-5.5.2- m2/5.5.2/libexec/mysqld select * from t1; insert into t1 values (4, 'gearoid'); insert into t1 values (5, 'domhnall'); select * from t1 order by a desc; ^C #
  • 29. Timing Locks global rdlocks global wrlocks probe process(@1).mark("handler__rdlock__start") { rdlocks[tid()] = get_cycles() printf("Start: Lock->Read %s.%sn", user_string($arg1), user_string($arg2)) } probe process(@1).mark("handler__rdlock__done") { printf("End: Lock->Read %d cyclesn", get_cycles() - rdlocks[tid()]) } probe process(@1).mark("handler__wrlock__start") { wrlocks[tid()] = get_cycles() printf("Start: Lock->Write %s.%sn", user_string($arg1), user_string($arg2)) } probe process(@1).mark("handler__wrlock__done") { printf("End: Lock->Write %d cyclesn", get_cycles() - wrlocks[tid()]) }
  • 30. Timing Locks # stap locktime.stp /home/posulliv/repos/mysql/mysql-5.5.2-m2/5.5.2/libexec/mysqld Start: Lock->Read test.t1 End: Lock->Read 418788 cycles Start: Lock->Read test.t1 End: Lock->Read 173971 cycles Start: Lock->Write test.t1 End: Lock->Write 402910 cycles Start: Lock->Write test.t1 End: Lock->Write 704391 cycles Start: Lock->Read test.t1 End: Lock->Read 171652 cycles Start: Lock->Read test.t1 End: Lock->Read 251286 cycles ^C #
  • 31. Resources and Thank You!  SystemTap wiki − Lots of documentation and tutorials on how to get started with stap  SystemTap examples − http://sourceware.org/systemtap/examples/  My blog has some articles on how to get SystemTap up and running on Ubuntu and how to configure MySQL/Drizzle for SystemTap  SystemTap script repository − http://github.com/posulliv/stap