You've already forked postgres_exporter
mirror of
https://github.com/prometheus-community/postgres_exporter.git
synced 2026-10-23 12:08:57 +03:00
Optimize pg_stat_statements queries (#1267)
Signed-off-by: Emin Umut Gercek <eumutgercek@gmail.com>
This commit is contained in:
@@ -187,14 +187,14 @@ const (
|
||||
pg_stat_statements.rows as rows_total,
|
||||
pg_stat_statements.blk_read_time / 1000.0 as block_read_seconds_total,
|
||||
pg_stat_statements.blk_write_time / 1000.0 as block_write_seconds_total
|
||||
FROM pg_stat_statements
|
||||
FROM pg_stat_statements(%t)
|
||||
JOIN pg_database
|
||||
ON pg_database.oid = pg_stat_statements.dbid
|
||||
WHERE
|
||||
total_exec_time > (
|
||||
SELECT percentile_cont(0.1)
|
||||
WITHIN GROUP (ORDER BY total_exec_time)
|
||||
FROM pg_stat_statements
|
||||
FROM pg_stat_statements(false)
|
||||
)
|
||||
%s %s
|
||||
ORDER BY seconds_total DESC
|
||||
@@ -210,14 +210,14 @@ const (
|
||||
pg_stat_statements.rows as rows_total,
|
||||
pg_stat_statements.shared_blk_read_time / 1000.0 as block_read_seconds_total,
|
||||
pg_stat_statements.shared_blk_write_time / 1000.0 as block_write_seconds_total
|
||||
FROM pg_stat_statements
|
||||
FROM pg_stat_statements(%t)
|
||||
JOIN pg_database
|
||||
ON pg_database.oid = pg_stat_statements.dbid
|
||||
WHERE
|
||||
total_exec_time > (
|
||||
SELECT percentile_cont(0.1)
|
||||
WITHIN GROUP (ORDER BY total_exec_time)
|
||||
FROM pg_stat_statements
|
||||
FROM pg_stat_statements(false)
|
||||
)
|
||||
%s %s
|
||||
ORDER BY seconds_total DESC
|
||||
@@ -225,15 +225,6 @@ const (
|
||||
)
|
||||
|
||||
func (c PGStatStatementsCollector) Update(ctx context.Context, instance *instance, ch chan<- prometheus.Metric) error {
|
||||
var queryTemplate string
|
||||
switch {
|
||||
case instance.version.GE(semver.MustParse("17.0.0")):
|
||||
queryTemplate = pgStatStatementsQuery_PG17
|
||||
case instance.version.GE(semver.MustParse("13.0.0")):
|
||||
queryTemplate = pgStatStatementsQuery_PG13
|
||||
default:
|
||||
queryTemplate = pgStatStatementsQuery
|
||||
}
|
||||
querySelect := ""
|
||||
if c.includeQueryStatement {
|
||||
querySelect = fmt.Sprintf(pgStatStatementQuerySelect, c.statementLength)
|
||||
@@ -244,7 +235,16 @@ func (c PGStatStatementsCollector) Update(ctx context.Context, instance *instanc
|
||||
if c.statementLimit > 0 {
|
||||
statementLimit = fmt.Sprintf("%d", c.statementLimit)
|
||||
}
|
||||
query := fmt.Sprintf(queryTemplate, querySelect, databaseFilter, userFilter, statementLimit)
|
||||
|
||||
var query string
|
||||
switch {
|
||||
case instance.version.GE(semver.MustParse("17.0.0")):
|
||||
query = fmt.Sprintf(pgStatStatementsQuery_PG17, querySelect, c.includeQueryStatement, databaseFilter, userFilter, statementLimit)
|
||||
case instance.version.GE(semver.MustParse("13.0.0")):
|
||||
query = fmt.Sprintf(pgStatStatementsQuery_PG13, querySelect, c.includeQueryStatement, databaseFilter, userFilter, statementLimit)
|
||||
default:
|
||||
query = fmt.Sprintf(pgStatStatementsQuery, querySelect, databaseFilter, userFilter, statementLimit)
|
||||
}
|
||||
|
||||
db := instance.getDB()
|
||||
rows, err := db.QueryContext(ctx, query)
|
||||
|
||||
@@ -167,7 +167,7 @@ func TestPGStatStatementsCollectorNull(t *testing.T) {
|
||||
columns := []string{"user", "datname", "queryid", "calls_total", "seconds_total", "rows_total", "block_read_seconds_total", "block_write_seconds_total"}
|
||||
rows := sqlmock.NewRows(columns).
|
||||
AddRow(nil, nil, nil, nil, nil, nil, nil, nil)
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG13, "", "", "", defaultStatementLimit))).WillReturnRows(rows)
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG13, "", false, "", "", defaultStatementLimit))).WillReturnRows(rows)
|
||||
|
||||
ch := make(chan prometheus.Metric)
|
||||
go func() {
|
||||
@@ -210,7 +210,7 @@ func TestPGStatStatementsCollectorNullWithStatement(t *testing.T) {
|
||||
columns := []string{"user", "datname", "queryid", "LEFT(pg_stat_statements.query, 200) as query", "calls_total", "seconds_total", "rows_total", "block_read_seconds_total", "block_write_seconds_total"}
|
||||
rows := sqlmock.NewRows(columns).
|
||||
AddRow(nil, nil, nil, nil, nil, nil, nil, nil, nil)
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG13, fmt.Sprintf(pgStatStatementQuerySelect, 200), "", "", defaultStatementLimit))).WillReturnRows(rows)
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG13, fmt.Sprintf(pgStatStatementQuerySelect, 200), true, "", "", defaultStatementLimit))).WillReturnRows(rows)
|
||||
|
||||
ch := make(chan prometheus.Metric)
|
||||
go func() {
|
||||
@@ -254,7 +254,7 @@ func TestPGStatStatementsCollectorNullWithStatementAndLimit(t *testing.T) {
|
||||
columns := []string{"user", "datname", "queryid", "LEFT(pg_stat_statements.query, 200) as query", "calls_total", "seconds_total", "rows_total", "block_read_seconds_total", "block_write_seconds_total"}
|
||||
rows := sqlmock.NewRows(columns).
|
||||
AddRow(nil, nil, nil, nil, nil, nil, nil, nil, nil)
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG13, fmt.Sprintf(pgStatStatementQuerySelect, 200), "", "", "10"))).WillReturnRows(rows)
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG13, fmt.Sprintf(pgStatStatementQuerySelect, 200), true, "", "", "10"))).WillReturnRows(rows)
|
||||
|
||||
ch := make(chan prometheus.Metric)
|
||||
go func() {
|
||||
@@ -298,7 +298,7 @@ func TestPGStatStatementsCollector_PG13(t *testing.T) {
|
||||
columns := []string{"user", "datname", "queryid", "calls_total", "seconds_total", "rows_total", "block_read_seconds_total", "block_write_seconds_total"}
|
||||
rows := sqlmock.NewRows(columns).
|
||||
AddRow("postgres", "postgres", 1500, 5, 0.4, 100, 0.1, 0.2)
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG13, "", "", "", defaultStatementLimit))).WillReturnRows(rows)
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG13, "", false, "", "", defaultStatementLimit))).WillReturnRows(rows)
|
||||
|
||||
ch := make(chan prometheus.Metric)
|
||||
go func() {
|
||||
@@ -341,7 +341,7 @@ func TestPGStatStatementsCollector_PG13_WithStatement(t *testing.T) {
|
||||
columns := []string{"user", "datname", "queryid", "LEFT(pg_stat_statements.query, 300) as query", "calls_total", "seconds_total", "rows_total", "block_read_seconds_total", "block_write_seconds_total"}
|
||||
rows := sqlmock.NewRows(columns).
|
||||
AddRow("postgres", "postgres", 1500, "select 1 from foo", 5, 0.4, 100, 0.1, 0.2)
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG13, fmt.Sprintf(pgStatStatementQuerySelect, 300), "", "", defaultStatementLimit))).WillReturnRows(rows)
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG13, fmt.Sprintf(pgStatStatementQuerySelect, 300), true, "", "", defaultStatementLimit))).WillReturnRows(rows)
|
||||
|
||||
ch := make(chan prometheus.Metric)
|
||||
go func() {
|
||||
@@ -385,7 +385,7 @@ func TestPGStatStatementsCollector_PG13_WithStatementAndLimit(t *testing.T) {
|
||||
columns := []string{"user", "datname", "queryid", "LEFT(pg_stat_statements.query, 300) as query", "calls_total", "seconds_total", "rows_total", "block_read_seconds_total", "block_write_seconds_total"}
|
||||
rows := sqlmock.NewRows(columns).
|
||||
AddRow("postgres", "postgres", 1500, "select 1 from foo", 5, 0.4, 100, 0.1, 0.2)
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG13, fmt.Sprintf(pgStatStatementQuerySelect, 300), "", "", "10"))).WillReturnRows(rows)
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG13, fmt.Sprintf(pgStatStatementQuerySelect, 300), true, "", "", "10"))).WillReturnRows(rows)
|
||||
|
||||
ch := make(chan prometheus.Metric)
|
||||
go func() {
|
||||
@@ -429,7 +429,7 @@ func TestPGStatStatementsCollector_PG17(t *testing.T) {
|
||||
columns := []string{"user", "datname", "queryid", "calls_total", "seconds_total", "rows_total", "block_read_seconds_total", "block_write_seconds_total"}
|
||||
rows := sqlmock.NewRows(columns).
|
||||
AddRow("postgres", "postgres", 1500, 5, 0.4, 100, 0.1, 0.2)
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG17, "", "", "", defaultStatementLimit))).WillReturnRows(rows)
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG17, "", false, "", "", defaultStatementLimit))).WillReturnRows(rows)
|
||||
|
||||
ch := make(chan prometheus.Metric)
|
||||
go func() {
|
||||
@@ -472,7 +472,7 @@ func TestPGStatStatementsCollector_PG17_WithStatement(t *testing.T) {
|
||||
columns := []string{"user", "datname", "queryid", "LEFT(pg_stat_statements.query, 300) as query", "calls_total", "seconds_total", "rows_total", "block_read_seconds_total", "block_write_seconds_total"}
|
||||
rows := sqlmock.NewRows(columns).
|
||||
AddRow("postgres", "postgres", 1500, "select 1 from foo", 5, 0.4, 100, 0.1, 0.2)
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG17, fmt.Sprintf(pgStatStatementQuerySelect, 300), "", "", defaultStatementLimit))).WillReturnRows(rows)
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG17, fmt.Sprintf(pgStatStatementQuerySelect, 300), true, "", "", defaultStatementLimit))).WillReturnRows(rows)
|
||||
|
||||
ch := make(chan prometheus.Metric)
|
||||
go func() {
|
||||
@@ -516,7 +516,7 @@ func TestPGStatStatementsCollector_PG17_WithStatementAndLimit(t *testing.T) {
|
||||
columns := []string{"user", "datname", "queryid", "LEFT(pg_stat_statements.query, 300) as query", "calls_total", "seconds_total", "rows_total", "block_read_seconds_total", "block_write_seconds_total"}
|
||||
rows := sqlmock.NewRows(columns).
|
||||
AddRow("postgres", "postgres", 1500, "select 1 from foo", 5, 0.4, 100, 0.1, 0.2)
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG17, fmt.Sprintf(pgStatStatementQuerySelect, 300), "", "", "10"))).WillReturnRows(rows)
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG17, fmt.Sprintf(pgStatStatementQuerySelect, 300), true, "", "", "10"))).WillReturnRows(rows)
|
||||
|
||||
ch := make(chan prometheus.Metric)
|
||||
go func() {
|
||||
@@ -613,7 +613,7 @@ func TestPGStatStatementsCollectorWithExcludedDatabasesSQLEscaping(t *testing.T)
|
||||
AddRow("postgres", "postgres", 1500, 5, 0.4, 100, 0.1, 0.2)
|
||||
|
||||
expectedFilter := " AND pg_database.datname NOT IN ('test''db')"
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG13, "", expectedFilter, "", defaultStatementLimit))).WillReturnRows(rows)
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG13, "", false, expectedFilter, "", defaultStatementLimit))).WillReturnRows(rows)
|
||||
|
||||
ch := make(chan prometheus.Metric)
|
||||
go func() {
|
||||
@@ -708,7 +708,7 @@ func TestPGStatStatementsCollectorWithExcludedUsersSQLEscaping(t *testing.T) {
|
||||
AddRow("postgres", "postgres", 1500, 5, 0.4, 100, 0.1, 0.2)
|
||||
|
||||
expectedFilter := " AND pg_get_userbyid(userid) NOT IN ('test''user')"
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG13, "", "", expectedFilter, defaultStatementLimit))).WillReturnRows(rows)
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG13, "", false, "", expectedFilter, defaultStatementLimit))).WillReturnRows(rows)
|
||||
|
||||
ch := make(chan prometheus.Metric)
|
||||
go func() {
|
||||
@@ -758,7 +758,7 @@ func TestPGStatStatementsCollectorWithExcludedDatabasesAndUsers(t *testing.T) {
|
||||
|
||||
expectedDbFilter := " AND pg_database.datname NOT IN ('rdsadmin', 'cloudsqladmin')"
|
||||
expectedUserFilter := " AND pg_get_userbyid(userid) NOT IN ('monitoring', 'readonly')"
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG17, "", expectedDbFilter, expectedUserFilter, defaultStatementLimit))).WillReturnRows(rows)
|
||||
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery_PG17, "", false, expectedDbFilter, expectedUserFilter, defaultStatementLimit))).WillReturnRows(rows)
|
||||
|
||||
ch := make(chan prometheus.Metric)
|
||||
go func() {
|
||||
|
||||
Reference in New Issue
Block a user