Use separate memory context to store intermediate stats
parent
1d4b0036e7
commit
fe558bdcae
17
hash_query.c
17
hash_query.c
|
@ -21,6 +21,7 @@
|
||||||
static pgsmLocalState pgsmStateLocal;
|
static pgsmLocalState pgsmStateLocal;
|
||||||
static PGSM_HASH_TABLE_HANDLE pgsm_create_bucket_hash(pgsmSharedState *pgsm, dsa_area *dsa);
|
static PGSM_HASH_TABLE_HANDLE pgsm_create_bucket_hash(pgsmSharedState *pgsm, dsa_area *dsa);
|
||||||
static Size pgsm_get_shared_area_size(void);
|
static Size pgsm_get_shared_area_size(void);
|
||||||
|
static void InitializeSharedState(pgsmSharedState *pgsm);
|
||||||
|
|
||||||
#if USE_DYNAMIC_HASH
|
#if USE_DYNAMIC_HASH
|
||||||
/* parameter for the shared hash */
|
/* parameter for the shared hash */
|
||||||
|
@ -108,7 +109,7 @@ pgsm_startup(void)
|
||||||
pgsm->pgsm_oom = false;
|
pgsm->pgsm_oom = false;
|
||||||
pgsm->lock = &(GetNamedLWLockTranche("pg_stat_monitor"))->lock;
|
pgsm->lock = &(GetNamedLWLockTranche("pg_stat_monitor"))->lock;
|
||||||
SpinLockInit(&pgsm->mutex);
|
SpinLockInit(&pgsm->mutex);
|
||||||
ResetSharedState(pgsm);
|
InitializeSharedState(pgsm);
|
||||||
/* the allocation of pgsmSharedState itself */
|
/* the allocation of pgsmSharedState itself */
|
||||||
p += MAXALIGN(sizeof(pgsmSharedState));
|
p += MAXALIGN(sizeof(pgsmSharedState));
|
||||||
pgsm->raw_dsa_area = p;
|
pgsm->raw_dsa_area = p;
|
||||||
|
@ -147,6 +148,18 @@ pgsm_startup(void)
|
||||||
on_shmem_exit(pgsm_shmem_shutdown, (Datum) 0);
|
on_shmem_exit(pgsm_shmem_shutdown, (Datum) 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
InitializeSharedState(pgsmSharedState *pgsm)
|
||||||
|
{
|
||||||
|
pg_atomic_init_u64(&pgsm->current_wbucket, 0);
|
||||||
|
pg_atomic_init_u64(&pgsm->prev_bucket_sec, 0);
|
||||||
|
memset(&pgsm->bucket_entry, 0, MAX_BUCKETS * sizeof(uint64));
|
||||||
|
pgsm->pgsm_mem_cxt = AllocSetContextCreate(TopMemoryContext,
|
||||||
|
"pg_stat_monitor local store",
|
||||||
|
ALLOCSET_DEFAULT_SIZES);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create the classic or dshahs hash table for storing the query statistics.
|
* Create the classic or dshahs hash table for storing the query statistics.
|
||||||
*/
|
*/
|
||||||
|
@ -415,4 +428,4 @@ pgsm_hash_delete_current(PGSM_HASH_SEQ_STATUS *hstat, PGSM_HASH_TABLE *shared_ha
|
||||||
#else
|
#else
|
||||||
hash_search(shared_hash, key, HASH_REMOVE, NULL);
|
hash_search(shared_hash, key, HASH_REMOVE, NULL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
#include "access/parallel.h"
|
#include "access/parallel.h"
|
||||||
#include "nodes/pg_list.h"
|
#include "nodes/pg_list.h"
|
||||||
#include "utils/guc.h"
|
#include "utils/guc.h"
|
||||||
#include "utils/memutils.h"
|
|
||||||
#include "utils/palloc.h"
|
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
#include "pgstat.h"
|
#include "pgstat.h"
|
||||||
#include "commands/dbcommands.h"
|
#include "commands/dbcommands.h"
|
||||||
|
@ -68,10 +66,6 @@ do \
|
||||||
/*---- Initicalization Function Declarations ----*/
|
/*---- Initicalization Function Declarations ----*/
|
||||||
void _PG_init(void);
|
void _PG_init(void);
|
||||||
|
|
||||||
/*---- Local variables ----*/
|
|
||||||
MemoryContextCallback callback;
|
|
||||||
volatile bool callback_setup = false;
|
|
||||||
|
|
||||||
/* Current nesting depth of ExecutorRun+ProcessUtility calls */
|
/* Current nesting depth of ExecutorRun+ProcessUtility calls */
|
||||||
static int exec_nested_level = 0;
|
static int exec_nested_level = 0;
|
||||||
volatile bool __pgsm_do_not_capture_error = false;
|
volatile bool __pgsm_do_not_capture_error = false;
|
||||||
|
@ -190,12 +184,20 @@ char *unpack_sql_state(int sql_state);
|
||||||
!IsA(n, DeallocateStmt))
|
!IsA(n, DeallocateStmt))
|
||||||
|
|
||||||
|
|
||||||
static pgsmEntry *pgsm_create_hash_entry(MemoryContext context, uint64 bucket_id, uint64 queryid, PlanInfo *plan_info);
|
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, bool should_dup);
|
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);
|
static pgsmEntry* pgsm_get_entry_for_query(uint64 queryid, PlanInfo *plan_info, const char* query_text, int query_len, bool create);
|
||||||
static void pgsm_cleanup_callback(void *arg);
|
static void pgsm_cleanup_callback(void *arg);
|
||||||
static void pgsm_store_error(const char *query, ErrorData *edata);
|
static void pgsm_store_error(const char *query, ErrorData *edata);
|
||||||
|
|
||||||
|
/*---- Local variables ----*/
|
||||||
|
MemoryContextCallback mem_cxt_reset_callback =
|
||||||
|
{
|
||||||
|
.func = pgsm_cleanup_callback,
|
||||||
|
.arg = NULL
|
||||||
|
};
|
||||||
|
volatile bool callback_setup = false;
|
||||||
|
|
||||||
static void pgsm_update_entry(pgsmEntry *entry,
|
static void pgsm_update_entry(pgsmEntry *entry,
|
||||||
const char *query,
|
const char *query,
|
||||||
PlanInfo * plan_info,
|
PlanInfo * plan_info,
|
||||||
|
@ -430,18 +432,14 @@ pgsm_post_parse_analyze_internal(ParseState *pstate, Query *query, JumbleState *
|
||||||
|
|
||||||
if (callback_setup == false)
|
if (callback_setup == false)
|
||||||
{
|
{
|
||||||
|
/* If MessageContext is valid setup a callback to cleanup
|
||||||
|
* our local stats list when the MessagContext gets reset
|
||||||
|
*/
|
||||||
if (MemoryContextIsValid(MessageContext))
|
if (MemoryContextIsValid(MessageContext))
|
||||||
{
|
{
|
||||||
callback.func = pgsm_cleanup_callback;
|
MemoryContextRegisterResetCallback(MessageContext, &mem_cxt_reset_callback);
|
||||||
callback.arg = (void *) strdup("MessageContext");
|
|
||||||
|
|
||||||
MemoryContextRegisterResetCallback(MessageContext, &callback);
|
|
||||||
callback_setup = true;
|
callback_setup = true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
MemoryContextStats(TopMemoryContext);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pgsm_enabled(exec_nested_level))
|
if (!pgsm_enabled(exec_nested_level))
|
||||||
|
@ -507,7 +505,7 @@ pgsm_post_parse_analyze_internal(ParseState *pstate, Query *query, JumbleState *
|
||||||
* The correct bucket value will be needed then to search the hash table, or create
|
* The correct bucket value will be needed then to search the hash table, or create
|
||||||
* the appropriate entry.
|
* the appropriate entry.
|
||||||
*/
|
*/
|
||||||
entry = pgsm_create_hash_entry(MessageContext, 0, query->queryId, NULL);
|
entry = pgsm_create_hash_entry(0, query->queryId, NULL);
|
||||||
|
|
||||||
/* Update other member that are not counters, so that we don't have to worry about these. */
|
/* Update other member that are not counters, so that we don't have to worry about these. */
|
||||||
entry->pgsm_query_id = pgsm_hash_string(norm_query ? norm_query : query_text, norm_query_len);
|
entry->pgsm_query_id = pgsm_hash_string(norm_query ? norm_query : query_text, norm_query_len);
|
||||||
|
@ -524,10 +522,10 @@ pgsm_post_parse_analyze_internal(ParseState *pstate, Query *query, JumbleState *
|
||||||
* it is put in the relevant memory context.
|
* it is put in the relevant memory context.
|
||||||
*/
|
*/
|
||||||
if (PGSM_NORMALIZED_QUERY && norm_query)
|
if (PGSM_NORMALIZED_QUERY && norm_query)
|
||||||
pgsm_add_to_list(entry, norm_query, norm_query_len, true);
|
pgsm_add_to_list(entry, norm_query, norm_query_len);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pgsm_add_to_list(entry, (char *)query_text, query_len, true);
|
pgsm_add_to_list(entry, (char *)query_text, query_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that we've not exceeded max_stack_depth */
|
/* Check that we've not exceeded max_stack_depth */
|
||||||
|
@ -722,7 +720,7 @@ pgsm_ExecutorEnd(QueryDesc *queryDesc)
|
||||||
entry = pgsm_get_entry_for_query(queryId, plan_ptr, (char *)queryDesc->sourceText, strlen(queryDesc->sourceText), true);
|
entry = pgsm_get_entry_for_query(queryId, plan_ptr, (char *)queryDesc->sourceText, strlen(queryDesc->sourceText), true);
|
||||||
if(!entry)
|
if(!entry)
|
||||||
{
|
{
|
||||||
elog(NOTICE,"[pg_stat_monitor] pgsm_ExecutorEnd: Failed to find entry for [%lu] %s.",queryId, queryDesc->sourceText);
|
elog(DEBUG2,"[pg_stat_monitor] pgsm_ExecutorEnd: Failed to find entry for [%lu] %s.",queryId, queryDesc->sourceText);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1122,7 +1120,7 @@ pgsm_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
|
||||||
BufferUsageAccumDiff(&bufusage, &pgBufferUsage, &bufusage_start);
|
BufferUsageAccumDiff(&bufusage, &pgBufferUsage, &bufusage_start);
|
||||||
|
|
||||||
/* Create an entry for this query */
|
/* Create an entry for this query */
|
||||||
entry = pgsm_create_hash_entry(MessageContext, 0, queryId, NULL);
|
entry = pgsm_create_hash_entry(0, queryId, NULL);
|
||||||
|
|
||||||
location = pstmt->stmt_location;
|
location = pstmt->stmt_location;
|
||||||
query_len = pstmt->stmt_len;
|
query_len = pstmt->stmt_len;
|
||||||
|
@ -1131,7 +1129,7 @@ pgsm_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
|
||||||
entry->pgsm_query_id = pgsm_hash_string(query_text, query_len);
|
entry->pgsm_query_id = pgsm_hash_string(query_text, query_len);
|
||||||
entry->counters.info.cmd_type = 0;
|
entry->counters.info.cmd_type = 0;
|
||||||
|
|
||||||
pgsm_add_to_list(entry, query_text, query_len, true);
|
pgsm_add_to_list(entry, query_text, query_len);
|
||||||
|
|
||||||
/* Check that we've not exceeded max_stack_depth */
|
/* Check that we've not exceeded max_stack_depth */
|
||||||
Assert(list_length(lentries) <= max_stack_depth);
|
Assert(list_length(lentries) <= max_stack_depth);
|
||||||
|
@ -1564,7 +1562,7 @@ pgsm_store_error(const char *query, ErrorData *edata)
|
||||||
|
|
||||||
queryid = pgsm_hash_string(query, len);
|
queryid = pgsm_hash_string(query, len);
|
||||||
|
|
||||||
entry = pgsm_create_hash_entry(ErrorContext, 0, queryid, NULL);
|
entry = pgsm_create_hash_entry(0, queryid, NULL);
|
||||||
entry->query_text.query_pointer = pnstrdup(query, len);
|
entry->query_text.query_pointer = pnstrdup(query, len);
|
||||||
|
|
||||||
entry->counters.error.elevel = edata->elevel;
|
entry->counters.error.elevel = edata->elevel;
|
||||||
|
@ -1575,20 +1573,12 @@ pgsm_store_error(const char *query, ErrorData *edata)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pgsm_add_to_list(pgsmEntry *entry, char *query_text, int query_len, bool should_dup)
|
pgsm_add_to_list(pgsmEntry *entry, char *query_text, int query_len)
|
||||||
{
|
{
|
||||||
MemoryContext oldctx;
|
/* Switch to pgsm memory context */
|
||||||
|
MemoryContext oldctx = MemoryContextSwitchTo(pgsm_get_ss()->pgsm_mem_cxt);
|
||||||
/* Switch to TopMemoryContext */
|
entry->query_text.query_pointer = pnstrdup(query_text, query_len);
|
||||||
oldctx = MemoryContextSwitchTo(MessageContext);
|
|
||||||
|
|
||||||
if (should_dup)
|
|
||||||
entry->query_text.query_pointer = pnstrdup(query_text, query_len);
|
|
||||||
else
|
|
||||||
entry->query_text.query_pointer = query_text;
|
|
||||||
|
|
||||||
lentries = lappend(lentries, entry);
|
lentries = lappend(lentries, entry);
|
||||||
|
|
||||||
MemoryContextSwitchTo(oldctx);
|
MemoryContextSwitchTo(oldctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1623,11 +1613,11 @@ pgsm_get_entry_for_query(uint64 queryid, PlanInfo *plan_info, const char* query_
|
||||||
* The correct bucket value will be needed then to search the hash table, or create
|
* The correct bucket value will be needed then to search the hash table, or create
|
||||||
* the appropriate entry.
|
* the appropriate entry.
|
||||||
*/
|
*/
|
||||||
entry = pgsm_create_hash_entry(MessageContext, 0, queryid, plan_info);
|
entry = pgsm_create_hash_entry(0, queryid, plan_info);
|
||||||
|
|
||||||
/* Update other member that are not counters, so that we don't have to worry about these. */
|
/* Update other member that are not counters, so that we don't have to worry about these. */
|
||||||
entry->pgsm_query_id = pgsm_hash_string(query_text, query_len);
|
entry->pgsm_query_id = pgsm_hash_string(query_text, query_len);
|
||||||
pgsm_add_to_list(entry, (char *)query_text, query_len, true);
|
pgsm_add_to_list(entry, (char *)query_text, query_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
|
@ -1636,6 +1626,8 @@ pgsm_get_entry_for_query(uint64 queryid, PlanInfo *plan_info, const char* query_
|
||||||
static void
|
static void
|
||||||
pgsm_cleanup_callback(void *arg)
|
pgsm_cleanup_callback(void *arg)
|
||||||
{
|
{
|
||||||
|
/* Reset the memory context holding the list */
|
||||||
|
MemoryContextReset(pgsm_get_ss()->pgsm_mem_cxt);
|
||||||
lentries = NIL;
|
lentries = NIL;
|
||||||
callback_setup = false;
|
callback_setup = false;
|
||||||
}
|
}
|
||||||
|
@ -1644,7 +1636,7 @@ pgsm_cleanup_callback(void *arg)
|
||||||
* The bucket_id may not be known at this stage. So pass any value that you may wish.
|
* The bucket_id may not be known at this stage. So pass any value that you may wish.
|
||||||
*/
|
*/
|
||||||
static pgsmEntry *
|
static pgsmEntry *
|
||||||
pgsm_create_hash_entry(MemoryContext context, uint64 bucket_id, uint64 queryid, PlanInfo *plan_info)
|
pgsm_create_hash_entry(uint64 bucket_id, uint64 queryid, PlanInfo *plan_info)
|
||||||
{
|
{
|
||||||
pgsmEntry *entry;
|
pgsmEntry *entry;
|
||||||
int sec_ctx;
|
int sec_ctx;
|
||||||
|
@ -1656,10 +1648,9 @@ pgsm_create_hash_entry(MemoryContext context, uint64 bucket_id, uint64 queryid,
|
||||||
char *datname = NULL;
|
char *datname = NULL;
|
||||||
char *username = NULL;
|
char *username = NULL;
|
||||||
|
|
||||||
/* Create an entry in the TopMemoryContext */
|
/* Create an entry in the pgsm memory context */
|
||||||
oldctx = MemoryContextSwitchTo(context);
|
oldctx = MemoryContextSwitchTo(pgsm_get_ss()->pgsm_mem_cxt);
|
||||||
entry = palloc0(sizeof(pgsmEntry));
|
entry = palloc0(sizeof(pgsmEntry));
|
||||||
MemoryContextSwitchTo(oldctx);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the user ID. Let's use this instead of GetUserID as this
|
* Get the user ID. Let's use this instead of GetUserID as this
|
||||||
|
@ -1706,6 +1697,8 @@ pgsm_create_hash_entry(MemoryContext context, uint64 bucket_id, uint64 queryid,
|
||||||
pfree(datname);
|
pfree(datname);
|
||||||
pfree(username);
|
pfree(username);
|
||||||
|
|
||||||
|
MemoryContextSwitchTo(oldctx);
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1965,8 +1958,6 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||||
PGSM_HASH_SEQ_STATUS hstat;
|
PGSM_HASH_SEQ_STATUS hstat;
|
||||||
pgsmEntry *entry;
|
pgsmEntry *entry;
|
||||||
pgsmSharedState *pgsm;
|
pgsmSharedState *pgsm;
|
||||||
char *query_txt = NULL;
|
|
||||||
char *parent_query_txt = NULL;
|
|
||||||
int expected_columns = (api_version >= PGSM_V2_0)?PG_STAT_MONITOR_COLS_V2_0:PG_STAT_MONITOR_COLS_V1_0;
|
int expected_columns = (api_version >= PGSM_V2_0)?PG_STAT_MONITOR_COLS_V2_0:PG_STAT_MONITOR_COLS_V1_0;
|
||||||
|
|
||||||
/* Disallow old api usage */
|
/* Disallow old api usage */
|
||||||
|
@ -2038,6 +2029,9 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||||
uint64 pgsm_query_id = entry->pgsm_query_id;
|
uint64 pgsm_query_id = entry->pgsm_query_id;
|
||||||
dsa_area *query_dsa_area;
|
dsa_area *query_dsa_area;
|
||||||
char *query_ptr;
|
char *query_ptr;
|
||||||
|
char *query_txt = NULL;
|
||||||
|
char *parent_query_txt = NULL;
|
||||||
|
|
||||||
bool toplevel = entry->key.toplevel;
|
bool toplevel = entry->key.toplevel;
|
||||||
#if PG_VERSION_NUM < 140000
|
#if PG_VERSION_NUM < 140000
|
||||||
bool is_allowed_role = is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_STATS);
|
bool is_allowed_role = is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_STATS);
|
||||||
|
@ -2353,15 +2347,16 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||||
|
|
||||||
/* clean up and return the tuplestore */
|
/* clean up and return the tuplestore */
|
||||||
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
|
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
|
||||||
|
|
||||||
|
if(query_txt)
|
||||||
|
pfree(query_txt);
|
||||||
|
if(parent_query_txt)
|
||||||
|
pfree(parent_query_txt);
|
||||||
}
|
}
|
||||||
/* clean up and return the tuplestore */
|
/* clean up and return the tuplestore */
|
||||||
pgsm_hash_seq_term(&hstat);
|
pgsm_hash_seq_term(&hstat);
|
||||||
LWLockRelease(pgsm->lock);
|
LWLockRelease(pgsm->lock);
|
||||||
|
|
||||||
if(query_txt)
|
|
||||||
pfree(query_txt);
|
|
||||||
if(parent_query_txt)
|
|
||||||
pfree(parent_query_txt);
|
|
||||||
|
|
||||||
tuplestore_donestoring(tupstore);
|
tuplestore_donestoring(tupstore);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,9 @@
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/guc.h"
|
#include "utils/guc.h"
|
||||||
#include "utils/guc_tables.h"
|
#include "utils/guc_tables.h"
|
||||||
|
#include "utils/memutils.h"
|
||||||
|
#include "utils/palloc.h"
|
||||||
|
|
||||||
|
|
||||||
#define MAX_BACKEND_PROCESES (MaxBackends + NUM_AUXILIARY_PROCS + max_prepared_xacts)
|
#define MAX_BACKEND_PROCESES (MaxBackends + NUM_AUXILIARY_PROCS + max_prepared_xacts)
|
||||||
#define IntArrayGetTextDatum(x,y) intarray_get_datum(x,y)
|
#define IntArrayGetTextDatum(x,y) intarray_get_datum(x,y)
|
||||||
|
@ -64,7 +67,6 @@
|
||||||
/* XXX: Should USAGE_EXEC reflect execution time and/or buffer usage? */
|
/* XXX: Should USAGE_EXEC reflect execution time and/or buffer usage? */
|
||||||
#define USAGE_EXEC(duration) (1.0)
|
#define USAGE_EXEC(duration) (1.0)
|
||||||
#define USAGE_INIT (1.0) /* including initial planning */
|
#define USAGE_INIT (1.0) /* including initial planning */
|
||||||
#define ASSUMED_MEDIAN_INIT (10.0) /* initial assumed median usage */
|
|
||||||
#define ASSUMED_LENGTH_INIT 1024 /* initial assumed mean query length */
|
#define ASSUMED_LENGTH_INIT 1024 /* initial assumed mean query length */
|
||||||
#define USAGE_DECREASE_FACTOR (0.99) /* decreased every entry_dealloc */
|
#define USAGE_DECREASE_FACTOR (0.99) /* decreased every entry_dealloc */
|
||||||
#define STICKY_DECREASE_FACTOR (0.50) /* factor for sticky entries */
|
#define STICKY_DECREASE_FACTOR (0.50) /* factor for sticky entries */
|
||||||
|
@ -402,7 +404,6 @@ typedef struct pgsmEntry
|
||||||
typedef struct pgsmSharedState
|
typedef struct pgsmSharedState
|
||||||
{
|
{
|
||||||
LWLock *lock; /* protects hashtable search/modification */
|
LWLock *lock; /* protects hashtable search/modification */
|
||||||
double cur_median_usage; /* current median usage in hashtable */
|
|
||||||
slock_t mutex; /* protects following fields only: */
|
slock_t mutex; /* protects following fields only: */
|
||||||
pg_atomic_uint64 current_wbucket;
|
pg_atomic_uint64 current_wbucket;
|
||||||
pg_atomic_uint64 prev_bucket_sec;
|
pg_atomic_uint64 prev_bucket_sec;
|
||||||
|
@ -417,6 +418,10 @@ typedef struct pgsmSharedState
|
||||||
* classic shared memory hash or dshash
|
* classic shared memory hash or dshash
|
||||||
* (if we are using USE_DYNAMIC_HASH)
|
* (if we are using USE_DYNAMIC_HASH)
|
||||||
*/
|
*/
|
||||||
|
MemoryContext pgsm_mem_cxt;
|
||||||
|
/* context to store stats in local
|
||||||
|
* memory until they are pushed to shared hash
|
||||||
|
*/
|
||||||
bool pgsm_oom;
|
bool pgsm_oom;
|
||||||
} pgsmSharedState;
|
} pgsmSharedState;
|
||||||
|
|
||||||
|
@ -429,16 +434,6 @@ typedef struct pgsmLocalState
|
||||||
PGSM_HASH_TABLE *shared_hash;
|
PGSM_HASH_TABLE *shared_hash;
|
||||||
}pgsmLocalState;
|
}pgsmLocalState;
|
||||||
|
|
||||||
#define ResetSharedState(x) \
|
|
||||||
do { \
|
|
||||||
x->cur_median_usage = ASSUMED_MEDIAN_INIT; \
|
|
||||||
x->cur_median_usage = ASSUMED_MEDIAN_INIT; \
|
|
||||||
pg_atomic_init_u64(&x->current_wbucket, 0); \
|
|
||||||
pg_atomic_init_u64(&x->prev_bucket_sec, 0); \
|
|
||||||
memset(&x->bucket_entry, 0, MAX_BUCKETS * sizeof(uint64)); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM < 140000
|
#if PG_VERSION_NUM < 140000
|
||||||
/*
|
/*
|
||||||
* Struct for tracking locations/lengths of constants during normalization
|
* Struct for tracking locations/lengths of constants during normalization
|
||||||
|
|
Loading…
Reference in New Issue