mirror of
https://github.com/percona/pg_stat_monitor.git
synced 2026-02-04 05:56:21 +00:00
[PG-810] PG-17 Support (#463)
* Temporary disable all workflows
* Add build workflow with PG17
* Fix incompatibilities
* Fix 007_settings_pgsm_query_shared_buffer.pl test
* Fix 018_column_names.pl
* Fix 025_compare_pgss.pl
* Remove tuplestore_donestoring usage at all
* Rename I/O timing statistics columns to shared_blk_{read|write}_time
* Fix comments with fileds numbers
* Fix format
* Revert "Temporary disable all workflows"
This reverts commit 12e75beb63.
* Disable all workflows except check and build for PG 15, 16 and 17
* Fix
* Fix comments
* Fix migration
* Use REL_17_BETA1 in CI
* Add timers tests to 028_temp_block.pl
* Add local blocks timing statistics columns local_blk_{write|read}_time
* Fix t/027_local_blocks.pl test for older PG versions
* Fix
* Add jit_deform_{count|time} metrics
* Fix
* Add stats_since and minmax_stats_since fields
* Revert "Disable all workflows except check and build for PG 15, 16 and 17"
This reverts commit 73febf3aee.
* Fix t/028_temp_block.pl for PG14 and below
* Fix build for PG12
* Add pgdg workflow for PG17
* Try to fix PG pgdg workflow
* Fixes and formatting
* Format code
* Add level tracking regression test
* Fix nesting level tracking
* Format code
* Add level tracking test expected result for PG13
* Fix for PG12
* Skip level tracking regression test for PG version less than 14
* Fix toplevel calculation for older PG version
* Fix level tracking test results
* Fix nesting level counting for older PG version
* Revert "Fix nesting level counting for older PG version"
This reverts commit 3e91da8010.
* Fix level tracking for older PG versions once again
* Set REL_17_BETA2 tag for PG
* Add CI badge for PG17
* Use PG17 for examples in readme
This commit is contained in:
@@ -31,16 +31,18 @@
|
||||
typedef enum pgsmVersion
|
||||
{
|
||||
PGSM_V1_0 = 0,
|
||||
PGSM_V2_0
|
||||
PGSM_V2_0,
|
||||
PGSM_V2_1
|
||||
} pgsmVersion;
|
||||
|
||||
PG_MODULE_MAGIC;
|
||||
|
||||
#define BUILD_VERSION "2.0.4"
|
||||
#define BUILD_VERSION "2.1.0"
|
||||
|
||||
/* Number of output arguments (columns) for various API versions */
|
||||
#define PG_STAT_MONITOR_COLS_V1_0 52
|
||||
#define PG_STAT_MONITOR_COLS_V2_0 64
|
||||
#define PG_STAT_MONITOR_COLS_V2_1 70
|
||||
#define PG_STAT_MONITOR_COLS PG_STAT_MONITOR_COLS_V2_0 /* maximum of above */
|
||||
|
||||
#define PGSM_TEXT_FILE PGSTAT_STAT_PERMANENT_DIRECTORY "pg_stat_monitor_query"
|
||||
@@ -71,11 +73,12 @@ do \
|
||||
/*---- Initicalization Function Declarations ----*/
|
||||
void _PG_init(void);
|
||||
|
||||
/* Current nesting depth of ExecutorRun+ProcessUtility calls */
|
||||
static int exec_nested_level = 0;
|
||||
/* Current nesting depth of planner/ExecutorRun/ProcessUtility calls */
|
||||
static int nesting_level = 0;
|
||||
volatile bool __pgsm_do_not_capture_error = false;
|
||||
|
||||
#if PG_VERSION_NUM >= 130000
|
||||
#if PG_VERSION_NUM >= 130000 && PG_VERSION_NUM < 170000
|
||||
/* Before planner nesting level was conunted separately */
|
||||
static int plan_nested_level = 0;
|
||||
#endif
|
||||
|
||||
@@ -145,6 +148,7 @@ PG_FUNCTION_INFO_V1(pg_stat_monitor_version);
|
||||
PG_FUNCTION_INFO_V1(pg_stat_monitor_reset);
|
||||
PG_FUNCTION_INFO_V1(pg_stat_monitor_1_0);
|
||||
PG_FUNCTION_INFO_V1(pg_stat_monitor_2_0);
|
||||
PG_FUNCTION_INFO_V1(pg_stat_monitor_2_1);
|
||||
PG_FUNCTION_INFO_V1(pg_stat_monitor);
|
||||
PG_FUNCTION_INFO_V1(get_histogram_timings);
|
||||
PG_FUNCTION_INFO_V1(pg_stat_monitor_hook_stats);
|
||||
@@ -197,11 +201,6 @@ DECLARE_HOOK(void pgsm_ProcessUtility, PlannedStmt *pstmt, const char *queryStri
|
||||
static uint64 pgsm_hash_string(const char *str, int len);
|
||||
char *unpack_sql_state(int sql_state);
|
||||
|
||||
#define PGSM_HANDLED_UTILITY(n) (!IsA(n, ExecuteStmt) && \
|
||||
!IsA(n, PrepareStmt) && \
|
||||
!IsA(n, DeallocateStmt))
|
||||
|
||||
|
||||
static pgsmEntry * pgsm_create_hash_entry(uint64 bucket_id, uint64 queryid, PlanInfo * plan_info);
|
||||
static void pgsm_add_to_list(pgsmEntry * entry, char *query_text, int query_len);
|
||||
static pgsmEntry * pgsm_get_entry_for_query(uint64 queryid, PlanInfo * plan_info, const char *query_text, int query_len, bool create);
|
||||
@@ -425,17 +424,18 @@ pgsm_post_parse_analyze_internal(ParseState *pstate, Query *query, JumbleState *
|
||||
}
|
||||
}
|
||||
|
||||
if (!pgsm_enabled(exec_nested_level))
|
||||
if (!pgsm_enabled(nesting_level))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Clear queryId for prepared statements related utility, as those will
|
||||
* inherit from the underlying statement's one (except DEALLOCATE which is
|
||||
* entirely untracked).
|
||||
* If it's EXECUTE, clear the queryId so that stats will accumulate for
|
||||
* the underlying PREPARE. But don't do this if we're not tracking
|
||||
* utility statements, to avoid messing up another extension that might be
|
||||
* tracking them.
|
||||
*/
|
||||
if (query->utilityStmt)
|
||||
{
|
||||
if (pgsm_track_utility && !PGSM_HANDLED_UTILITY(query->utilityStmt))
|
||||
if (pgsm_track_utility && IsA(query->utilityStmt, ExecuteStmt))
|
||||
query->queryId = UINT64CONST(0);
|
||||
|
||||
return;
|
||||
@@ -568,7 +568,7 @@ pgsm_ExecutorStart(QueryDesc *queryDesc, int eflags)
|
||||
* counting of optimizable statements that are directly contained in
|
||||
* utility statements.
|
||||
*/
|
||||
if (pgsm_enabled(exec_nested_level) &&
|
||||
if (pgsm_enabled(nesting_level) &&
|
||||
queryDesc->plannedstmt->queryId != UINT64CONST(0))
|
||||
{
|
||||
/*
|
||||
@@ -599,37 +599,37 @@ static void
|
||||
pgsm_ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count,
|
||||
bool execute_once)
|
||||
{
|
||||
if (exec_nested_level >= 0 && exec_nested_level < max_stack_depth)
|
||||
if (nesting_level >= 0 && nesting_level < max_stack_depth)
|
||||
{
|
||||
nested_queryids[exec_nested_level] = queryDesc->plannedstmt->queryId;
|
||||
nested_query_txts[exec_nested_level] = strdup(queryDesc->sourceText);
|
||||
nested_queryids[nesting_level] = queryDesc->plannedstmt->queryId;
|
||||
nested_query_txts[nesting_level] = strdup(queryDesc->sourceText);
|
||||
}
|
||||
|
||||
exec_nested_level++;
|
||||
nesting_level++;
|
||||
PG_TRY();
|
||||
{
|
||||
if (prev_ExecutorRun)
|
||||
prev_ExecutorRun(queryDesc, direction, count, execute_once);
|
||||
else
|
||||
standard_ExecutorRun(queryDesc, direction, count, execute_once);
|
||||
exec_nested_level--;
|
||||
if (exec_nested_level >= 0 && exec_nested_level < max_stack_depth)
|
||||
nesting_level--;
|
||||
if (nesting_level >= 0 && nesting_level < max_stack_depth)
|
||||
{
|
||||
nested_queryids[exec_nested_level] = UINT64CONST(0);
|
||||
if (nested_query_txts[exec_nested_level])
|
||||
free(nested_query_txts[exec_nested_level]);
|
||||
nested_query_txts[exec_nested_level] = NULL;
|
||||
nested_queryids[nesting_level] = UINT64CONST(0);
|
||||
if (nested_query_txts[nesting_level])
|
||||
free(nested_query_txts[nesting_level]);
|
||||
nested_query_txts[nesting_level] = NULL;
|
||||
}
|
||||
}
|
||||
PG_CATCH();
|
||||
{
|
||||
exec_nested_level--;
|
||||
if (exec_nested_level >= 0 && exec_nested_level < max_stack_depth)
|
||||
nesting_level--;
|
||||
if (nesting_level >= 0 && nesting_level < max_stack_depth)
|
||||
{
|
||||
nested_queryids[exec_nested_level] = UINT64CONST(0);
|
||||
if (nested_query_txts[exec_nested_level])
|
||||
free(nested_query_txts[exec_nested_level]);
|
||||
nested_query_txts[exec_nested_level] = NULL;
|
||||
nested_queryids[nesting_level] = UINT64CONST(0);
|
||||
if (nested_query_txts[nesting_level])
|
||||
free(nested_query_txts[nesting_level]);
|
||||
nested_query_txts[nesting_level] = NULL;
|
||||
}
|
||||
PG_RE_THROW();
|
||||
}
|
||||
@@ -642,7 +642,7 @@ pgsm_ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count,
|
||||
static void
|
||||
pgsm_ExecutorFinish(QueryDesc *queryDesc)
|
||||
{
|
||||
exec_nested_level++;
|
||||
nesting_level++;
|
||||
|
||||
PG_TRY();
|
||||
{
|
||||
@@ -650,11 +650,11 @@ pgsm_ExecutorFinish(QueryDesc *queryDesc)
|
||||
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();
|
||||
@@ -722,7 +722,7 @@ pgsm_ExecutorEnd(QueryDesc *queryDesc)
|
||||
MemoryContextSwitchTo(oldctx);
|
||||
}
|
||||
|
||||
if (queryId != UINT64CONST(0) && queryDesc->totaltime && pgsm_enabled(exec_nested_level))
|
||||
if (queryId != UINT64CONST(0) && queryDesc->totaltime && pgsm_enabled(nesting_level))
|
||||
{
|
||||
entry = pgsm_get_entry_for_query(queryId, plan_ptr, (char *) queryDesc->sourceText, strlen(queryDesc->sourceText), true);
|
||||
if (!entry)
|
||||
@@ -868,8 +868,14 @@ pgsm_planner_hook(Query *parse, const char *query_string, int cursorOptions, Par
|
||||
* top level planner call.
|
||||
*/
|
||||
|
||||
if (pgsm_enabled(plan_nested_level + exec_nested_level) &&
|
||||
pgsm_track_planning && query_string && parse->queryId != UINT64CONST(0))
|
||||
bool enabled;
|
||||
#if PG_VERSION_NUM >= 170000
|
||||
enabled = pgsm_enabled(nesting_level);
|
||||
#else
|
||||
enabled = pgsm_enabled(plan_nested_level + nesting_level);
|
||||
#endif
|
||||
|
||||
if (enabled && pgsm_track_planning && query_string && parse->queryId != UINT64CONST(0))
|
||||
{
|
||||
pgsmEntry *entry = NULL;
|
||||
instr_time start;
|
||||
@@ -892,7 +898,11 @@ pgsm_planner_hook(Query *parse, const char *query_string, int cursorOptions, Par
|
||||
if (MemoryContextIsValid(MessageContext))
|
||||
entry = pgsm_get_entry_for_query(parse->queryId, NULL, query_string, strlen(query_string), true);
|
||||
|
||||
#if PG_VERSION_NUM >= 170000
|
||||
nesting_level++;
|
||||
#else
|
||||
plan_nested_level++;
|
||||
#endif
|
||||
PG_TRY();
|
||||
{
|
||||
/*
|
||||
@@ -909,7 +919,11 @@ pgsm_planner_hook(Query *parse, const char *query_string, int cursorOptions, Par
|
||||
}
|
||||
PG_FINALLY();
|
||||
{
|
||||
#if PG_VERSION_NUM >= 170000
|
||||
nesting_level--;
|
||||
#else
|
||||
plan_nested_level--;
|
||||
#endif
|
||||
}
|
||||
PG_END_TRY();
|
||||
|
||||
@@ -945,19 +959,38 @@ pgsm_planner_hook(Query *parse, const char *query_string, int cursorOptions, Par
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Even though we're not tracking plan time for this statement, we
|
||||
* must still increment the nesting level, to ensure that functions
|
||||
* evaluated during planning are not seen as top-level calls.
|
||||
*
|
||||
* If there is a previous installed hook, then assume it's going to
|
||||
* call standard_planner() function, otherwise we call the function
|
||||
* here. This is to avoid calling standard_planner() function twice,
|
||||
* since it modifies the first argument (Query *), the second call
|
||||
* would trigger an assertion failure.
|
||||
*/
|
||||
plan_nested_level++;
|
||||
|
||||
if (planner_hook_next)
|
||||
result = planner_hook_next(parse, query_string, cursorOptions, boundParams);
|
||||
else
|
||||
result = standard_planner(parse, query_string, cursorOptions, boundParams);
|
||||
plan_nested_level--;
|
||||
#if PG_VERSION_NUM >= 170000
|
||||
nesting_level++;
|
||||
#else
|
||||
plan_nested_level++;
|
||||
#endif
|
||||
PG_TRY();
|
||||
{
|
||||
if (planner_hook_next)
|
||||
result = planner_hook_next(parse, query_string, cursorOptions, boundParams);
|
||||
else
|
||||
result = standard_planner(parse, query_string, cursorOptions, boundParams);
|
||||
}
|
||||
PG_FINALLY();
|
||||
{
|
||||
#if PG_VERSION_NUM >= 170000
|
||||
nesting_level--;
|
||||
#else
|
||||
plan_nested_level--;
|
||||
#endif
|
||||
}
|
||||
PG_END_TRY();
|
||||
|
||||
}
|
||||
return result;
|
||||
@@ -995,6 +1028,7 @@ pgsm_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
|
||||
{
|
||||
Node *parsetree = pstmt->utilityStmt;
|
||||
uint64 queryId = 0;
|
||||
bool enabled = pgsm_track_utility && pgsm_enabled(nesting_level);
|
||||
|
||||
#if PG_VERSION_NUM < 140000
|
||||
int len = strlen(queryString);
|
||||
@@ -1012,7 +1046,7 @@ pgsm_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
|
||||
* since we are already measuring the statement's costs at the utility
|
||||
* level.
|
||||
*/
|
||||
if (pgsm_track_utility && pgsm_enabled(exec_nested_level))
|
||||
if (enabled)
|
||||
pstmt->queryId = UINT64CONST(0);
|
||||
#endif
|
||||
|
||||
@@ -1025,13 +1059,16 @@ pgsm_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
|
||||
* hash table entry for the PREPARE (with hash calculated from the query
|
||||
* string), and then a different one with the same query string (but hash
|
||||
* calculated from the query tree) would be used to accumulate costs of
|
||||
* ensuing EXECUTEs. This would be confusing, and inconsistent with other
|
||||
* cases where planning time is not included at all.
|
||||
* ensuing EXECUTEs. This would be confusing. Since PREPARE doesn't
|
||||
* actually run the planner (only parse+rewrite), its costs are generally
|
||||
* pretty negligible and it seems okay to just ignore it.
|
||||
*
|
||||
* Likewise, we don't track execution of DEALLOCATE.
|
||||
*/
|
||||
if (pgsm_track_utility && pgsm_enabled(exec_nested_level) &&
|
||||
PGSM_HANDLED_UTILITY(parsetree))
|
||||
if (enabled &&
|
||||
!IsA(parsetree, ExecuteStmt) &&
|
||||
!IsA(parsetree, PrepareStmt) &&
|
||||
!IsA(parsetree, DeallocateStmt))
|
||||
{
|
||||
pgsmEntry *entry;
|
||||
char *query_text;
|
||||
@@ -1052,7 +1089,7 @@ pgsm_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
|
||||
elog(DEBUG1, "[pg_stat_monitor] pgsm_ProcessUtility: Failed to execute getrusage.");
|
||||
|
||||
INSTR_TIME_SET_CURRENT(start);
|
||||
exec_nested_level++;
|
||||
nesting_level++;
|
||||
|
||||
PG_TRY();
|
||||
{
|
||||
@@ -1092,11 +1129,11 @@ pgsm_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
|
||||
dest,
|
||||
completionTag);
|
||||
#endif
|
||||
exec_nested_level--;
|
||||
nesting_level--;
|
||||
}
|
||||
PG_CATCH();
|
||||
{
|
||||
exec_nested_level--;
|
||||
nesting_level--;
|
||||
PG_RE_THROW();
|
||||
}
|
||||
|
||||
@@ -1182,41 +1219,80 @@ pgsm_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Even though we're not tracking execution time for this statement,
|
||||
* we must still increment the nesting level, to ensure that functions
|
||||
* evaluated within it are not seen as top-level calls. But don't do
|
||||
* so for EXECUTE; that way, when control reaches pgss_planner or
|
||||
* pgss_ExecutorStart, we will treat the costs as top-level if
|
||||
* appropriate. Likewise, don't bump for PREPARE, so that parse
|
||||
* analysis will treat the statement as top-level if appropriate.
|
||||
*
|
||||
* Likewise, we don't track execution of DEALLOCATE.
|
||||
*
|
||||
* To be absolutely certain we don't mess up the nesting level,
|
||||
* evaluate the bump_level condition just once.
|
||||
*/
|
||||
|
||||
#if PG_VERSION_NUM >= 170000
|
||||
bool bump_level =
|
||||
!IsA(parsetree, ExecuteStmt) &&
|
||||
!IsA(parsetree, PrepareStmt) &&
|
||||
!IsA(parsetree, DeallocateStmt);
|
||||
|
||||
if (bump_level)
|
||||
nesting_level++;
|
||||
|
||||
PG_TRY();
|
||||
{
|
||||
#endif
|
||||
#if PG_VERSION_NUM >= 140000
|
||||
if (prev_ProcessUtility)
|
||||
prev_ProcessUtility(pstmt, queryString,
|
||||
readOnlyTree,
|
||||
context, params, queryEnv,
|
||||
dest,
|
||||
qc);
|
||||
else
|
||||
standard_ProcessUtility(pstmt, queryString,
|
||||
if (prev_ProcessUtility)
|
||||
prev_ProcessUtility(pstmt, queryString,
|
||||
readOnlyTree,
|
||||
context, params, queryEnv,
|
||||
dest,
|
||||
qc);
|
||||
else
|
||||
standard_ProcessUtility(pstmt, queryString,
|
||||
readOnlyTree,
|
||||
context, params, queryEnv,
|
||||
dest,
|
||||
qc);
|
||||
#elif PG_VERSION_NUM >= 130000
|
||||
if (prev_ProcessUtility)
|
||||
prev_ProcessUtility(pstmt, queryString,
|
||||
context, params, queryEnv,
|
||||
dest,
|
||||
qc);
|
||||
else
|
||||
standard_ProcessUtility(pstmt, queryString,
|
||||
if (prev_ProcessUtility)
|
||||
prev_ProcessUtility(pstmt, queryString,
|
||||
context, params, queryEnv,
|
||||
dest,
|
||||
qc);
|
||||
else
|
||||
standard_ProcessUtility(pstmt, queryString,
|
||||
context, params, queryEnv,
|
||||
dest,
|
||||
qc);
|
||||
#else
|
||||
if (prev_ProcessUtility)
|
||||
prev_ProcessUtility(pstmt, queryString,
|
||||
context, params, queryEnv,
|
||||
dest,
|
||||
completionTag);
|
||||
else
|
||||
standard_ProcessUtility(pstmt, queryString,
|
||||
if (prev_ProcessUtility)
|
||||
prev_ProcessUtility(pstmt, queryString,
|
||||
context, params, queryEnv,
|
||||
dest,
|
||||
completionTag);
|
||||
else
|
||||
standard_ProcessUtility(pstmt, queryString,
|
||||
context, params, queryEnv,
|
||||
dest,
|
||||
completionTag);
|
||||
#endif
|
||||
#if PG_VERSION_NUM >= 170000
|
||||
if (bump_level)
|
||||
nesting_level--;
|
||||
}
|
||||
PG_CATCH();
|
||||
{
|
||||
if (bump_level)
|
||||
nesting_level--;
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1358,9 +1434,13 @@ pgsm_update_entry(pgsmEntry * entry,
|
||||
int sqlcode_len = error_info ? strlen(error_info->sqlcode) : 0;
|
||||
int plan_text_len = plan_info ? plan_info->plan_len : 0;
|
||||
|
||||
/* Start collecting data for next bucket and reset all counters */
|
||||
/* Start collecting data for next bucket and reset all counters and timestamps */
|
||||
if (reset)
|
||||
{
|
||||
memset(&entry->counters, 0, sizeof(Counters));
|
||||
entry->stats_since = GetCurrentTimestamp();
|
||||
entry->minmax_stats_since = entry->stats_since;
|
||||
}
|
||||
|
||||
/* volatile block */
|
||||
{
|
||||
@@ -1457,14 +1537,14 @@ pgsm_update_entry(pgsmEntry * entry,
|
||||
e->counters.info.num_relations = num_relations;
|
||||
_snprintf2(e->counters.info.relations, relations, num_relations, REL_LEN);
|
||||
|
||||
if (exec_nested_level > 0 && e->counters.info.parentid == 0 && pgsm_track == PGSM_TRACK_ALL)
|
||||
if (nesting_level > 0 && e->counters.info.parentid == 0 && pgsm_track == PGSM_TRACK_ALL)
|
||||
{
|
||||
if (exec_nested_level >= 0 && exec_nested_level < max_stack_depth)
|
||||
if (nesting_level >= 0 && nesting_level < max_stack_depth)
|
||||
{
|
||||
int parent_query_len = nested_query_txts[exec_nested_level - 1] ?
|
||||
strlen(nested_query_txts[exec_nested_level - 1]) : 0;
|
||||
int parent_query_len = nested_query_txts[nesting_level - 1] ?
|
||||
strlen(nested_query_txts[nesting_level - 1]) : 0;
|
||||
|
||||
e->counters.info.parentid = nested_queryids[exec_nested_level - 1];
|
||||
e->counters.info.parentid = nested_queryids[nesting_level - 1];
|
||||
e->counters.info.parent_query = InvalidDsaPointer;
|
||||
/* If we have a parent query, store it in the raw dsa area */
|
||||
if (parent_query_len > 0)
|
||||
@@ -1482,7 +1562,7 @@ pgsm_update_entry(pgsmEntry * entry,
|
||||
if (DsaPointerIsValid(qry))
|
||||
{
|
||||
qry_buff = dsa_get_address(query_dsa_area, qry);
|
||||
memcpy(qry_buff, nested_query_txts[exec_nested_level - 1], parent_query_len);
|
||||
memcpy(qry_buff, nested_query_txts[nesting_level - 1], parent_query_len);
|
||||
qry_buff[parent_query_len] = 0;
|
||||
/* store the dsa pointer for parent query text */
|
||||
e->counters.info.parent_query = qry;
|
||||
@@ -1518,15 +1598,32 @@ pgsm_update_entry(pgsmEntry * entry,
|
||||
e->counters.blocks.local_blks_written += bufusage->local_blks_written;
|
||||
e->counters.blocks.temp_blks_read += bufusage->temp_blks_read;
|
||||
e->counters.blocks.temp_blks_written += bufusage->temp_blks_written;
|
||||
e->counters.blocks.blk_read_time += INSTR_TIME_GET_MILLISEC(bufusage->blk_read_time);
|
||||
e->counters.blocks.blk_write_time += INSTR_TIME_GET_MILLISEC(bufusage->blk_write_time);
|
||||
|
||||
#if PG_VERSION_NUM < 170000
|
||||
e->counters.blocks.shared_blk_read_time += INSTR_TIME_GET_MILLISEC(bufusage->blk_read_time);
|
||||
e->counters.blocks.shared_blk_write_time += INSTR_TIME_GET_MILLISEC(bufusage->blk_write_time);
|
||||
#else
|
||||
e->counters.blocks.shared_blk_read_time += INSTR_TIME_GET_MILLISEC(bufusage->shared_blk_read_time);
|
||||
e->counters.blocks.shared_blk_write_time += INSTR_TIME_GET_MILLISEC(bufusage->shared_blk_write_time);
|
||||
e->counters.blocks.local_blk_read_time += INSTR_TIME_GET_MILLISEC(bufusage->local_blk_read_time);
|
||||
e->counters.blocks.local_blk_write_time += INSTR_TIME_GET_MILLISEC(bufusage->local_blk_write_time);
|
||||
#endif
|
||||
|
||||
#if PG_VERSION_NUM >= 150000
|
||||
e->counters.blocks.temp_blk_read_time += INSTR_TIME_GET_MILLISEC(bufusage->temp_blk_read_time);
|
||||
e->counters.blocks.temp_blk_write_time += INSTR_TIME_GET_MILLISEC(bufusage->temp_blk_write_time);
|
||||
#endif
|
||||
|
||||
memcpy((void *) &e->counters.blocks.instr_blk_read_time, &bufusage->blk_read_time, sizeof(instr_time));
|
||||
memcpy((void *) &e->counters.blocks.instr_blk_write_time, &bufusage->blk_write_time, sizeof(instr_time));
|
||||
#if PG_VERSION_NUM < 170000
|
||||
memcpy((void *) &e->counters.blocks.instr_shared_blk_read_time, &bufusage->blk_read_time, sizeof(instr_time));
|
||||
memcpy((void *) &e->counters.blocks.instr_shared_blk_write_time, &bufusage->blk_write_time, sizeof(instr_time));
|
||||
#else
|
||||
memcpy((void *) &e->counters.blocks.instr_shared_blk_read_time, &bufusage->shared_blk_read_time, sizeof(instr_time));
|
||||
memcpy((void *) &e->counters.blocks.instr_shared_blk_write_time, &bufusage->shared_blk_write_time, sizeof(instr_time));
|
||||
memcpy((void *) &e->counters.blocks.instr_local_blk_write_time, &bufusage->local_blk_write_time, sizeof(instr_time));
|
||||
memcpy((void *) &e->counters.blocks.instr_local_blk_write_time, &bufusage->local_blk_write_time, sizeof(instr_time));
|
||||
#endif
|
||||
|
||||
|
||||
#if PG_VERSION_NUM >= 150000
|
||||
memcpy((void *) &e->counters.blocks.instr_temp_blk_read_time, &bufusage->temp_blk_read_time, sizeof(bufusage->temp_blk_read_time));
|
||||
@@ -1564,6 +1661,12 @@ pgsm_update_entry(pgsmEntry * entry,
|
||||
e->counters.jitinfo.jit_emission_count++;
|
||||
e->counters.jitinfo.jit_emission_time += INSTR_TIME_GET_MILLISEC(jitusage->emission_counter);
|
||||
|
||||
#if PG_VERSION_NUM >= 170000
|
||||
if (INSTR_TIME_GET_MILLISEC(jitusage->deform_counter))
|
||||
e->counters.jitinfo.jit_deform_count++;
|
||||
e->counters.jitinfo.jit_deform_time += INSTR_TIME_GET_MILLISEC(jitusage->deform_counter);
|
||||
#endif
|
||||
|
||||
/* Only do this for local storage scenarios */
|
||||
if (kind != PGSM_STORE)
|
||||
{
|
||||
@@ -1571,6 +1674,10 @@ pgsm_update_entry(pgsmEntry * entry,
|
||||
memcpy((void *) &e->counters.jitinfo.instr_inlining_counter, &jitusage->inlining_counter, sizeof(instr_time));
|
||||
memcpy((void *) &e->counters.jitinfo.instr_optimization_counter, &jitusage->optimization_counter, sizeof(instr_time));
|
||||
memcpy((void *) &e->counters.jitinfo.instr_emission_counter, &jitusage->emission_counter, sizeof(instr_time));
|
||||
|
||||
#if PG_VERSION_NUM >= 170000
|
||||
memcpy((void *) &e->counters.jitinfo.instr_deform_counter, &jitusage->deform_counter, sizeof(instr_time));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1716,7 +1823,11 @@ pgsm_create_hash_entry(uint64 bucket_id, uint64 queryid, PlanInfo * plan_info)
|
||||
#if PG_VERSION_NUM < 140000
|
||||
entry->key.toplevel = 1;
|
||||
#else
|
||||
entry->key.toplevel = ((exec_nested_level + plan_nested_level) == 0);
|
||||
#if PG_VERSION_NUM >= 170000
|
||||
entry->key.toplevel = ((nesting_level) == 0);
|
||||
#else
|
||||
entry->key.toplevel = ((nesting_level + plan_nested_level) == 0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (IsTransactionState())
|
||||
@@ -1802,8 +1913,15 @@ pgsm_store(pgsmEntry * entry)
|
||||
bufusage.temp_blks_read = entry->counters.blocks.temp_blks_read;
|
||||
bufusage.temp_blks_written = entry->counters.blocks.temp_blks_written;
|
||||
|
||||
memcpy(&bufusage.blk_read_time, &entry->counters.blocks.instr_blk_read_time, sizeof(instr_time));
|
||||
memcpy(&bufusage.blk_write_time, &entry->counters.blocks.instr_blk_write_time, sizeof(instr_time));
|
||||
#if PG_VERSION_NUM < 170000
|
||||
memcpy(&bufusage.blk_read_time, &entry->counters.blocks.instr_shared_blk_read_time, sizeof(instr_time));
|
||||
memcpy(&bufusage.blk_write_time, &entry->counters.blocks.instr_shared_blk_write_time, sizeof(instr_time));
|
||||
#else
|
||||
memcpy(&bufusage.shared_blk_read_time, &entry->counters.blocks.instr_shared_blk_read_time, sizeof(instr_time));
|
||||
memcpy(&bufusage.shared_blk_write_time, &entry->counters.blocks.instr_shared_blk_write_time, sizeof(instr_time));
|
||||
memcpy(&bufusage.local_blk_read_time, &entry->counters.blocks.instr_local_blk_read_time, sizeof(instr_time));
|
||||
memcpy(&bufusage.local_blk_write_time, &entry->counters.blocks.instr_local_blk_write_time, sizeof(instr_time));
|
||||
#endif
|
||||
|
||||
#if PG_VERSION_NUM >= 150000
|
||||
memcpy(&bufusage.temp_blk_read_time, &entry->counters.blocks.instr_temp_blk_read_time, sizeof(instr_time));
|
||||
@@ -1822,6 +1940,10 @@ pgsm_store(pgsmEntry * entry)
|
||||
memcpy(&jitusage.optimization_counter, &entry->counters.jitinfo.instr_optimization_counter, sizeof(instr_time));
|
||||
memcpy(&jitusage.emission_counter, &entry->counters.jitinfo.instr_emission_counter, sizeof(instr_time));
|
||||
|
||||
#if PG_VERSION_NUM >= 170000
|
||||
memcpy(&jitusage.deform_counter, &entry->counters.jitinfo.instr_deform_counter, sizeof(instr_time));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Acquire a share lock to start with. We'd have to acquire exclusive if
|
||||
* we need ot create the entry.
|
||||
@@ -1979,6 +2101,13 @@ pg_stat_monitor_2_0(PG_FUNCTION_ARGS)
|
||||
return (Datum) 0;
|
||||
}
|
||||
|
||||
Datum
|
||||
pg_stat_monitor_2_1(PG_FUNCTION_ARGS)
|
||||
{
|
||||
pg_stat_monitor_internal(fcinfo, PGSM_V2_1, true);
|
||||
return (Datum) 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Legacy entry point for pg_stat_monitor() API versions 1.0
|
||||
*/
|
||||
@@ -1999,7 +2128,7 @@ IsBucketValid(uint64 bucketid)
|
||||
|
||||
TimestampDifference(pgsm->bucket_start_time[bucketid], current_tz, &secs, µsecs);
|
||||
|
||||
if (secs > ((int64)pgsm_bucket_time * pgsm_max_buckets))
|
||||
if (secs > ((int64) pgsm_bucket_time * pgsm_max_buckets))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@@ -2018,7 +2147,25 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||
PGSM_HASH_SEQ_STATUS hstat;
|
||||
pgsmEntry *entry;
|
||||
pgsmSharedState *pgsm;
|
||||
int expected_columns = (api_version >= PGSM_V2_0) ? PG_STAT_MONITOR_COLS_V2_0 : PG_STAT_MONITOR_COLS_V1_0;
|
||||
|
||||
int expected_columns;
|
||||
|
||||
switch (api_version)
|
||||
{
|
||||
case PGSM_V1_0:
|
||||
expected_columns = PG_STAT_MONITOR_COLS_V1_0;
|
||||
break;
|
||||
case PGSM_V2_0:
|
||||
expected_columns = PG_STAT_MONITOR_COLS_V2_0;
|
||||
break;
|
||||
case PGSM_V2_1:
|
||||
expected_columns = PG_STAT_MONITOR_COLS_V2_1;
|
||||
break;
|
||||
default:
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("[pg_stat_monitor] pg_stat_monitor_internal: Unknown API version")));
|
||||
}
|
||||
|
||||
/* Disallow old api usage */
|
||||
if (api_version < PGSM_V2_0)
|
||||
@@ -2148,17 +2295,17 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||
/* userid at column number 1 */
|
||||
values[i++] = ObjectIdGetDatum(userid);
|
||||
|
||||
/* userid at column number 1 */
|
||||
/* username at column number 2 */
|
||||
values[i++] = CStringGetTextDatum(entry->username);
|
||||
|
||||
/* dbid at column number 2 */
|
||||
/* dbid at column number 3 */
|
||||
values[i++] = ObjectIdGetDatum(dbid);
|
||||
|
||||
/* userid at column number 1 */
|
||||
/* datname at column number 4 */
|
||||
values[i++] = CStringGetTextDatum(entry->datname);
|
||||
|
||||
/*
|
||||
* ip address at column number 3, Superusers or members of
|
||||
* ip address at column number 5, Superusers or members of
|
||||
* pg_read_all_stats members are allowed
|
||||
*/
|
||||
if (is_allowed_role || userid == GetUserId())
|
||||
@@ -2166,10 +2313,10 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||
else
|
||||
nulls[i++] = true;
|
||||
|
||||
/* queryid at column number 4 */
|
||||
/* queryid at column number 6 */
|
||||
values[i++] = UInt64GetDatum(queryid);
|
||||
|
||||
/* planid at column number 5 */
|
||||
/* planid at column number 7 */
|
||||
if (planid)
|
||||
{
|
||||
values[i++] = UInt64GetDatum(planid);
|
||||
@@ -2184,12 +2331,12 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||
{
|
||||
char *enc;
|
||||
|
||||
/* query at column number 6 */
|
||||
/* query at column number 8 */
|
||||
enc = pg_any_to_server(query_txt, strlen(query_txt), GetDatabaseEncoding());
|
||||
values[i++] = CStringGetTextDatum(enc);
|
||||
if (enc != query_txt)
|
||||
pfree(enc);
|
||||
/* plan at column number 7 */
|
||||
/* plan at column number 9 */
|
||||
if (planid && tmp.planinfo.plan_text[0])
|
||||
values[i++] = CStringGetTextDatum(tmp.planinfo.plan_text);
|
||||
else
|
||||
@@ -2197,25 +2344,26 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||
}
|
||||
else
|
||||
{
|
||||
/* query at column number 6 */
|
||||
/* query at column number 8 */
|
||||
nulls[i++] = true;
|
||||
/* plan at column number 7 */
|
||||
/* plan at column number 9 */
|
||||
nulls[i++] = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* query text at column number 6 */
|
||||
/* query text and plan at column number 8 and 9 */
|
||||
values[i++] = CStringGetTextDatum("<insufficient privilege>");
|
||||
values[i++] = CStringGetTextDatum("<insufficient privilege>");
|
||||
}
|
||||
|
||||
/* pgsm_query_id at column number 10 */
|
||||
if (pgsm_query_id)
|
||||
values[i++] = UInt64GetDatum(pgsm_query_id);
|
||||
else
|
||||
nulls[i++] = true;
|
||||
|
||||
/* parentid at column number 9 */
|
||||
/* parentid at column number 11 */
|
||||
if (tmp.info.parentid != UINT64CONST(0))
|
||||
{
|
||||
values[i++] = UInt64GetDatum(tmp.info.parentid);
|
||||
@@ -2227,13 +2375,13 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||
nulls[i++] = true;
|
||||
}
|
||||
|
||||
/* application_name at column number 10 */
|
||||
/* application_name at column number 15 */
|
||||
if (strlen(tmp.info.application_name) > 0)
|
||||
values[i++] = CStringGetTextDatum(tmp.info.application_name);
|
||||
else
|
||||
nulls[i++] = true;
|
||||
|
||||
/* relations at column number 10 */
|
||||
/* relations at column number 14 */
|
||||
if (tmp.info.num_relations > 0)
|
||||
{
|
||||
int j;
|
||||
@@ -2262,28 +2410,28 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||
else
|
||||
nulls[i++] = true;
|
||||
|
||||
/* cmd_type at column number 11 */
|
||||
/* cmd_type at column number 15 */
|
||||
if (tmp.info.cmd_type == CMD_NOTHING)
|
||||
nulls[i++] = true;
|
||||
else
|
||||
values[i++] = Int64GetDatumFast((int64) tmp.info.cmd_type);
|
||||
|
||||
/* elevel at column number 12 */
|
||||
/* elevel at column number 16 */
|
||||
values[i++] = Int64GetDatumFast(tmp.error.elevel);
|
||||
|
||||
/* sqlcode at column number 13 */
|
||||
/* sqlcode at column number 17 */
|
||||
if (strlen(tmp.error.sqlcode) == 0)
|
||||
nulls[i++] = true;
|
||||
else
|
||||
values[i++] = CStringGetTextDatum(tmp.error.sqlcode);
|
||||
|
||||
/* message at column number 14 */
|
||||
/* message at column number 18 */
|
||||
if (strlen(tmp.error.message) == 0)
|
||||
nulls[i++] = true;
|
||||
else
|
||||
values[i++] = CStringGetTextDatum(tmp.error.message);
|
||||
|
||||
/* bucket_start_time at column number 15 */
|
||||
/* bucket_start_time at column number 19 */
|
||||
values[i++] = TimestampTzGetDatum(pgsm->bucket_start_time[entry->key.bucket_id]);
|
||||
|
||||
if (tmp.calls.calls == 0)
|
||||
@@ -2293,29 +2441,29 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||
tmp.resp_calls[0]++;
|
||||
}
|
||||
|
||||
/* calls at column number 16 */
|
||||
/* calls at column number 20 */
|
||||
values[i++] = Int64GetDatumFast(tmp.calls.calls);
|
||||
|
||||
/* total_time at column number 17 */
|
||||
/* total_time at column number 21 */
|
||||
values[i++] = Float8GetDatumFast(tmp.time.total_time);
|
||||
|
||||
/* min_time at column number 18 */
|
||||
/* min_time at column number 22 */
|
||||
values[i++] = Float8GetDatumFast(tmp.time.min_time);
|
||||
|
||||
/* max_time at column number 19 */
|
||||
/* max_time at column number 23 */
|
||||
values[i++] = Float8GetDatumFast(tmp.time.max_time);
|
||||
|
||||
/* mean_time at column number 20 */
|
||||
/* mean_time at column number 24 */
|
||||
values[i++] = Float8GetDatumFast(tmp.time.mean_time);
|
||||
if (tmp.calls.calls > 1)
|
||||
stddev = sqrt(tmp.time.sum_var_time / tmp.calls.calls);
|
||||
else
|
||||
stddev = 0.0;
|
||||
|
||||
/* calls at column number 21 */
|
||||
/* stddev_exec_time at column number 25 */
|
||||
values[i++] = Float8GetDatumFast(stddev);
|
||||
|
||||
/* calls at column number 22 */
|
||||
/* rows at column number 26 */
|
||||
values[i++] = Int64GetDatumFast(tmp.calls.rows);
|
||||
|
||||
if (tmp.calls.calls == 0)
|
||||
@@ -2325,29 +2473,29 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||
tmp.resp_calls[0]++;
|
||||
}
|
||||
|
||||
/* calls at column number 23 */
|
||||
/* plans at column number 27 */
|
||||
values[i++] = Int64GetDatumFast(tmp.plancalls.calls);
|
||||
|
||||
/* total_time at column number 24 */
|
||||
/* total_plan_time at column number 28 */
|
||||
values[i++] = Float8GetDatumFast(tmp.plantime.total_time);
|
||||
|
||||
/* min_time at column number 25 */
|
||||
/* min_plan_time at column number 29 */
|
||||
values[i++] = Float8GetDatumFast(tmp.plantime.min_time);
|
||||
|
||||
/* max_time at column number 26 */
|
||||
/* max_plan_time at column number 30 */
|
||||
values[i++] = Float8GetDatumFast(tmp.plantime.max_time);
|
||||
|
||||
/* mean_time at column number 27 */
|
||||
/* mean_plan_time at column number 31 */
|
||||
values[i++] = Float8GetDatumFast(tmp.plantime.mean_time);
|
||||
if (tmp.plancalls.calls > 1)
|
||||
stddev = sqrt(tmp.plantime.sum_var_time / tmp.plancalls.calls);
|
||||
else
|
||||
stddev = 0.0;
|
||||
|
||||
/* calls at column number 28 */
|
||||
/* stddev_plan_time at column number 32 */
|
||||
values[i++] = Float8GetDatumFast(stddev);
|
||||
|
||||
/* blocks are from column number 29 - 40 */
|
||||
/* blocks are from column number 33 - 48 */
|
||||
values[i++] = Int64GetDatumFast(tmp.blocks.shared_blks_hit);
|
||||
values[i++] = Int64GetDatumFast(tmp.blocks.shared_blks_read);
|
||||
values[i++] = Int64GetDatumFast(tmp.blocks.shared_blks_dirtied);
|
||||
@@ -2358,27 +2506,29 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||
values[i++] = Int64GetDatumFast(tmp.blocks.local_blks_written);
|
||||
values[i++] = Int64GetDatumFast(tmp.blocks.temp_blks_read);
|
||||
values[i++] = Int64GetDatumFast(tmp.blocks.temp_blks_written);
|
||||
values[i++] = Float8GetDatumFast(tmp.blocks.blk_read_time);
|
||||
values[i++] = Float8GetDatumFast(tmp.blocks.blk_write_time);
|
||||
values[i++] = Float8GetDatumFast(tmp.blocks.shared_blk_read_time);
|
||||
values[i++] = Float8GetDatumFast(tmp.blocks.shared_blk_write_time);
|
||||
values[i++] = Float8GetDatumFast(tmp.blocks.local_blk_read_time);
|
||||
values[i++] = Float8GetDatumFast(tmp.blocks.local_blk_write_time);
|
||||
values[i++] = Float8GetDatumFast(tmp.blocks.temp_blk_read_time);
|
||||
values[i++] = Float8GetDatumFast(tmp.blocks.temp_blk_write_time);
|
||||
|
||||
/* resp_calls at column number 41 */
|
||||
/* resp_calls at column number 49 */
|
||||
values[i++] = IntArrayGetTextDatum(tmp.resp_calls, hist_bucket_count_total);
|
||||
|
||||
/* utime at column number 42 */
|
||||
/* cpu_user_time at column number 50 */
|
||||
values[i++] = Float8GetDatumFast(tmp.sysinfo.utime);
|
||||
|
||||
/* stime at column number 43 */
|
||||
/* cpu_sys_time at column number 51 */
|
||||
values[i++] = Float8GetDatumFast(tmp.sysinfo.stime);
|
||||
{
|
||||
char buf[256];
|
||||
Datum wal_bytes;
|
||||
|
||||
/* wal_records at column number 44 */
|
||||
/* wal_records at column number 52 */
|
||||
values[i++] = Int64GetDatumFast(tmp.walusage.wal_records);
|
||||
|
||||
/* wal_fpi at column number 45 */
|
||||
/* wal_fpi at column number 53 */
|
||||
values[i++] = Int64GetDatumFast(tmp.walusage.wal_fpi);
|
||||
|
||||
snprintf(buf, sizeof buf, UINT64_FORMAT, tmp.walusage.wal_bytes);
|
||||
@@ -2388,15 +2538,16 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||
CStringGetDatum(buf),
|
||||
ObjectIdGetDatum(0),
|
||||
Int32GetDatum(-1));
|
||||
/* wal_bytes at column number 46 */
|
||||
/* wal_bytes at column number 54 */
|
||||
values[i++] = wal_bytes;
|
||||
|
||||
/* application_name at column number 47 */
|
||||
/* application_name at column number 55 */
|
||||
if (strlen(tmp.info.comments) > 0)
|
||||
values[i++] = CStringGetTextDatum(tmp.info.comments);
|
||||
else
|
||||
nulls[i++] = true;
|
||||
|
||||
/* blocks are from column number 56 - 63 */
|
||||
values[i++] = Int64GetDatumFast(tmp.jitinfo.jit_functions);
|
||||
values[i++] = Float8GetDatumFast(tmp.jitinfo.jit_generation_time);
|
||||
values[i++] = Int64GetDatumFast(tmp.jitinfo.jit_inlining_count);
|
||||
@@ -2405,8 +2556,18 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||
values[i++] = Float8GetDatumFast(tmp.jitinfo.jit_optimization_time);
|
||||
values[i++] = Int64GetDatumFast(tmp.jitinfo.jit_emission_count);
|
||||
values[i++] = Float8GetDatumFast(tmp.jitinfo.jit_emission_time);
|
||||
values[i++] = Int64GetDatumFast(tmp.jitinfo.jit_deform_count);
|
||||
values[i++] = Float8GetDatumFast(tmp.jitinfo.jit_deform_time);
|
||||
}
|
||||
|
||||
/* at column number 64 */
|
||||
values[i++] = TimestampTzGetDatum(entry->stats_since);
|
||||
values[i++] = TimestampTzGetDatum(entry->minmax_stats_since);
|
||||
|
||||
/* toplevel at column number 66 */
|
||||
values[i++] = BoolGetDatum(toplevel);
|
||||
|
||||
/* bucket_done at column number 67 */
|
||||
values[i++] = BoolGetDatum(pg_atomic_read_u64(&pgsm->current_wbucket) != bucketid);
|
||||
|
||||
/* clean up and return the tuplestore */
|
||||
@@ -2420,9 +2581,6 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||
/* clean up and return the tuplestore */
|
||||
pgsm_hash_seq_term(&hstat);
|
||||
LWLockRelease(pgsm->lock);
|
||||
|
||||
|
||||
tuplestore_donestoring(tupstore);
|
||||
}
|
||||
|
||||
static uint64
|
||||
|
||||
Reference in New Issue
Block a user