Stages now seems to work ok
[pstop.git] / p_s / events_stages_summary_global_by_event_name / public.go
1 // public interface to events_stages_summary_global_by_event_name
2 package events_stages_summary_global_by_event_name
3
4 import (
5         "database/sql"
6         "fmt"
7         "time"
8
9         "github.com/sjmudd/pstop/lib"
10         "github.com/sjmudd/pstop/p_s"
11 )
12
13 /*
14
15 root@localhost [performance_schema]> select * from events_stages_summary_global_by_event_name where sum_timer_wait > 0;
16 +--------------------------------+------------+----------------+----------------+----------------+----------------+
17 | EVENT_NAME                     | COUNT_STAR | SUM_TIMER_WAIT | MIN_TIMER_WAIT | AVG_TIMER_WAIT | MAX_TIMER_WAIT |
18 +--------------------------------+------------+----------------+----------------+----------------+----------------+
19 | stage/sql/After create         |          3 |       21706000 |         558000 |        7235000 |       11693000 |
20 | stage/sql/checking permissions |       5971 |    92553236000 |         406000 |       15500000 |    12727728000 |
21 | stage/sql/cleaning up          |       6531 |     4328103000 |         154000 |         662000 |       23464000 |
22 | stage/sql/closing tables       |       4281 |    18303106000 |         118000 |        4275000 |       71505000 |
23 | stage/sql/Creating sort index  |          2 |    31300648000 |    14183237000 |    15650324000 |    17117411000 |
24 | stage/sql/creating table       |          2 |   138276471000 |    64077127000 |    69138235000 |    74199344000 |
25 | stage/sql/end                  |       4254 |     9940694000 |         220000 |        2336000 |       42683000 |
26 | stage/sql/executing            |       1256 |   252300800000 |         151000 |      200876000 |    59564212000 |
27 | stage/sql/freeing items        |       3733 |    83966405000 |        5341000 |       22493000 |     2527549000 |
28 | stage/sql/init                 |       4256 |    63836793000 |        1990000 |       14999000 |     7656920000 |
29 | stage/sql/Opening tables       |       6002 |  1489653915000 |        1411000 |      248192000 |   216300236000 |
30 | stage/sql/optimizing           |       1257 |  2685426016000 |         255000 |     2136377000 |  2656149827000 |
31 | stage/sql/preparing            |       1166 |     8626237000 |        1666000 |        7398000 |       91804000 |
32 | stage/sql/query end            |       4280 |    37299265000 |         411000 |        8714000 |    12018400000 |
33 | stage/sql/removing tmp table   |       1187 |    11890909000 |        1838000 |       10017000 |     2365358000 |
34 | stage/sql/Sending data         |       1165 |  3071893676000 |        2925000 |     2636818000 |    63354201000 |
35 | stage/sql/Sorting result       |          2 |        4128000 |        1930000 |        2064000 |        2198000 |
36 | stage/sql/statistics           |       1166 |    26655651000 |        2078000 |       22860000 |     8446818000 |
37 | stage/sql/System lock          |       4263 |  1901250693000 |         584000 |      445988000 |  1651181465000 |
38 | stage/sql/update               |          4 |     8246608000 |       78145000 |     2061652000 |     7597263000 |
39 | stage/sql/updating             |       2994 |  1608420140000 |      285867000 |      537214000 |    15651495000 |
40 | stage/sql/starting             |       6532 |   364087027000 |        2179000 |       55738000 |    23420395000 |
41 +--------------------------------+------------+----------------+----------------+----------------+----------------+
42 22 rows in set (0.01 sec)
43
44 */
45
46 // public view of object
47 type Object struct {
48         p_s.RelativeStats
49         p_s.InitialTime
50         initial table_rows // initial data for relative values
51         current table_rows // last loaded values
52         results table_rows // results (maybe with subtraction)
53         totals  table_row  // totals of results
54 }
55
56 // Collect() collects data from the db, updating initial
57 // values if needed, and then subtracting initial values if we want
58 // relative values, after which it stores totals.
59 func (t *Object) Collect(dbh *sql.DB) {
60         start := time.Now()
61         t.current = select_rows(dbh)
62         lib.Logger.Println("t.current collected", len(t.current), "row(s) from SELECT")
63
64         if len(t.initial) == 0 && len(t.current) > 0 {
65                 lib.Logger.Println("t.initial: copying from t.current (initial setup)")
66                 t.initial = make(table_rows, len(t.current))
67                 copy(t.initial, t.current)
68         }
69
70         // check for reload initial characteristics
71         if t.initial.needs_refresh(t.current) {
72                 lib.Logger.Println("t.initial: copying from t.current (data needs refreshing)")
73                 t.initial = make(table_rows, len(t.current))
74                 copy(t.initial, t.current)
75         }
76
77         t.make_results()
78
79         // lib.Logger.Println( "t.initial:", t.initial )
80         // lib.Logger.Println( "t.current:", t.current )
81         lib.Logger.Println("t.initial.totals():", t.initial.totals())
82         lib.Logger.Println("t.current.totals():", t.current.totals())
83         // lib.Logger.Println("t.results:", t.results)
84         // lib.Logger.Println("t.totals:", t.totals)
85         lib.Logger.Println("Table_io_waits_summary_by_table.Collect() END, took:", time.Duration(time.Since(start)).String())
86 }
87
88 // return the headings of the object
89 func (t *Object) Headings() string {
90         return t.totals.headings()
91 }
92
93 // return a slice of strings containing the row content
94 func (t Object) RowContent(max_rows int) []string {
95         rows := make([]string, 0, max_rows)
96
97         for i := range t.results {
98                 if i < max_rows {
99                         rows = append(rows, t.results[i].row_content(t.totals))
100                 }
101         }
102
103         return rows
104 }
105
106 // return an empty row
107 func (t Object) EmptyRowContent() string {
108         var e table_row
109
110         return e.row_content(e)
111 }
112
113 // return a row containing the totals
114 func (t Object) TotalRowContent() string {
115         return t.totals.row_content(t.totals)
116 }
117
118 // describe the stages
119 func (t Object) Description() string {
120         count := t.count_rows()
121         return fmt.Sprintf("Latency by SQL stage (events_stages_summary_global_by_event_name) %d rows", count)
122 }
123
124 // reset the statistics to current values
125 func (t *Object) SyncReferenceValues() {
126         t.SetNow()
127         t.initial = make(table_rows, len(t.current))
128         copy(t.initial, t.current)
129
130         t.make_results()
131 }
132
133 // generate the results and totals and sort data
134 func (t *Object) make_results() {
135         // lib.Logger.Println( "- t.results set from t.current" )
136         t.results = make(table_rows, len(t.current))
137         copy(t.results, t.current)
138         if t.WantRelativeStats() {
139                 t.results.subtract(t.initial)
140         }
141
142         t.results.Sort()
143         t.totals = t.results.totals()
144 }
145
146 // count the number of rows we have data for
147 func (t Object) count_rows() int {
148         var count int
149         for row := range t.results {
150                 if t.results[row].SUM_TIMER_WAIT > 0 {
151                         count++
152                 }
153         }
154         return count
155 }