Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 34147af

Browse files
author
Alena Rybakina
committed
Add hierarchical memory context for saving datas not
to use postgres memory contexts except situation when AQO prediction which is passed on to the optimizer. We add three additional memory context for managing memory. AQOMemoryContext is renamed as AQOCacheMemCtx and containe as in the previous time environment data. During predict for plan nodes all of palloc is saved into AQO Predict Memory Context and clean up in the execution stage of query. After executing query we collect some long lived information until it is put into AQO knowledge table. All of them are saved in AQO Learn Memory Context. During these stages we calculates hashes from having got clause, selectivity arrays and relid lists. These tactical information is short-lived, so we save it in the AQO Utility Memory Context. We clean up Utility Memory Context inside calculated function or immediately after her having completed.
1 parent ef76161 commit 34147af

11 files changed

+171
-138
lines changed

aqo.c

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,23 @@ double log_selectivity_lower_bound = -30;
7979
* Currently we use it only to store query_text string which is initialized
8080
* after a query parsing and is used during the query planning.
8181
*/
82-
MemoryContext AQOMemoryContext;
83-
MemoryContext AQO_cache_mem_ctx;
82+
8483
QueryContextData query_context;
84+
85+
MemoryContext AQOTopMemCtx = NULL;
86+
87+
/* Is released at the end of transaction */
88+
MemoryContext AQOCacheMemCtx = NULL;
89+
90+
/* Should be released in-place, just after a huge calculation */
91+
MemoryContext AQOUtilityMemCtx = NULL;
92+
93+
/* Is released at the end of planning */
94+
MemoryContext AQOPredictMemCtx = NULL;
95+
96+
/* Is released at the end of learning */
97+
MemoryContext AQOLearnMemCtx = NULL;
98+
8599
/* Additional plan info */
86100
int njoins;
87101

@@ -116,7 +130,7 @@ aqo_free_callback(ResourceReleasePhase phase,
116130

117131
if (isTopLevel)
118132
{
119-
list_free_deep(cur_classes);
133+
MemoryContextReset(AQOCacheMemCtx);
120134
cur_classes = NIL;
121135
}
122136
}
@@ -302,12 +316,42 @@ _PG_init(void)
302316
create_upper_paths_hook = aqo_store_upper_signature_hook;
303317

304318
init_deactivated_queries_storage();
305-
AQOMemoryContext = AllocSetContextCreate(TopMemoryContext,
306-
"AQOMemoryContext",
319+
320+
/*
321+
* Create own Top memory Context for reporting AQO memory in the future.
322+
*/
323+
AQOTopMemCtx = AllocSetContextCreate(TopMemoryContext,
324+
"AQOTopMemoryContext",
307325
ALLOCSET_DEFAULT_SIZES);
308-
AQO_cache_mem_ctx = AllocSetContextCreate(TopMemoryContext,
309-
"AQO_cache_mem_ctx",
326+
/*
327+
* AQO Cache Memory Context containe environment data.
328+
*/
329+
AQOCacheMemCtx = AllocSetContextCreate(AQOTopMemCtx,
330+
"AQOCacheMemCtx",
310331
ALLOCSET_DEFAULT_SIZES);
332+
/*
333+
* AQOUtilityMemoryContext containe short-lived information which
334+
* is appeared from having got clause, selectivity arrays and relid lists
335+
* while calculating hashes. It clean up inside calculated
336+
* function or immediately after her having completed.
337+
*/
338+
AQOUtilityMemCtx = AllocSetContextCreate(AQOTopMemCtx,
339+
"AQOUtilityMemoryContext",
340+
ALLOCSET_DEFAULT_SIZES);
341+
/*
342+
* AQOPredictMemoryContext save necessary information for making predict of plan nodes
343+
* and clean up in the execution stage of query.
344+
*/
345+
AQOPredictMemCtx = AllocSetContextCreate(AQOTopMemCtx,
346+
"AQOPredictMemoryContext",
347+
ALLOCSET_DEFAULT_SIZES);
348+
/*
349+
* AQOLearnMemoryContext save necessary information for writing down to AQO knowledge table
350+
* and clean up after doing this operation.
351+
*/
352+
AQOLearnMemCtx = AllocSetContextCreate(AQOTopMemCtx,
353+
"AQOLearnMemoryContext",
354+
ALLOCSET_DEFAULT_SIZES);
311355
RegisterResourceReleaseCallback(aqo_free_callback, NULL);
312356
RegisterAQOPlanNodeMethods();
313357

aqo.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,12 @@ extern double log_selectivity_lower_bound;
221221
extern QueryContextData query_context;
222222
extern int njoins;
223223

224-
/* Memory context for long-live data */
225-
extern MemoryContext AQOMemoryContext;
226-
extern MemoryContext AQO_cache_mem_ctx;
224+
/* AQO Memory contexts */
225+
extern MemoryContext AQOTopMemCtx;
226+
extern MemoryContext AQOCacheMemCtx;
227+
extern MemoryContext AQOUtilityMemCtx;
228+
extern MemoryContext AQOPredictMemCtx;
229+
extern MemoryContext AQOLearnMemCtx;
227230

228231
/* Saved hook values in case of unload */
229232
extern post_parse_analyze_hook_type prev_post_parse_analyze_hook;

cardinality_estimation.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ predict_debug_output(List *clauses, List *selectivities,
5252

5353
appendStringInfo(&debug_str, "}, result: %lf", result);
5454
elog(DEBUG1, "Prediction: %s", debug_str.data);
55-
pfree(debug_str.data);
5655
}
5756
#endif
5857

@@ -104,8 +103,6 @@ predict_for_relation(List *clauses, List *selectivities, List *relsigns,
104103
#ifdef AQO_DEBUG_PRINT
105104
predict_debug_output(clauses, selectivities, relsigns, *fss, result);
106105
#endif
107-
pfree(features);
108-
OkNNr_free(data);
109106

110107
if (result < 0)
111108
return -1;

cardinality_hooks.c

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -144,20 +144,21 @@ aqo_set_baserel_rows_estimate(PlannerInfo *root, RelOptInfo *rel)
144144
List *selectivities = NULL;
145145
List *clauses;
146146
int fss = 0;
147+
MemoryContext old_ctx_m;
147148

148149
if (IsQueryDisabled())
149150
/* Fast path. */
150151
goto default_estimator;
151152

153+
old_ctx_m = MemoryContextSwitchTo(AQOPredictMemCtx);
154+
152155
if (query_context.use_aqo || query_context.learn_aqo)
153156
selectivities = get_selectivities(root, rel->baserestrictinfo, 0,
154157
JOIN_INNER, NULL);
155158

156159
if (!query_context.use_aqo)
157160
{
158-
if (query_context.learn_aqo)
159-
list_free_deep(selectivities);
160-
161+
MemoryContextSwitchTo(old_ctx_m);
161162
goto default_estimator;
162163
}
163164

@@ -174,10 +175,8 @@ aqo_set_baserel_rows_estimate(PlannerInfo *root, RelOptInfo *rel)
174175
&fss);
175176
rel->fss_hash = fss;
176177

177-
list_free(rels.hrels);
178-
list_free(rels.signatures);
179-
list_free_deep(selectivities);
180-
list_free(clauses);
178+
/* Return to the caller's memory context. */
179+
MemoryContextSwitchTo(old_ctx_m);
181180

182181
if (predicted >= 0)
183182
{
@@ -224,14 +223,16 @@ aqo_get_parameterized_baserel_size(PlannerInfo *root,
224223
int *eclass_hash;
225224
int current_hash;
226225
int fss = 0;
226+
MemoryContext oldctx;
227227

228228
if (IsQueryDisabled())
229229
/* Fast path */
230230
goto default_estimator;
231231

232+
oldctx = MemoryContextSwitchTo(AQOPredictMemCtx);
233+
232234
if (query_context.use_aqo || query_context.learn_aqo)
233235
{
234-
MemoryContext old_ctx_m;
235236

236237
selectivities = list_concat(
237238
get_selectivities(root, param_clauses, rel->relid,
@@ -247,8 +248,6 @@ aqo_get_parameterized_baserel_size(PlannerInfo *root,
247248
rte = planner_rt_fetch(rel->relid, root);
248249
get_eclasses(allclauses, &nargs, &args_hash, &eclass_hash);
249250

250-
old_ctx_m = MemoryContextSwitchTo(AQO_cache_mem_ctx);
251-
252251
forboth(l, allclauses, l2, selectivities)
253252
{
254253
current_hash = get_clause_hash(
@@ -257,19 +256,11 @@ aqo_get_parameterized_baserel_size(PlannerInfo *root,
257256
cache_selectivity(current_hash, rel->relid, rte->relid,
258257
*((double *) lfirst(l2)));
259258
}
260-
261-
MemoryContextSwitchTo(old_ctx_m);
262-
pfree(args_hash);
263-
pfree(eclass_hash);
264259
}
265260

266261
if (!query_context.use_aqo)
267262
{
268-
if (query_context.learn_aqo)
269-
{
270-
list_free_deep(selectivities);
271-
list_free(allclauses);
272-
}
263+
MemoryContextSwitchTo(oldctx);
273264

274265
goto default_estimator;
275266
}
@@ -282,8 +273,9 @@ aqo_get_parameterized_baserel_size(PlannerInfo *root,
282273
}
283274

284275
predicted = predict_for_relation(allclauses, selectivities, rels.signatures, &fss);
285-
list_free(rels.hrels);
286-
list_free(rels.signatures);
276+
277+
/* Return to the caller's memory context */
278+
MemoryContextSwitchTo(oldctx);
287279

288280
predicted_ppi_rows = predicted;
289281
fss_ppi_hash = fss;
@@ -317,20 +309,20 @@ aqo_set_joinrel_size_estimates(PlannerInfo *root, RelOptInfo *rel,
317309
List *outer_selectivities;
318310
List *current_selectivities = NULL;
319311
int fss = 0;
312+
MemoryContext old_ctx_m;
320313

321314
if (IsQueryDisabled())
322315
/* Fast path */
323316
goto default_estimator;
324317

318+
old_ctx_m = MemoryContextSwitchTo(AQOPredictMemCtx);
319+
325320
if (query_context.use_aqo || query_context.learn_aqo)
326321
current_selectivities = get_selectivities(root, restrictlist, 0,
327322
sjinfo->jointype, sjinfo);
328-
329323
if (!query_context.use_aqo)
330324
{
331-
if (query_context.learn_aqo)
332-
list_free_deep(current_selectivities);
333-
325+
MemoryContextSwitchTo(old_ctx_m);
334326
goto default_estimator;
335327
}
336328

@@ -347,8 +339,9 @@ aqo_set_joinrel_size_estimates(PlannerInfo *root, RelOptInfo *rel,
347339

348340
predicted = predict_for_relation(allclauses, selectivities, rels.signatures,
349341
&fss);
350-
list_free(rels.hrels);
351-
list_free(rels.signatures);
342+
343+
/* Return to the caller's memory context */
344+
MemoryContextSwitchTo(old_ctx_m);
352345

353346
rel->fss_hash = fss;
354347

@@ -389,20 +382,21 @@ aqo_get_parameterized_joinrel_size(PlannerInfo *root,
389382
List *outer_selectivities;
390383
List *current_selectivities = NULL;
391384
int fss = 0;
385+
MemoryContext old_ctx_m;
392386

393387
if (IsQueryDisabled())
394388
/* Fast path */
395389
goto default_estimator;
396390

391+
old_ctx_m = MemoryContextSwitchTo(AQOPredictMemCtx);
392+
397393
if (query_context.use_aqo || query_context.learn_aqo)
398394
current_selectivities = get_selectivities(root, clauses, 0,
399395
sjinfo->jointype, sjinfo);
400396

401397
if (!query_context.use_aqo)
402398
{
403-
if (query_context.learn_aqo)
404-
list_free_deep(current_selectivities);
405-
399+
MemoryContextSwitchTo(old_ctx_m);
406400
goto default_estimator;
407401
}
408402

@@ -417,8 +411,8 @@ aqo_get_parameterized_joinrel_size(PlannerInfo *root,
417411

418412
predicted = predict_for_relation(allclauses, selectivities, rels.signatures,
419413
&fss);
420-
list_free(rels.hrels);
421-
list_free(rels.signatures);
414+
/* Return to the caller's memory context */
415+
MemoryContextSwitchTo(old_ctx_m);
422416

423417
predicted_ppi_rows = predicted;
424418
fss_ppi_hash = fss;
@@ -453,8 +447,6 @@ predict_num_groups(PlannerInfo *root, Path *subpath, List *group_exprs,
453447
clauses = get_path_clauses(subpath, root, &selectivities);
454448
(void) predict_for_relation(clauses, selectivities, rels.signatures,
455449
&child_fss);
456-
list_free(rels.hrels);
457-
list_free(rels.signatures);
458450
}
459451

460452
*fss = get_grouped_exprs_hash(child_fss, group_exprs);
@@ -475,6 +467,7 @@ aqo_estimate_num_groups_hook(PlannerInfo *root, List *groupExprs,
475467
{
476468
int fss;
477469
double predicted;
470+
MemoryContext old_ctx_m;
478471

479472
if (!query_context.use_aqo)
480473
goto default_estimator;
@@ -489,12 +482,15 @@ aqo_estimate_num_groups_hook(PlannerInfo *root, List *groupExprs,
489482
if (groupExprs == NIL)
490483
return 1.0;
491484

485+
old_ctx_m = MemoryContextSwitchTo(AQOPredictMemCtx);
486+
492487
predicted = predict_num_groups(root, subpath, groupExprs, &fss);
493488
if (predicted > 0.)
494489
{
495490
grouped_rel->predicted_cardinality = predicted;
496491
grouped_rel->rows = predicted;
497492
grouped_rel->fss_hash = fss;
493+
MemoryContextSwitchTo(old_ctx_m);
498494
return predicted;
499495
}
500496
else
@@ -504,6 +500,8 @@ aqo_estimate_num_groups_hook(PlannerInfo *root, List *groupExprs,
504500
*/
505501
grouped_rel->predicted_cardinality = -1;
506502

503+
MemoryContextSwitchTo(old_ctx_m);
504+
507505
default_estimator:
508506
return default_estimate_num_groups(root, groupExprs, subpath, grouped_rel,
509507
pgset);

0 commit comments

Comments
 (0)