Skip to content

Commit 16d394c

Browse files
committed
Free memory after building each statistics object
Until now, all extended statistics on a given relation were built in the same memory context, without resetting. Some of the memory was released explicitly, but not all of it - for example memory allocated while detoasting values is hard to free. This is how it worked since extended statistics were introduced in PostgreSQL 10, but adding support for extended stats on expressions made the issue somewhat worse as it increases the number of statistics to build. Fixed by adding a memory context which gets reset after building each statistics object (all the statistics kinds included in it). Resetting it after building each statistics kind would be even better, but it would require more invasive changes and copying of results, making it harder to backpatch. Backpatch to PostgreSQL 10, where extended statistics were introduced. Author: Justin Pryzby Reported-by: Justin Pryzby Reviewed-by: Tomas Vondra Backpatch-through: 10 Discussion: https://www.postgresql.org/message-id/20210915200928.GP831%40telsasoft.com
1 parent 76001de commit 16d394c

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

src/backend/statistics/extended_stats.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,15 @@ BuildRelationExtStatistics(Relation onerel, double totalrows,
9090
MemoryContext cxt;
9191
MemoryContext oldcxt;
9292

93+
pg_stext = table_open(StatisticExtRelationId, RowExclusiveLock);
94+
stats = fetch_statentries_for_relation(pg_stext, RelationGetRelid(onerel));
95+
96+
/* memory context for building each statistics object */
9397
cxt = AllocSetContextCreate(CurrentMemoryContext,
9498
"BuildRelationExtStatistics",
9599
ALLOCSET_DEFAULT_SIZES);
96100
oldcxt = MemoryContextSwitchTo(cxt);
97101

98-
pg_stext = table_open(StatisticExtRelationId, RowExclusiveLock);
99-
stats = fetch_statentries_for_relation(pg_stext, RelationGetRelid(onerel));
100-
101102
foreach(lc, stats)
102103
{
103104
StatExtEntry *stat = (StatExtEntry *) lfirst(lc);
@@ -148,12 +149,17 @@ BuildRelationExtStatistics(Relation onerel, double totalrows,
148149

149150
/* store the statistics in the catalog */
150151
statext_store(stat->statOid, ndistinct, dependencies, mcv, stats);
151-
}
152152

153-
table_close(pg_stext, RowExclusiveLock);
153+
/* free the data used for building this statistics object */
154+
MemoryContextReset(cxt);
155+
}
154156

155157
MemoryContextSwitchTo(oldcxt);
156158
MemoryContextDelete(cxt);
159+
160+
list_free(stats);
161+
162+
table_close(pg_stext, RowExclusiveLock);
157163
}
158164

159165
/*

0 commit comments

Comments
 (0)