Skip to content

[+] add longest_idle_in_tx_seconds to backends - #1613

Open
pashagolub wants to merge 2 commits into
v7from
backends-idle-in-tx-age
Open

pashagolub wants to merge 2 commits into
v7from
backends-idle-in-tx-age

Conversation

@pashagolub

Copy link
Copy Markdown
Collaborator

Summary

backends counts idle-in-transaction sessions but does not say how long they have been idle. The new gauge longest_idle_in_tx_seconds holds the seconds since the oldest idle-in-transaction client session, aborted ones included, entered that state. It is null when there is no such session.

 (select count(*) from sa_snapshot where state = 'idle in transaction' and backend_type = 'client backend') as idleintransaction,
+(select round(extract(epoch from max(now() - state_change)), 3)::float from sa_snapshot
+  where state in ('idle in transaction', 'idle in transaction (aborted)')
+    and backend_type = 'client backend') as longest_idle_in_tx_seconds,

It uses state_change, not xact_start, so a transaction that worked for ten minutes and then paused for one second shows 1 s. longest_tx_seconds already reports the transaction age.

Both v13 sessions overview dashboards get a new panel after "Longest TX duration":

 Sessions overview (postgres, prometheus)
   Longest TX duration
+  Longest idle-in-transaction duration
   ...

The second commit fixes the v13 postgres dashboards, which cast the fractional *_seconds columns of backends to int/int8. Postgres rejects that cast, so the panels returned errors instead of data. They now cast to float in sessions-overview, global-health and recommendations.

Evidence

  • Before: backends had no idle age column. The v13 dashboard cast failed:
    select ('{"s":12.345}'::jsonb->>'s')::int8
    ERROR:  invalid input syntax for type bigint: "12.345"
    
    After: the new SQL against postgres:19beta2-alpine:
    no idle-in-tx session                     longest_idle_in_tx_seconds = null,  idleintransaction = 0
    begin; select 1; then wait 3 s            longest_idle_in_tx_seconds = 3.212, idleintransaction = 1
    begin; select 1/0; then wait 2 s          longest_idle_in_tx_seconds = 2.214, idleintransaction = 0
    
    The same cast with ::float returns 12.345. TestBackendsColumns checks that every backends column, the new one included, stays in the SQL. Lint and go test ./... pass.

Merge Danger

Door: two-way

The change adds a column and panels and renames nothing. Reverting removes them.

Blast Radius: small

Sinks store one more field per backends row, and Prometheus exposes one more series, pgwatch_backends_longest_idle_in_tx_seconds, per database. The v12 postgres dashboards still have the int cast bug in 11 queries.

The new gauge holds the seconds since the oldest idle-in-transaction
client session, aborted ones included, entered that state. It is null
when there is no such session. Add a matching panel to both v13
sessions overview dashboards.
The backends metric stores *_seconds columns rounded to three decimals,
so casting them to int or int8 fails with "invalid input syntax for type
bigint". Cast them to float in the v13 postgres dashboards.
@pashagolub
pashagolub requested a review from 0xgouda October 22, 2026 12:22
@pashagolub pashagolub self-assigned this Oct 22, 2026
@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 39777029889

Warning

No base build found for commit 201f822 on v7.
Coverage changes can't be calculated without a base build.
If a base build is processing, this comment will update automatically when it completes.

Coverage: 89.684%

Details

  • Patch coverage: No coverable lines changed in this PR.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

Requires a base build to compare against. How to fix this →


Coverage Stats

Coverage Status
Relevant Lines: 5661
Covered Lines: 5077
Line Coverage: 89.68%
Coverage Strength: 0.9 hits per line

💛 - Coveralls

@pashagolub pashagolub added enhancement New feature or request dashboards Grafana dashboards related metrics Metrics related issues labels Oct 22, 2026
@pashagolub
pashagolub requested a lite review from Copilot October 22, 2026 12:26

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No blocking issues were identified; the remaining review comments are non-blocking documentation nits.

2 open issues
What changed in this PR

Adds longest_idle_in_tx_seconds to the backends metric and exposes it in the PostgreSQL and Prometheus v13 sessions dashboards. It also corrects affected fractional-duration casts.

Changes:

  • Calculates the oldest client session’s idle-in-transaction duration, including aborted sessions.
  • Adds a contract test covering the complete backends column set.
  • Adds dashboard panels and updates duration casts to float.
File Description
pkg/​metrics/​metrics.yaml Defines and documents the new idle-in-transaction duration gauge.
pkg/​metrics/​metrics_yaml_test.go Verifies the complete backends SQL column contract.
grafana/​prometheus/​v13/​sessions-overview-prometheus.json Adds the Prometheus sessions panel and dashboard placement.
grafana/​postgres/​v13/​sessions-overview.json Adds the PostgreSQL sessions panel and fixes fractional duration casts.
grafana/​postgres/​v13/​recommendations.json Fixes fractional duration casts in recommendation queries.
grafana/​postgres/​v13/​global-health.json Fixes the fractional transaction-duration cast.

Review effort: Lite

"spec": {
"id": 15,
"title": "Longest idle-in-transaction duration",
"description": "Seconds since the oldest idle-in-transaction client session (aborted ones included) entered that state. Such a session holds its snapshot and locks, so vacuum cannot remove dead rows.",
"spec": {
"id": 10,
"title": "Longest idle-in-transaction duration",
"description": "Seconds since the oldest idle-in-transaction client session (aborted ones included) entered that state. Such a session holds its snapshot and locks, so vacuum cannot remove dead rows.",

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dashboards Grafana dashboards related enhancement New feature or request metrics Metrics related issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants