Skip to content

Instantly share code, notes, and snippets.

@dholroyd
Last active November 28, 2018 00:29
Show Gist options
  • Select an option

  • Save dholroyd/93e92bf861e244001bc9a30803a628f1 to your computer and use it in GitHub Desktop.

Select an option

Save dholroyd/93e92bf861e244001bc9a30803a628f1 to your computer and use it in GitHub Desktop.
systemtap script to dump sqlite statements as they are executed
/*
* Dump sqlite statements as they are executed. Tested with sqlite 3.6.20
*
* Prereqs:
* sudo yum install systemtap-client systemtap-devel kernel-devel gcc yum-utils
* sudo debuginfo-install sqlite
*
* Running:
* sudo stap -DMAXUPROBES=800 sqlite-dump.stp
*
* Inspired by:
* https://github.com/asutherland/tb-test-help/blob/master/systemtap/sqlite-perf.stp
*/
// maps thread id to current sqlite3_step depth, to avoid recursive calls
global thread_sqlite3_step_depth;
global thread_current_query_start;
probe process("/usr/lib64/libsqlite3.so.0").function("sqlite3_step") {
ctx = tid();
depth = thread_sqlite3_step_depth[ctx]++;
// don't do anything more if we are nested
if (depth)
next;
sql = @cast($pStmt, "struct Vdbe")->zSql;
if (sql) {
time_start = gettimeofday_us();
printf("%5d > %d : %s\n", ctx, time_start, user_string(sql));
thread_current_query_start[ctx] = time_start;
} else {
thread_current_query_start[ctx] = 0;
}
}
probe process("/usr/lib64/libsqlite3.so.0").function("sqlite3_step").return {
ctx = tid();
depth = --thread_sqlite3_step_depth[ctx];
if (depth == 0) {
time_start = thread_current_query_start[ctx];
if (time_start) {
time_end = gettimeofday_us();
duration = time_end - time_start;
printf("%5d < %d \n", ctx, duration);
}
}
}
#!/bin/env ruby -w
class Stat
def initialize
@count = @time = 0
end
attr_accessor :time, :count
end
statements_by_thread = Hash.new
stats_by_statement = Hash.new
File.open("sqlite.log").each_line do |line|
case line
when /^\s*(\d+) > (\d+) : (.*)/
statements_by_thread[$1] = $3
when /^\s*(\d+) < (\d+)/
statement = statements_by_thread[$1]
stats = stats_by_statement[statement]
if !stats
stats = Stat.new
stats_by_statement[statement] = stats
end
stats.count += 1
stats.time += $2.to_i
else
$stderr.puts "failed to parse line #{line.inspect}"
end
end
stats_by_statement.each do |k,v|
puts "#{v.count}\t#{v.time}\t#{k}"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment