aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Vondra <tomas.vondra@postgresql.org>2021-09-21 01:14:11 +0200
committerTomas Vondra <tomas.vondra@postgresql.org>2021-09-23 18:33:59 +0200
commitb564eb0181e678ee58c1be2e9f3c53eeb68f8c4b (patch)
treea7cbb5f15b5c0996752f3007e8146fa5ae096448
parentf09a81f1c08fa5c2fed12bed88d53a11a72ff993 (diff)
downloadpostgresql-b564eb0181e678ee58c1be2e9f3c53eeb68f8c4b.tar.gz
postgresql-b564eb0181e678ee58c1be2e9f3c53eeb68f8c4b.zip
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
-rw-r--r--src/backend/statistics/extended_stats.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c
index 0c80e55d107..4c19336b293 100644
--- a/src/backend/statistics/extended_stats.c
+++ b/src/backend/statistics/extended_stats.c
@@ -97,14 +97,15 @@ BuildRelationExtStatistics(Relation onerel, double totalrows,
MemoryContext oldcxt;
int64 ext_cnt;
+ pg_stext = table_open(StatisticExtRelationId, RowExclusiveLock);
+ stats = fetch_statentries_for_relation(pg_stext, RelationGetRelid(onerel));
+
+ /* memory context for building each statistics object */
cxt = AllocSetContextCreate(CurrentMemoryContext,
"BuildRelationExtStatistics",
ALLOCSET_DEFAULT_SIZES);
oldcxt = MemoryContextSwitchTo(cxt);
- pg_stext = table_open(StatisticExtRelationId, RowExclusiveLock);
- stats = fetch_statentries_for_relation(pg_stext, RelationGetRelid(onerel));
-
/* report this phase */
if (stats != NIL)
{
@@ -189,12 +190,17 @@ BuildRelationExtStatistics(Relation onerel, double totalrows,
/* for reporting progress */
pgstat_progress_update_param(PROGRESS_ANALYZE_EXT_STATS_COMPUTED,
++ext_cnt);
- }
- table_close(pg_stext, RowExclusiveLock);
+ /* free the data used for building this statistics object */
+ MemoryContextReset(cxt);
+ }
MemoryContextSwitchTo(oldcxt);
MemoryContextDelete(cxt);
+
+ list_free(stats);
+
+ table_close(pg_stext, RowExclusiveLock);
}
/*