--- /dev/null
+// p_s - library routines for pstop.
+//
+// This file contains the library routines for managing the
+// file_summary_by_instance table.
+package file_summary_by_instance
+
+import (
+ "database/sql"
+ "fmt"
+ "time"
+
+ "github.com/sjmudd/pstop/lib"
+ "github.com/sjmudd/pstop/p_s"
+)
+
+/*
+CREATE TABLE `file_summary_by_instance` (
+ `FILE_NAME` varchar(512) NOT NULL,
+ `EVENT_NAME` varchar(128) NOT NULL, // not collected
+ `OBJECT_INSTANCE_BEGIN` bigint(20) unsigned NOT NULL, // not collected
+ `COUNT_STAR` bigint(20) unsigned NOT NULL,
+ `SUM_TIMER_WAIT` bigint(20) unsigned NOT NULL,
+ `MIN_TIMER_WAIT` bigint(20) unsigned NOT NULL,
+ `AVG_TIMER_WAIT` bigint(20) unsigned NOT NULL,
+ `MAX_TIMER_WAIT` bigint(20) unsigned NOT NULL,
+ `COUNT_READ` bigint(20) unsigned NOT NULL,
+ `SUM_TIMER_READ` bigint(20) unsigned NOT NULL,
+ `MIN_TIMER_READ` bigint(20) unsigned NOT NULL,
+ `AVG_TIMER_READ` bigint(20) unsigned NOT NULL,
+ `MAX_TIMER_READ` bigint(20) unsigned NOT NULL,
+ `SUM_NUMBER_OF_BYTES_READ` bigint(20) NOT NULL,
+ `COUNT_WRITE` bigint(20) unsigned NOT NULL,
+ `SUM_TIMER_WRITE` bigint(20) unsigned NOT NULL,
+ `MIN_TIMER_WRITE` bigint(20) unsigned NOT NULL,
+ `AVG_TIMER_WRITE` bigint(20) unsigned NOT NULL,
+ `MAX_TIMER_WRITE` bigint(20) unsigned NOT NULL,
+ `SUM_NUMBER_OF_BYTES_WRITE` bigint(20) NOT NULL,
+ `COUNT_MISC` bigint(20) unsigned NOT NULL,
+ `SUM_TIMER_MISC` bigint(20) unsigned NOT NULL,
+ `MIN_TIMER_MISC` bigint(20) unsigned NOT NULL,
+ `AVG_TIMER_MISC` bigint(20) unsigned NOT NULL,
+ `MAX_TIMER_MISC` bigint(20) unsigned NOT NULL
+) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
+1 row in set (0.00 sec)
+
+*/
+
+// a table of rows
+type File_summary_by_instance struct {
+ p_s.RelativeStats
+ p_s.InitialTime
+ initial file_summary_by_instance_rows
+ current file_summary_by_instance_rows
+ results file_summary_by_instance_rows
+ totals file_summary_by_instance_row
+ global_variables map[string]string
+}
+
+// reset the statistics to current values
+func (t *File_summary_by_instance) SyncReferenceValues() {
+ t.SetNow()
+ t.initial = make(file_summary_by_instance_rows, len(t.current))
+ copy(t.initial, t.current)
+
+ t.results = make(file_summary_by_instance_rows, len(t.current))
+ copy(t.results, t.current)
+
+ if t.WantRelativeStats() {
+ t.results.subtract(t.initial) // should be 0 if relative
+ }
+
+ t.results.sort()
+ t.totals = t.results.totals()
+}
+
+// Collect data from the db, then merge it in.
+func (t *File_summary_by_instance) Collect(dbh *sql.DB) {
+ start := time.Now()
+ // UPDATE current from db handle
+ t.current = merge_by_table_name(select_fsbi_rows(dbh), t.global_variables)
+
+ // copy in initial data if it was not there
+ if len(t.initial) == 0 && len(t.current) > 0 {
+ t.initial = make(file_summary_by_instance_rows, len(t.current))
+ copy(t.initial, t.current)
+ }
+
+ // check for reload initial characteristics
+ if t.initial.needs_refresh(t.current) {
+ t.initial = make(file_summary_by_instance_rows, len(t.current))
+ copy(t.initial, t.current)
+ }
+
+ // update results to current value
+ t.results = make(file_summary_by_instance_rows, len(t.current))
+ copy(t.results, t.current)
+
+ // make relative if need be
+ if t.WantRelativeStats() {
+ t.results.subtract(t.initial)
+ }
+
+ // sort the results
+ t.results.sort()
+
+ // setup the totals
+ t.totals = t.results.totals()
+ lib.Logger.Println("File_summary_by_instance.Collect() took:", time.Duration(time.Since(start)).String())
+}
+
+// return the headings for a table
+func (t File_summary_by_instance) Headings() string {
+ var r file_summary_by_instance_row
+
+ return r.headings()
+}
+
+// return the rows we need for displaying
+func (t File_summary_by_instance) RowContent(max_rows int) []string {
+ rows := make([]string, 0, max_rows)
+
+ for i := range t.results {
+ if i < max_rows {
+ rows = append(rows, t.results[i].row_content(t.totals))
+ }
+ }
+
+ return rows
+}
+
+// return all the totals
+func (t File_summary_by_instance) TotalRowContent() string {
+ return t.totals.row_content(t.totals)
+}
+
+// return an empty string of data (for filling in)
+func (t File_summary_by_instance) EmptyRowContent() string {
+ var emtpy file_summary_by_instance_row
+ return emtpy.row_content(emtpy)
+}
+
+func (t File_summary_by_instance) Description() string {
+ count := t.count_rows()
+ return fmt.Sprintf("File I/O by filename (file_summary_by_instance) %4d row(s) ", count)
+}
+
+// create a new structure and include various variable values:
+// - datadir, relay_log
+// There's no checking that these are actually provided!
+func NewFileSummaryByInstance(global_variables map[string]string) *File_summary_by_instance {
+ n := new(File_summary_by_instance)
+
+ n.global_variables = global_variables
+
+ return n
+}
+
+func (t File_summary_by_instance) count_rows() int {
+ var count int
+ for row := range t.results {
+ if t.results[row].SUM_TIMER_WAIT > 0 {
+ count++
+ }
+ }
+ return count
+}