xref: /aosp_15_r20/external/bcc/tools/mysqld_qslower.py (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/env python
2*387f9dfdSAndroid Build Coastguard Worker#
3*387f9dfdSAndroid Build Coastguard Worker# mysqld_qslower    MySQL server queries slower than a threshold.
4*387f9dfdSAndroid Build Coastguard Worker#                   For Linux, uses BCC, BPF. Embedded C.
5*387f9dfdSAndroid Build Coastguard Worker#
6*387f9dfdSAndroid Build Coastguard Worker# USAGE: mysqld_qslower PID [min_ms]
7*387f9dfdSAndroid Build Coastguard Worker#
8*387f9dfdSAndroid Build Coastguard Worker# By default, a threshold of 1.0 ms is used. Set this to 0 ms to trace all
9*387f9dfdSAndroid Build Coastguard Worker# queries (verbose).
10*387f9dfdSAndroid Build Coastguard Worker#
11*387f9dfdSAndroid Build Coastguard Worker# This uses USDT probes, and needs a MySQL server with -DENABLE_DTRACE=1.
12*387f9dfdSAndroid Build Coastguard Worker#
13*387f9dfdSAndroid Build Coastguard Worker# Copyright 2016 Netflix, Inc.
14*387f9dfdSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License")
15*387f9dfdSAndroid Build Coastguard Worker#
16*387f9dfdSAndroid Build Coastguard Worker# 30-Jul-2016   Brendan Gregg   Created this.
17*387f9dfdSAndroid Build Coastguard Worker
18*387f9dfdSAndroid Build Coastguard Workerfrom __future__ import print_function
19*387f9dfdSAndroid Build Coastguard Workerfrom bcc import BPF, USDT
20*387f9dfdSAndroid Build Coastguard Workerimport sys
21*387f9dfdSAndroid Build Coastguard Worker
22*387f9dfdSAndroid Build Coastguard Worker# arguments
23*387f9dfdSAndroid Build Coastguard Workerdef usage():
24*387f9dfdSAndroid Build Coastguard Worker    print("USAGE: mysqld_qslower PID [min_ms]")
25*387f9dfdSAndroid Build Coastguard Worker    exit()
26*387f9dfdSAndroid Build Coastguard Workerif len(sys.argv) < 2:
27*387f9dfdSAndroid Build Coastguard Worker    usage()
28*387f9dfdSAndroid Build Coastguard Workerif sys.argv[1][0:1] == "-":
29*387f9dfdSAndroid Build Coastguard Worker    usage()
30*387f9dfdSAndroid Build Coastguard Workerpid = int(sys.argv[1])
31*387f9dfdSAndroid Build Coastguard Workermin_ns = 1 * 1000000
32*387f9dfdSAndroid Build Coastguard Workermin_ms_text = 1
33*387f9dfdSAndroid Build Coastguard Workerif len(sys.argv) == 3:
34*387f9dfdSAndroid Build Coastguard Worker    min_ns = float(sys.argv[2]) * 1000000
35*387f9dfdSAndroid Build Coastguard Worker    min_ms_text = sys.argv[2]
36*387f9dfdSAndroid Build Coastguard Workerdebug = 0
37*387f9dfdSAndroid Build Coastguard WorkerQUERY_MAX = 128
38*387f9dfdSAndroid Build Coastguard Worker
39*387f9dfdSAndroid Build Coastguard Worker# load BPF program
40*387f9dfdSAndroid Build Coastguard Workerbpf_text = """
41*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/ptrace.h>
42*387f9dfdSAndroid Build Coastguard Worker
43*387f9dfdSAndroid Build Coastguard Worker#define QUERY_MAX	""" + str(QUERY_MAX) + """
44*387f9dfdSAndroid Build Coastguard Worker
45*387f9dfdSAndroid Build Coastguard Workerstruct start_t {
46*387f9dfdSAndroid Build Coastguard Worker    u64 ts;
47*387f9dfdSAndroid Build Coastguard Worker    char *query;
48*387f9dfdSAndroid Build Coastguard Worker};
49*387f9dfdSAndroid Build Coastguard Worker
50*387f9dfdSAndroid Build Coastguard Workerstruct data_t {
51*387f9dfdSAndroid Build Coastguard Worker    u32 pid;
52*387f9dfdSAndroid Build Coastguard Worker    u64 ts;
53*387f9dfdSAndroid Build Coastguard Worker    u64 delta;
54*387f9dfdSAndroid Build Coastguard Worker    char query[QUERY_MAX];
55*387f9dfdSAndroid Build Coastguard Worker};
56*387f9dfdSAndroid Build Coastguard Worker
57*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(start_tmp, u32, struct start_t);
58*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(events);
59*387f9dfdSAndroid Build Coastguard Worker
60*387f9dfdSAndroid Build Coastguard Workerint do_start(struct pt_regs *ctx) {
61*387f9dfdSAndroid Build Coastguard Worker    u32 tid = bpf_get_current_pid_tgid();
62*387f9dfdSAndroid Build Coastguard Worker    struct start_t start = {};
63*387f9dfdSAndroid Build Coastguard Worker    start.ts = bpf_ktime_get_ns();
64*387f9dfdSAndroid Build Coastguard Worker    bpf_usdt_readarg(1, ctx, &start.query);
65*387f9dfdSAndroid Build Coastguard Worker    start_tmp.update(&tid, &start);
66*387f9dfdSAndroid Build Coastguard Worker    return 0;
67*387f9dfdSAndroid Build Coastguard Worker};
68*387f9dfdSAndroid Build Coastguard Worker
69*387f9dfdSAndroid Build Coastguard Workerint do_done(struct pt_regs *ctx) {
70*387f9dfdSAndroid Build Coastguard Worker    u64 pid_tgid = bpf_get_current_pid_tgid();
71*387f9dfdSAndroid Build Coastguard Worker    u32 pid = pid_tgid >> 32;
72*387f9dfdSAndroid Build Coastguard Worker    u32 tid = (u32)pid_tgid;
73*387f9dfdSAndroid Build Coastguard Worker    struct start_t *sp;
74*387f9dfdSAndroid Build Coastguard Worker
75*387f9dfdSAndroid Build Coastguard Worker    sp = start_tmp.lookup(&tid);
76*387f9dfdSAndroid Build Coastguard Worker    if (sp == 0) {
77*387f9dfdSAndroid Build Coastguard Worker        // missed tracing start
78*387f9dfdSAndroid Build Coastguard Worker        return 0;
79*387f9dfdSAndroid Build Coastguard Worker    }
80*387f9dfdSAndroid Build Coastguard Worker
81*387f9dfdSAndroid Build Coastguard Worker    // check if query exceeded our threshold
82*387f9dfdSAndroid Build Coastguard Worker    u64 delta = bpf_ktime_get_ns() - sp->ts;
83*387f9dfdSAndroid Build Coastguard Worker    if (delta >= """ + str(min_ns) + """) {
84*387f9dfdSAndroid Build Coastguard Worker        // populate and emit data struct
85*387f9dfdSAndroid Build Coastguard Worker        struct data_t data = {.pid = pid, .ts = sp->ts, .delta = delta};
86*387f9dfdSAndroid Build Coastguard Worker        bpf_probe_read_user(&data.query, sizeof(data.query), (void *)sp->query);
87*387f9dfdSAndroid Build Coastguard Worker        events.perf_submit(ctx, &data, sizeof(data));
88*387f9dfdSAndroid Build Coastguard Worker    }
89*387f9dfdSAndroid Build Coastguard Worker
90*387f9dfdSAndroid Build Coastguard Worker    start_tmp.delete(&tid);
91*387f9dfdSAndroid Build Coastguard Worker
92*387f9dfdSAndroid Build Coastguard Worker    return 0;
93*387f9dfdSAndroid Build Coastguard Worker};
94*387f9dfdSAndroid Build Coastguard Worker
95*387f9dfdSAndroid Build Coastguard Worker"""
96*387f9dfdSAndroid Build Coastguard Worker
97*387f9dfdSAndroid Build Coastguard Worker# enable USDT probe from given PID
98*387f9dfdSAndroid Build Coastguard Workeru = USDT(pid=pid)
99*387f9dfdSAndroid Build Coastguard Workeru.enable_probe(probe="query__start", fn_name="do_start")
100*387f9dfdSAndroid Build Coastguard Workeru.enable_probe(probe="query__done", fn_name="do_done")
101*387f9dfdSAndroid Build Coastguard Workerif debug:
102*387f9dfdSAndroid Build Coastguard Worker    print(u.get_text())
103*387f9dfdSAndroid Build Coastguard Worker    print(bpf_text)
104*387f9dfdSAndroid Build Coastguard Worker
105*387f9dfdSAndroid Build Coastguard Worker# initialize BPF
106*387f9dfdSAndroid Build Coastguard Workerb = BPF(text=bpf_text, usdt_contexts=[u])
107*387f9dfdSAndroid Build Coastguard Worker
108*387f9dfdSAndroid Build Coastguard Worker# header
109*387f9dfdSAndroid Build Coastguard Workerprint("Tracing MySQL server queries for PID %d slower than %s ms..." % (pid,
110*387f9dfdSAndroid Build Coastguard Worker    min_ms_text))
111*387f9dfdSAndroid Build Coastguard Workerprint("%-14s %-7s %8s %s" % ("TIME(s)", "PID", "MS", "QUERY"))
112*387f9dfdSAndroid Build Coastguard Worker
113*387f9dfdSAndroid Build Coastguard Worker# process event
114*387f9dfdSAndroid Build Coastguard Workerstart = 0
115*387f9dfdSAndroid Build Coastguard Workerdef print_event(cpu, data, size):
116*387f9dfdSAndroid Build Coastguard Worker    global start
117*387f9dfdSAndroid Build Coastguard Worker    event = b["events"].event(data)
118*387f9dfdSAndroid Build Coastguard Worker    if start == 0:
119*387f9dfdSAndroid Build Coastguard Worker        start = event.ts
120*387f9dfdSAndroid Build Coastguard Worker    print("%-14.6f %-7d %8.3f %s" % (float(event.ts - start) / 1000000000,
121*387f9dfdSAndroid Build Coastguard Worker        event.pid, float(event.delta) / 1000000, event.query))
122*387f9dfdSAndroid Build Coastguard Worker
123*387f9dfdSAndroid Build Coastguard Worker# loop with callback to print_event
124*387f9dfdSAndroid Build Coastguard Workerb["events"].open_perf_buffer(print_event, page_cnt=64)
125*387f9dfdSAndroid Build Coastguard Workerwhile 1:
126*387f9dfdSAndroid Build Coastguard Worker    try:
127*387f9dfdSAndroid Build Coastguard Worker        b.perf_buffer_poll()
128*387f9dfdSAndroid Build Coastguard Worker    except KeyboardInterrupt:
129*387f9dfdSAndroid Build Coastguard Worker        exit()
130