Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix some issues with tracking nesting level #46

Merged
merged 1 commit into from
Sep 14, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 47 additions & 47 deletions pg_stat_kcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,8 @@ typedef struct pgskSharedState

/*---- Local variables ----*/

/* Current nesting depth of ExecutorRun+ProcessUtility calls */
static int exec_nested_level = 0;

#if PG_VERSION_NUM >= 130000
/* Current nesting depth of planner calls */
static int plan_nested_level = 0;
#endif
/* Current nesting depth of planner/ExecutorRun/ProcessUtility calls */
static int nesting_level = 0;


/* saved hook address in case of unload */
Expand Down Expand Up @@ -212,8 +207,6 @@ static bool pgsk_track_planning = false; /* whether to track planning duration *
((pgsk_track == PGSK_TRACK_ALL && (level) < PGSK_MAX_NESTED_LEVEL) || \
(pgsk_track == PGSK_TRACK_TOP && (level) == 0))

#define is_top(level) (level) == 0

/*--- Functions --- */

void _PG_init(void);
Expand Down Expand Up @@ -263,7 +256,7 @@ static pgskEntry *pgsk_entry_alloc(pgskHashKey *key);
static void pgsk_entry_dealloc(void);
static void pgsk_entry_reset(void);
static void pgsk_entry_store(pgsk_queryid queryId, pgskStoreKind kind,
int level, pgskCounters counters);
pgskCounters counters);
static uint32 pgsk_hash_fn(const void *key, Size keysize);
static int pgsk_match_fn(const void *key1, const void *key2, Size keysize);

Expand Down Expand Up @@ -733,7 +726,7 @@ pgsk_queryids_array_size(void)

static void
pgsk_entry_store(pgsk_queryid queryId, pgskStoreKind kind,
int level, pgskCounters counters)
pgskCounters counters)
{
volatile pgskEntry *e;

Expand All @@ -748,7 +741,7 @@ pgsk_entry_store(pgsk_queryid queryId, pgskStoreKind kind,
key.userid = GetUserId();
key.dbid = MyDatabaseId;
key.queryid = queryId;
key.top = is_top(level);
key.top = (nesting_level == 0);

/* Lookup the hash table entry with shared lock. */
LWLockAcquire(pgsk->lock, LW_SHARED);
Expand Down Expand Up @@ -918,28 +911,19 @@ pgsk_planner(Query *parse,
{
PlannedStmt *result;

/*
* We can't process the query if no queryid has been computed.
*
* Note that planner_hook can be called from the planner itself, so we
* have a specific nesting level for the planner. However, utility
* commands containing optimizable statements can also call the planner,
* same for regular DML (for instance for underlying foreign key queries).
* So testing the planner nesting level only is not enough to detect real
* top level planner call.
*/
if (pgsk_enabled(plan_nested_level + exec_nested_level)
/* We can't process the query if no queryid has been computed. */
if (pgsk_enabled(nesting_level)
&& pgsk_track_planning
&& parse->queryId != UINT64CONST(0))
{
struct rusage *rusage_start = &plan_rusage_start[plan_nested_level];
struct rusage *rusage_start = &plan_rusage_start[nesting_level];
struct rusage rusage_end;
pgskCounters counters;

/* capture kernel usage stats in rusage_start */
getrusage(RUSAGE_SELF, rusage_start);

plan_nested_level++;
nesting_level++;
PG_TRY();
{
if (prev_planner_hook)
Expand All @@ -948,11 +932,11 @@ pgsk_planner(Query *parse,
else
result = standard_planner(parse, query_string, cursorOptions,
boundParams);
plan_nested_level--;
nesting_level--;
}
PG_CATCH();
{
plan_nested_level--;
nesting_level--;
PG_RE_THROW();
}
PG_END_TRY();
Expand All @@ -963,22 +947,38 @@ pgsk_planner(Query *parse,
pgsk_compute_counters(&counters, rusage_start, &rusage_end, NULL);

/* store current number of block reads and writes */
pgsk_entry_store(parse->queryId, PGSK_PLAN, plan_nested_level + exec_nested_level, counters);
pgsk_entry_store(parse->queryId, PGSK_PLAN, counters);

if (pgsk_counters_hook)
pgsk_counters_hook(&counters,
query_string,
plan_nested_level + exec_nested_level,
nesting_level,
PGSK_PLAN);
}
else
{
if (prev_planner_hook)
result = prev_planner_hook(parse, query_string, cursorOptions,
boundParams);
else
result = standard_planner(parse, query_string, cursorOptions,
boundParams);
/*
* Even though we're not tracking planning for this statement, we
* must still increment the nesting level, to ensure that functions
* evaluated during planning are not seen as top-level calls.
*/
nesting_level++;
PG_TRY();
{
if (prev_planner_hook)
result = prev_planner_hook(parse, query_string, cursorOptions,
boundParams);
else
result = standard_planner(parse, query_string, cursorOptions,
boundParams);
nesting_level--;
}
PG_CATCH();
{
nesting_level--;
PG_RE_THROW();
}
PG_END_TRY();
}

return result;
Expand All @@ -988,9 +988,9 @@ pgsk_planner(Query *parse,
static void
pgsk_ExecutorStart (QueryDesc *queryDesc, int eflags)
{
if (pgsk_enabled(exec_nested_level))
if (pgsk_enabled(nesting_level))
{
struct rusage *rusage_start = &exec_rusage_start[exec_nested_level];
struct rusage *rusage_start = &exec_rusage_start[nesting_level];

/* capture kernel usage stats in rusage_start */
getrusage(RUSAGE_SELF, rusage_start);
Expand Down Expand Up @@ -1027,7 +1027,7 @@ pgsk_ExecutorRun(QueryDesc *queryDesc,
#endif
)
{
exec_nested_level++;
nesting_level++;
PG_TRY();
{
if (prev_ExecutorRun)
Expand All @@ -1042,11 +1042,11 @@ pgsk_ExecutorRun(QueryDesc *queryDesc,
#else
standard_ExecutorRun(queryDesc, direction, count);
#endif
exec_nested_level--;
nesting_level--;
}
PG_CATCH();
{
exec_nested_level--;
nesting_level--;
PG_RE_THROW();
}
PG_END_TRY();
Expand All @@ -1058,18 +1058,18 @@ pgsk_ExecutorRun(QueryDesc *queryDesc,
static void
pgsk_ExecutorFinish(QueryDesc *queryDesc)
{
exec_nested_level++;
nesting_level++;
PG_TRY();
{
if (prev_ExecutorFinish)
prev_ExecutorFinish(queryDesc);
else
standard_ExecutorFinish(queryDesc);
exec_nested_level--;
nesting_level--;
}
PG_CATCH();
{
exec_nested_level--;
nesting_level--;
PG_RE_THROW();
}
PG_END_TRY();
Expand All @@ -1082,9 +1082,9 @@ pgsk_ExecutorEnd (QueryDesc *queryDesc)
struct rusage rusage_end;
pgskCounters counters;

if (pgsk_enabled(exec_nested_level))
if (pgsk_enabled(nesting_level))
{
struct rusage *rusage_start = &exec_rusage_start[exec_nested_level];
struct rusage *rusage_start = &exec_rusage_start[nesting_level];

/* capture kernel usage stats in rusage_end */
getrusage(RUSAGE_SELF, &rusage_end);
Expand All @@ -1099,12 +1099,12 @@ pgsk_ExecutorEnd (QueryDesc *queryDesc)
pgsk_compute_counters(&counters, rusage_start, &rusage_end, queryDesc);

/* store current number of block reads and writes */
pgsk_entry_store(queryId, PGSK_EXEC, exec_nested_level, counters);
pgsk_entry_store(queryId, PGSK_EXEC, counters);

if (pgsk_counters_hook)
pgsk_counters_hook(&counters,
(const char *)queryDesc->sourceText,
exec_nested_level,
nesting_level,
PGSK_EXEC);
}

Expand Down
Loading