From 39da629b461678485276059bc90f89f9093388ce Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Thu, 19 Dec 2024 12:15:25 -0600 Subject: [PATCH] Track parent partition size when child partitions are untracked --- input/postgres/relation_stats.go | 11 ++++++++++- output/transform/merge_partition_sizes.go | 6 ++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/input/postgres/relation_stats.go b/input/postgres/relation_stats.go index 398210e62..3e24e1f00 100644 --- a/input/postgres/relation_stats.go +++ b/input/postgres/relation_stats.go @@ -20,7 +20,16 @@ locked_relids_with_parents AS ( UNION SELECT relid FROM locked_relids ) SELECT c.oid, - COALESCE(pg_catalog.pg_table_size(c.oid), 0) AS size_bytes, + COALESCE(pg_catalog.pg_table_size(c.oid), 0) + + COALESCE(( + SELECT pg_catalog.sum(pg_catalog.pg_table_size(inhrelid)) + FROM pg_catalog.pg_inherits + JOIN pg_class t ON inhrelid = t.oid + WHERE inhparent = c.oid + -- Only include sizes from child partitions skipped by ignore_schema_regexp. + -- Child partitions tracked by the collector have their sizes added by mergePartitionSizes. + AND ($1 != '' AND (n.nspname || '.' || t.relname) ~* $1) + ), 0) AS size_bytes, CASE c.reltoastrelid WHEN NULL THEN 0 ELSE COALESCE(pg_catalog.pg_total_relation_size(c.reltoastrelid), 0) END AS toast_bytes, COALESCE(pg_stat_get_numscans(c.oid), 0) AS seq_scan, COALESCE(pg_stat_get_tuples_returned(c.oid), 0) AS seq_tup_read, diff --git a/output/transform/merge_partition_sizes.go b/output/transform/merge_partition_sizes.go index 7d3227bb6..ce65b195d 100644 --- a/output/transform/merge_partition_sizes.go +++ b/output/transform/merge_partition_sizes.go @@ -5,6 +5,12 @@ import ( "github.com/pganalyze/collector/state" ) +// Since Postgres reports parent partition tables as being zero-sized, +// this backfills stats for the parent table as a summation of all child tables. +// +// When ignore_schema_regexp is set, GetRelationStats bypasses this for tables not tracked by the collector. +// +// TODO: recursively build up stats when nested partitioning is used func mergePartitionSizes(s snapshot.FullSnapshot, newState state.PersistedState, ts state.TransientState, databaseOidToIdx OidToIdx) snapshot.FullSnapshot { for idx, rel := range s.RelationInformations { if !rel.HasParentRelation || rel.PartitionBoundary == "" {