Skip to content

Commit ad2d127

Browse files
committed
Add extra columns from pg_stat_statements in pg13.
1 parent 1410e62 commit ad2d127

2 files changed

Lines changed: 76 additions & 4 deletions

File tree

collector/collect.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1723,6 +1723,67 @@ func (c *collector) getStatements(currdb string) {
17231723
return
17241724
}
17251725

1726+
if c.version >= 130000 {
1727+
c.getStatementsv13(currdb)
1728+
} else {
1729+
c.getStatementsPrev13(currdb)
1730+
}
1731+
}
1732+
1733+
func (c *collector) getStatementsv13(currdb string) {
1734+
ctx, cancel := context.WithTimeout(context.Background(), c.timeout)
1735+
defer cancel()
1736+
1737+
q := `SELECT userid, dbid, queryid, LEFT(COALESCE(query, ''), $1), calls,
1738+
total_exec_time, min_exec_time, max_exec_time, stddev_exec_time,
1739+
rows, shared_blks_hit, shared_blks_read, shared_blks_dirtied,
1740+
shared_blks_written, local_blks_hit, local_blks_read,
1741+
local_blks_dirtied, local_blks_written, temp_blks_read,
1742+
temp_blks_written, blk_read_time, blk_write_time,
1743+
plans, total_plan_time, min_plan_time, max_plan_time,
1744+
stddev_plan_time, wal_records, wal_fpi, wal_bytes::bigint
1745+
FROM pg_stat_statements
1746+
ORDER BY total_exec_time DESC
1747+
LIMIT $2`
1748+
rows, err := c.db.QueryContext(ctx, q, c.sqlLength, c.stmtsLimit)
1749+
if err != nil {
1750+
log.Printf("warning: pg_stat_statements query failed: %v", err)
1751+
return
1752+
}
1753+
defer rows.Close()
1754+
1755+
c.result.Statements = make([]pgmetrics.Statement, 0, c.stmtsLimit)
1756+
for rows.Next() {
1757+
var s pgmetrics.Statement
1758+
var queryID sql.NullInt64
1759+
if err := rows.Scan(&s.UserOID, &s.DBOID, &queryID, &s.Query,
1760+
&s.Calls, &s.TotalTime, &s.MinTime, &s.MaxTime, &s.StddevTime,
1761+
&s.Rows, &s.SharedBlksHit, &s.SharedBlksRead, &s.SharedBlksDirtied,
1762+
&s.SharedBlksWritten, &s.LocalBlksHit, &s.LocalBlksRead,
1763+
&s.LocalBlksDirtied, &s.LocalBlksWritten, &s.TempBlksRead,
1764+
&s.TempBlksWritten, &s.BlkReadTime, &s.BlkWriteTime, &s.Plans,
1765+
&s.TotalPlanTime, &s.MinPlanTime, &s.MaxPlanTime, &s.StddevPlanTime,
1766+
&s.WALRecords, &s.WALFPI, &s.WALBytes); err != nil {
1767+
log.Fatalf("pg_stat_statements scan failed: %v", err)
1768+
}
1769+
// UserName
1770+
if r := c.result.RoleByOID(s.UserOID); r != nil {
1771+
s.UserName = r.Name
1772+
}
1773+
// DBName
1774+
if d := c.result.DatabaseByOID(s.DBOID); d != nil {
1775+
s.DBName = d.Name
1776+
}
1777+
// Query ID, set to 0 if null
1778+
s.QueryID = queryID.Int64
1779+
c.result.Statements = append(c.result.Statements, s)
1780+
}
1781+
if err := rows.Err(); err != nil {
1782+
log.Fatalf("pg_stat_statements failed: %v", err)
1783+
}
1784+
}
1785+
1786+
func (c *collector) getStatementsPrev13(currdb string) {
17261787
ctx, cancel := context.WithTimeout(context.Background(), c.timeout)
17271788
defer cancel()
17281789

@@ -1752,6 +1813,7 @@ func (c *collector) getStatements(currdb string) {
17521813
// If we still have errors, silently give up on querying
17531814
// pg_stat_statements.
17541815
if err != nil {
1816+
log.Printf("warning: pg_stat_statements query failed: %v", err)
17551817
return
17561818
}
17571819
}

model.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package pgmetrics
1818

1919
// ModelSchemaVersion is the schema version of the "Model" data structure
2020
// defined below. It is in the "semver" notation. Version history:
21+
// 1.10 - New fields in pg_stat_statements for Postgres 13
2122
// 1.9 - Postgres 13, Citus support
2223
// 1.8 - AWS RDS/EnhancedMonitoring metrics, index defn,
2324
// backend type counts, slab memory (linux), user agent
@@ -515,10 +516,10 @@ type Statement struct {
515516
QueryID int64 `json:"queryid"` // Internal hash code, computed from the statement's parse tree
516517
Query string `json:"query"` // Text of a representative statement
517518
Calls int64 `json:"calls"` // Number of times executed
518-
TotalTime float64 `json:"total_time"` // Total time spent in the statement, in milliseconds
519-
MinTime float64 `json:"min_time"` // Minimum time spent in the statement, in milliseconds
520-
MaxTime float64 `json:"max_time"` // Maximum time spent in the statement, in milliseconds
521-
StddevTime float64 `json:"stddev_time"` // Population standard deviation of time spent in the statement, in milliseconds
519+
TotalTime float64 `json:"total_time"` // Total time spent executing the statement, in milliseconds
520+
MinTime float64 `json:"min_time"` // Minimum time spent executing the statement, in milliseconds
521+
MaxTime float64 `json:"max_time"` // Maximum time spent executing the statement, in milliseconds
522+
StddevTime float64 `json:"stddev_time"` // Population standard deviation of time spent executing the statement, in milliseconds
522523
Rows int64 `json:"rows"` // Total number of rows retrieved or affected by the statement
523524
SharedBlksHit int64 `json:"shared_blks_hit"` // Total number of shared block cache hits by the statement
524525
SharedBlksRead int64 `json:"shared_blks_read"` // Total number of shared blocks read by the statement
@@ -532,6 +533,15 @@ type Statement struct {
532533
TempBlksWritten int64 `json:"temp_blks_written"` // Total number of temp blocks written by the statement
533534
BlkReadTime float64 `json:"blk_read_time"` // Total time the statement spent reading blocks, in milliseconds (if track_io_timing is enabled, otherwise zero)
534535
BlkWriteTime float64 `json:"blk_write_time"` // Total time the statement spent writing blocks, in milliseconds (if track_io_timing is enabled, otherwise zero)
536+
// following fields present only in schema 1.10 and later (for Postgres v13+)
537+
Plans int64 `json:"plans"` // Number of times the statement was planned
538+
TotalPlanTime float64 `json:"total_plan_time"` // Total time spent planning the statement, in milliseconds
539+
MinPlanTime float64 `json:"min_plan_time"` // Minimum time spent planning the statement, in milliseconds
540+
MaxPlanTime float64 `json:"max_plan_time"` // Maximum time spent planning the statement, in milliseconds
541+
StddevPlanTime float64 `json:"stddev_plan_time"` // Population standard deviation of time spent planning the statement, in milliseconds
542+
WALRecords int64 `json:"wal_records"` // Total number of WAL records generated by the statement
543+
WALFPI int64 `json:"wal_fpi"` // Total number of WAL full page images generated by the statement
544+
WALBytes int64 `json:"wal_bytes"` // Total amount of WAL bytes generated by the statement
535545
}
536546

537547
// Publication represents a single v10+ publication. Added in schema 1.2.

0 commit comments

Comments
 (0)