Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit dc7dbe4

Browse files
committed
Add used_memory column to pg_autopreped_statement view
1 parent b8b4b76 commit dc7dbe4

File tree

5 files changed

+60
-20
lines changed

5 files changed

+60
-20
lines changed

doc/src/sgml/autoprepare.sgml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@
5555
<para>
5656
It is possible to inspect autoprepared queries in the backend using
5757
<literal>pg_autoprepared_statements</literal> view. It shows original text of the
58-
query, types of the extracted parameters (replacing literals) and
59-
query execution counter.
58+
query, types of the extracted parameters (replacing literals),
59+
query execution counter and used memory.
6060
</para>
6161

6262
</chapter>

src/backend/tcop/postgres.c

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,9 @@ typedef struct
216216
{
217217
AutoprepareStatementKey key;
218218
CachedPlanSource* plan;
219-
dlist_node lru; /* double linked list to implement LRU */
220-
int64 exec_count; /* counter of execution of this query */
219+
dlist_node lru; /* double linked list to implement LRU */
220+
int64 exec_count; /* counter of execution of this query */
221+
Size used_memory; /* memory used by prepared statement */
221222
} AutoprepareStatement;
222223

223224
static AutoprepareStatement* autoprepare_stmt;
@@ -255,14 +256,6 @@ static int autoprepare_match_fn(const void *key1, const void *key2, Size keysize
255256
return strcmp(ask1->query_string, ask2->query_string);
256257
}
257258

258-
static Size
259-
get_memory_context_size(MemoryContext ctx)
260-
{
261-
MemoryContextCounters counters = {0};
262-
ctx->methods->stats(ctx, NULL, NULL, &counters);
263-
return counters.totalspace;
264-
}
265-
266259
/*
267260
* This set returning function reads all the autoprepared statements and
268261
* returns a set of (name, statement, prepare_time, param_types, from_sql).
@@ -295,13 +288,15 @@ pg_autoprepared_statement(PG_FUNCTION_ARGS)
295288
* build tupdesc for result tuples. This must match the definition of the
296289
* pg_prepared_statements view in system_views.sql
297290
*/
298-
tupdesc = CreateTemplateTupleDesc(3);
291+
tupdesc = CreateTemplateTupleDesc(4);
299292
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "statement",
300293
TEXTOID, -1, 0);
301294
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "parameter_types",
302295
REGTYPEARRAYOID, -1, 0);
303296
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "exec_count",
304297
INT8OID, -1, 0);
298+
TupleDescInitEntry(tupdesc, (AttrNumber) 4, "used_memory",
299+
INT8OID, -1, 0);
305300

306301
/*
307302
* We put all the tuples into a tuplestore in one scan of the hashtable.
@@ -325,14 +320,15 @@ pg_autoprepared_statement(PG_FUNCTION_ARGS)
325320
{
326321
if (autoprep_stmt->plan != NULL)
327322
{
328-
Datum values[3];
329-
bool nulls[3];
323+
Datum values[4];
324+
bool nulls[4];
330325
MemSet(nulls, 0, sizeof(nulls));
331326

332327
values[0] = CStringGetTextDatum(autoprep_stmt->key.query_string);
333328
values[1] = build_regtype_array(autoprep_stmt->key.param_types,
334329
autoprep_stmt->key.num_params);
335330
values[2] = Int64GetDatum(autoprep_stmt->exec_count);
331+
values[3] = Int64GetDatum(autoprep_stmt->used_memory);
336332

337333
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
338334
}
@@ -1597,9 +1593,10 @@ exec_parse_message(const char *query_string, /* string to execute */
15971593
{
15981594
/* Drop invalidated plan: it will be reconstructed later */
15991595
if (autoprepare_memory_limit)
1600-
autoprepare_used_memory -= get_memory_context_size(autoprepare_stmt->plan->context);
1596+
autoprepare_used_memory -= autoprepare_stmt->used_memory;
16011597
DropCachedPlan(autoprepare_stmt->plan);
16021598
autoprepare_stmt->plan = NULL;
1599+
autoprepare_stmt->used_memory = 0;
16031600
}
16041601
else
16051602
{
@@ -1612,6 +1609,7 @@ exec_parse_message(const char *query_string, /* string to execute */
16121609
/* Initialize autoprepare hash entry */
16131610
autoprepare_cached_plans += 1;
16141611
autoprepare_stmt->plan = NULL;
1612+
autoprepare_stmt->used_memory = 0;
16151613
autoprepare_stmt->exec_count = 1;
16161614

16171615
/* Copy query text and parameter type info to CacheMemoryContext */
@@ -1629,7 +1627,7 @@ exec_parse_message(const char *query_string, /* string to execute */
16291627
if (victim->plan)
16301628
{
16311629
if (autoprepare_memory_limit)
1632-
autoprepare_used_memory -= get_memory_context_size(victim->plan->context);
1630+
autoprepare_used_memory -= victim->used_memory;
16331631
DropCachedPlan(victim->plan);
16341632
}
16351633
hash_search(autoprepare_hash, victim, HASH_REMOVE, NULL);
@@ -1795,7 +1793,11 @@ exec_parse_message(const char *query_string, /* string to execute */
17951793
{
17961794
SaveCachedPlan(psrc);
17971795
if (autoprepare_stmt)
1796+
{
17981797
autoprepare_stmt->plan = psrc;
1798+
autoprepare_stmt->used_memory = CachedPlanMemoryUsage(autoprepare_stmt->plan);
1799+
autoprepare_used_memory += autoprepare_stmt->used_memory;
1800+
}
17991801
else
18001802
/*
18011803
* We just save the CachedPlanSource into unnamed_stmt_psrc.

src/backend/utils/cache/plancache.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2022,3 +2022,39 @@ ResetPlanCache(void)
20222022
cexpr->is_valid = false;
20232023
}
20242024
}
2025+
2026+
/*
2027+
* CachedPlanMemUsage: Return memory used by the CachedPlanSource
2028+
*
2029+
* Returns the malloced memory used by the two MemoryContexts in
2030+
* CachedPlanSource and (if available) the MemoryContext in the generic plan.
2031+
* Does not care for the free memory in those MemoryContexts because it is very
2032+
* unlikely that it is reused for anythink else anymore and can be considered
2033+
* dead memory anyway. Also the size of the CachedPlanSource struct is added.
2034+
*
2035+
* This function is used only for the pg_prepared_statements view to allow
2036+
* client applications to monitor memory used by prepared statements and to
2037+
* selects candidates for eviction in memory contraint environments with
2038+
* automatic preparation of often called queries.
2039+
*/
2040+
Size
2041+
CachedPlanMemoryUsage(CachedPlanSource *plan)
2042+
{
2043+
MemoryContextCounters counters;
2044+
MemoryContext context;
2045+
2046+
counters.totalspace = 0;
2047+
2048+
context = plan->context;
2049+
context->methods->stats(context,NULL,NULL,&counters);
2050+
2051+
context = plan->query_context;
2052+
context->methods->stats(context,NULL,NULL,&counters);
2053+
2054+
if( plan->gplan ) {
2055+
context = plan->gplan->context;
2056+
context->methods->stats(context,NULL,NULL,&counters);
2057+
}
2058+
2059+
return counters.totalspace;
2060+
}

src/include/catalog/pg_proc.dat

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7611,9 +7611,9 @@
76117611
{ oid => '4035', descr => 'get the autoprepared statements for this session',
76127612
proname => 'pg_autoprepared_statement', prorows => '1000', proretset => 't',
76137613
provolatile => 's', proparallel => 'r', prorettype => 'record',
7614-
proargtypes => '', proallargtypes => '{text,_regtype,int8}',
7615-
proargmodes => '{o,o,o}',
7616-
proargnames => '{statement,parameter_types,exec_count}',
7614+
proargtypes => '', proallargtypes => '{text,_regtype,int8,int8}',
7615+
proargmodes => '{o,o,o,o}',
7616+
proargnames => '{statement,parameter_types,exec_count,used_memory}',
76177617
prosrc => 'pg_autoprepared_statement' },
76187618
{ oid => '2511', descr => 'get the open cursors for this session',
76197619
proname => 'pg_cursor', prorows => '1000', proretset => 't',

src/include/utils/plancache.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,4 +222,6 @@ extern void ReleaseCachedPlan(CachedPlan *plan, bool useResOwner);
222222
extern CachedExpression *GetCachedExpression(Node *expr);
223223
extern void FreeCachedExpression(CachedExpression *cexpr);
224224

225+
extern Size CachedPlanMemoryUsage(CachedPlanSource *plansource);
226+
225227
#endif /* PLANCACHE_H */

0 commit comments

Comments
 (0)