Skip to content

Commit ce879ba

Browse files
committed
(PE-40043) Remove faulty index bloat statistics
This commit removes index bloat estimates added in SUP-2115 from `psql_metrics`. Collection of this data can result in some amount of temporary files written to disk every 5 minutes due to the nested group and sort operations involved. The bloat values generated were also of questionable quality producing both "reasonable" numbers like 50% bloat and absolutely unusable numbers like -230% bloat. The table bloat estimate is retained as the query there is less complicated, operates directly on postgres page counts and fill percentages, and does not produce the same negative estimates that the index bloat query is generating. This partially reverts commit 7497949.
1 parent 3d16062 commit ce879ba

File tree

1 file changed

+1
-105
lines changed

1 file changed

+1
-105
lines changed

files/psql_metrics

Lines changed: 1 addition & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -540,9 +540,7 @@ SELECT json_object_agg(
540540
'idx_tup_read', idx_tup_read,
541541
'idx_tup_fetch', idx_tup_fetch,
542542
'idx_blks_read', idx_blks_read,
543-
'idx_blks_hit', idx_blks_hit,
544-
'bloat_size', bloat_size,
545-
'bloat_percent', bloat_pct
543+
'idx_blks_hit', idx_blks_hit
546544
)
547545
)
548546
FROM
@@ -553,108 +551,6 @@ JOIN
553551
pg_catalog.pg_stat_all_indexes AS s ON c.oid = s.indexrelid
554552
JOIN
555553
pg_catalog.pg_statio_all_indexes AS si ON c.oid = si.indexrelid
556-
JOIN
557-
(
558-
SELECT nspname AS schemaname, tblname, idxname, bs*(relpages)::bigint AS real_size,
559-
bs*(relpages-est_pages)::bigint AS extra_size,
560-
100 * (relpages-est_pages)::float / relpages AS extra_pct,
561-
fillfactor,
562-
idxoid,
563-
CASE WHEN relpages > est_pages_ff
564-
THEN bs*(relpages-est_pages_ff)
565-
ELSE 0
566-
END AS bloat_size,
567-
100 * (relpages-est_pages_ff)::float / relpages AS bloat_pct,
568-
is_na
569-
-- , 100-(pst).avg_leaf_density AS pst_avg_bloat, est_pages, index_tuple_hdr_bm, maxalign, pagehdr, nulldatawidth, nulldatahdrwidth, reltuples, relpages -- (DEBUG INFO)
570-
FROM (
571-
SELECT coalesce(1 +
572-
ceil(reltuples/floor((bs-pageopqdata-pagehdr)/(4+nulldatahdrwidth)::float)), 0 -- ItemIdData size + computed avg size of a tuple (nulldatahdrwidth)
573-
) AS est_pages,
574-
coalesce(1 +
575-
ceil(reltuples/floor((bs-pageopqdata-pagehdr)*fillfactor/(100*(4+nulldatahdrwidth)::float))), 0
576-
) AS est_pages_ff,
577-
bs, nspname, tblname, idxname, idxoid, relpages, fillfactor, is_na
578-
-- , pgstatindex(idxoid) AS pst, index_tuple_hdr_bm, maxalign, pagehdr, nulldatawidth, nulldatahdrwidth, reltuples -- (DEBUG INFO)
579-
FROM (
580-
SELECT maxalign, bs, nspname, tblname, idxname, reltuples, relpages, idxoid, fillfactor,
581-
( index_tuple_hdr_bm +
582-
maxalign - CASE -- Add padding to the index tuple header to align on MAXALIGN
583-
WHEN index_tuple_hdr_bm%maxalign = 0 THEN maxalign
584-
ELSE index_tuple_hdr_bm%maxalign
585-
END
586-
+ nulldatawidth + maxalign - CASE -- Add padding to the data to align on MAXALIGN
587-
WHEN nulldatawidth = 0 THEN 0
588-
WHEN nulldatawidth::integer%maxalign = 0 THEN maxalign
589-
ELSE nulldatawidth::integer%maxalign
590-
END
591-
)::numeric AS nulldatahdrwidth, pagehdr, pageopqdata, is_na
592-
-- , index_tuple_hdr_bm, nulldatawidth -- (DEBUG INFO)
593-
FROM (
594-
SELECT n.nspname, i.tblname, i.idxname, i.reltuples, i.relpages,
595-
i.idxoid, i.fillfactor, current_setting('block_size')::numeric AS bs,
596-
CASE -- MAXALIGN: 4 on 32bits, 8 on 64bits (and mingw32 ?)
597-
WHEN version() ~ 'mingw32' OR version() ~ '64-bit|x86_64|ppc64|ia64|amd64' THEN 8
598-
ELSE 4
599-
END AS maxalign,
600-
/* per page header, fixed size: 20 for 7.X, 24 for others */
601-
24 AS pagehdr,
602-
/* per page btree opaque data */
603-
16 AS pageopqdata,
604-
/* per tuple header: add IndexAttributeBitMapData if some cols are null-able */
605-
CASE WHEN max(coalesce(s.null_frac,0)) = 0
606-
THEN 8 -- IndexTupleData size
607-
ELSE 8 + (( 32 + 8 - 1 ) / 8) -- IndexTupleData size + IndexAttributeBitMapData size ( max num filed per index + 8 - 1 /8)
608-
END AS index_tuple_hdr_bm,
609-
/* data len: we remove null values save space using it fractionnal part from stats */
610-
sum( (1-coalesce(s.null_frac, 0)) * coalesce(s.avg_width, 1024)) AS nulldatawidth,
611-
max( CASE WHEN i.atttypid = 'pg_catalog.name'::regtype THEN 1 ELSE 0 END ) > 0 AS is_na
612-
FROM (
613-
SELECT ct.relname AS tblname, ct.relnamespace, ic.idxname, ic.attpos, ic.indkey, ic.indkey[ic.attpos], ic.reltuples, ic.relpages, ic.tbloid, ic.idxoid, ic.fillfactor,
614-
coalesce(a1.attnum, a2.attnum) AS attnum, coalesce(a1.attname, a2.attname) AS attname, coalesce(a1.atttypid, a2.atttypid) AS atttypid,
615-
CASE WHEN a1.attnum IS NULL
616-
THEN ic.idxname
617-
ELSE ct.relname
618-
END AS attrelname
619-
FROM (
620-
SELECT idxname, reltuples, relpages, tbloid, idxoid, fillfactor, indkey,
621-
pg_catalog.generate_series(1,indnatts) AS attpos
622-
FROM (
623-
SELECT ci.relname AS idxname, ci.reltuples, ci.relpages, i.indrelid AS tbloid,
624-
i.indexrelid AS idxoid,
625-
coalesce(substring(
626-
array_to_string(ci.reloptions, ' ')
627-
from 'fillfactor=([0-9]+)')::smallint, 90) AS fillfactor,
628-
i.indnatts,
629-
pg_catalog.string_to_array(pg_catalog.textin(
630-
pg_catalog.int2vectorout(i.indkey)),' ')::int[] AS indkey
631-
FROM pg_catalog.pg_index i
632-
JOIN pg_catalog.pg_class ci ON ci.oid = i.indexrelid
633-
WHERE ci.relam=(SELECT oid FROM pg_am WHERE amname = 'btree')
634-
AND ci.relpages > 0
635-
) AS idx_data
636-
) AS ic
637-
JOIN pg_catalog.pg_class ct ON ct.oid = ic.tbloid
638-
LEFT JOIN pg_catalog.pg_attribute a1 ON
639-
ic.indkey[ic.attpos] <> 0
640-
AND a1.attrelid = ic.tbloid
641-
AND a1.attnum = ic.indkey[ic.attpos]
642-
LEFT JOIN pg_catalog.pg_attribute a2 ON
643-
ic.indkey[ic.attpos] = 0
644-
AND a2.attrelid = ic.idxoid
645-
AND a2.attnum = ic.attpos
646-
) i
647-
JOIN pg_catalog.pg_namespace n ON n.oid = i.relnamespace
648-
JOIN pg_catalog.pg_stats s ON s.schemaname = n.nspname
649-
AND s.tablename = i.attrelname
650-
AND s.attname = i.attname
651-
GROUP BY 1,2,3,4,5,6,7,8,9,10,11
652-
) AS rows_data_stats
653-
) AS rows_hdr_pdg_stats
654-
) AS relation_stats
655-
ORDER BY nspname, tblname, idxname
656-
) a on
657-
a.idxoid = s.indexrelid
658554
WHERE
659555
n.nspname NOT IN ('pg_catalog', 'information_schema')
660556
AND c.relkind = 'i'

0 commit comments

Comments
 (0)