Fixing issue with server crash because of get_database_name without a transaction. Also, added out of memory warning to log as well as pg_stat_monitor_internal view
parent
1343e85919
commit
1d4b0036e7
10
hash_query.c
10
hash_query.c
|
@ -105,6 +105,7 @@ pgsm_startup(void)
|
||||||
dsa_area *dsa;
|
dsa_area *dsa;
|
||||||
char *p = (char *) pgsm;
|
char *p = (char *) pgsm;
|
||||||
|
|
||||||
|
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);
|
ResetSharedState(pgsm);
|
||||||
|
@ -332,7 +333,8 @@ hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_bu
|
||||||
|
|
||||||
if (DsaPointerIsValid(parent_qdsa))
|
if (DsaPointerIsValid(parent_qdsa))
|
||||||
dsa_free(pgsmStateLocal.dsa, parent_qdsa);
|
dsa_free(pgsmStateLocal.dsa, parent_qdsa);
|
||||||
continue;
|
|
||||||
|
pgsmStateLocal.shared_pgsmState->pgsm_oom = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pgsm_hash_seq_term(&hstat);
|
pgsm_hash_seq_term(&hstat);
|
||||||
|
@ -344,6 +346,12 @@ IsHashInitialize(void)
|
||||||
return (pgsmStateLocal.shared_pgsmState != NULL);
|
return (pgsmStateLocal.shared_pgsmState != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
IsSystemOOM(void)
|
||||||
|
{
|
||||||
|
return (IsHashInitialize() && pgsmStateLocal.shared_pgsmState->pgsm_oom);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pgsm_* functions are just wrapper functions over the hash table standard
|
* pgsm_* functions are just wrapper functions over the hash table standard
|
||||||
* API and call the appropriate hash table function based on USE_DYNAMIC_HASH
|
* API and call the appropriate hash table function based on USE_DYNAMIC_HASH
|
||||||
|
|
|
@ -228,6 +228,7 @@ static void RecordConstLocation(JumbleState *jstate, int location);
|
||||||
* relevant part of the string.
|
* relevant part of the string.
|
||||||
*/
|
*/
|
||||||
static const char *CleanQuerytext(const char *query, int *location, int *len);
|
static const char *CleanQuerytext(const char *query, int *location, int *len);
|
||||||
|
static uint64 get_query_id(JumbleState *jstate, Query *query);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static char *generate_normalized_query(JumbleState *jstate, const char *query,
|
static char *generate_normalized_query(JumbleState *jstate, const char *query,
|
||||||
|
@ -237,10 +238,6 @@ static int comp_location(const void *a, const void *b);
|
||||||
|
|
||||||
static uint64 get_next_wbucket(pgsmSharedState *pgsm);
|
static uint64 get_next_wbucket(pgsmSharedState *pgsm);
|
||||||
|
|
||||||
#if PG_VERSION_NUM < 140000
|
|
||||||
static uint64 get_query_id(JumbleState *jstate, Query *query);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Module load callback
|
* Module load callback
|
||||||
*/
|
*/
|
||||||
|
@ -1691,11 +1688,15 @@ pgsm_create_hash_entry(MemoryContext context, uint64 bucket_id, uint64 queryid,
|
||||||
entry->key.toplevel = ((exec_nested_level + plan_nested_level) == 0);
|
entry->key.toplevel = ((exec_nested_level + plan_nested_level) == 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (IsTransactionState())
|
||||||
|
{
|
||||||
datname = get_database_name(entry->key.dbid);
|
datname = get_database_name(entry->key.dbid);
|
||||||
|
username = GetUserNameFromId(entry->key.userid, true);
|
||||||
|
}
|
||||||
|
|
||||||
if (!datname)
|
if (!datname)
|
||||||
datname = pnstrdup("<database name not available>", sizeof(entry->datname) - 1);
|
datname = pnstrdup("<database name not available>", sizeof(entry->datname) - 1);
|
||||||
|
|
||||||
username = GetUserNameFromId(entry->key.userid, true);
|
|
||||||
if (!username)
|
if (!username)
|
||||||
username = pnstrdup("<user name not available>", sizeof(entry->username) - 1);
|
username = pnstrdup("<user name not available>", sizeof(entry->username) - 1);
|
||||||
|
|
||||||
|
@ -1804,6 +1805,18 @@ pgsm_store(pgsmEntry *entry)
|
||||||
|
|
||||||
if (shared_hash_entry == NULL)
|
if (shared_hash_entry == NULL)
|
||||||
{
|
{
|
||||||
|
/* Out of memory; report only if the state has changed now. Otherwise we risk filling up the log file with these message. */
|
||||||
|
if (!IsSystemOOM())
|
||||||
|
{
|
||||||
|
pgsm->pgsm_oom = true;
|
||||||
|
|
||||||
|
ereport(WARNING,
|
||||||
|
(errcode(ERRCODE_OUT_OF_MEMORY),
|
||||||
|
errmsg("[pg_stat_monitor] pgsm_store: Hash table is out of memory and can no longer store queries!"),
|
||||||
|
errdetail("You may reset the view or when the buckets are deallocated, pg_stat_monitor will resume saving " \
|
||||||
|
"queries. Alternatively, try increasing the value of pg_stat_monitor.pgsm_max.")));
|
||||||
|
}
|
||||||
|
|
||||||
LWLockRelease(pgsm->lock);
|
LWLockRelease(pgsm->lock);
|
||||||
|
|
||||||
if (DsaPointerIsValid(dsa_query_pointer))
|
if (DsaPointerIsValid(dsa_query_pointer))
|
||||||
|
@ -1968,6 +1981,14 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||||
errmsg("[pg_stat_monitor] pg_stat_monitor_internal: Must be loaded via shared_preload_libraries.")));
|
errmsg("[pg_stat_monitor] pg_stat_monitor_internal: Must be loaded via shared_preload_libraries.")));
|
||||||
|
|
||||||
|
/* Out of memory? */
|
||||||
|
if (IsSystemOOM())
|
||||||
|
ereport(WARNING,
|
||||||
|
(errcode(ERRCODE_OUT_OF_MEMORY),
|
||||||
|
errmsg("[pg_stat_monitor] pg_stat_monitor_internal: Hash table is out of memory and can no longer store queries!"),
|
||||||
|
errdetail("You may reset the view or when the buckets are deallocated, pg_stat_monitor will resume saving " \
|
||||||
|
"queries. Alternatively, try increasing the value of pg_stat_monitor.pgsm_max.")));
|
||||||
|
|
||||||
/* check to see if caller supports us returning a tuplestore */
|
/* check to see if caller supports us returning a tuplestore */
|
||||||
if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
|
if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
|
@ -1979,8 +2000,6 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||||
errmsg("[pg_stat_monitor] pg_stat_monitor_internal: Materialize mode required, but it is not " \
|
errmsg("[pg_stat_monitor] pg_stat_monitor_internal: Materialize mode required, but it is not " \
|
||||||
"allowed in this context.")));
|
"allowed in this context.")));
|
||||||
|
|
||||||
pgsm = pgsm_get_ss();
|
|
||||||
|
|
||||||
/* Switch into long-lived context to construct returned data structures */
|
/* Switch into long-lived context to construct returned data structures */
|
||||||
per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
|
per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
|
||||||
oldcontext = MemoryContextSwitchTo(per_query_ctx);
|
oldcontext = MemoryContextSwitchTo(per_query_ctx);
|
||||||
|
@ -1999,8 +2018,8 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||||
|
|
||||||
MemoryContextSwitchTo(oldcontext);
|
MemoryContextSwitchTo(oldcontext);
|
||||||
|
|
||||||
|
pgsm = pgsm_get_ss();
|
||||||
LWLockAcquire(pgsm->lock, LW_SHARED);
|
LWLockAcquire(pgsm->lock, LW_SHARED);
|
||||||
|
|
||||||
pgsm_hash_seq_init(&hstat, get_pgsmHash(), false);
|
pgsm_hash_seq_init(&hstat, get_pgsmHash(), false);
|
||||||
|
|
||||||
while ((entry = pgsm_hash_seq_next(&hstat)) != NULL)
|
while ((entry = pgsm_hash_seq_next(&hstat)) != NULL)
|
||||||
|
@ -3410,7 +3429,8 @@ pgsm_emit_log_hook(ErrorData *edata)
|
||||||
if (MyProc == NULL)
|
if (MyProc == NULL)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if (PGSM_ERROR_CAPTURE_ENABLED && edata->elevel >= WARNING)
|
/* Do not store */
|
||||||
|
if (PGSM_ERROR_CAPTURE_ENABLED && edata->elevel >= WARNING && IsSystemOOM() == false)
|
||||||
{
|
{
|
||||||
pgsm_store_error(debug_query_string ? debug_query_string : "",
|
pgsm_store_error(debug_query_string ? debug_query_string : "",
|
||||||
edata);
|
edata);
|
||||||
|
@ -3426,7 +3446,6 @@ IsSystemInitialized(void)
|
||||||
return (system_init && IsHashInitialize());
|
return (system_init && IsHashInitialize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static double
|
static double
|
||||||
time_diff(struct timeval end, struct timeval start)
|
time_diff(struct timeval end, struct timeval start)
|
||||||
{
|
{
|
||||||
|
|
|
@ -417,6 +417,7 @@ 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)
|
||||||
*/
|
*/
|
||||||
|
bool pgsm_oom;
|
||||||
} pgsmSharedState;
|
} pgsmSharedState;
|
||||||
|
|
||||||
typedef struct pgsmLocalState
|
typedef struct pgsmLocalState
|
||||||
|
@ -484,6 +485,7 @@ PGSM_HASH_TABLE *get_pgsmHash(void);
|
||||||
|
|
||||||
void pgsm_attach_shmem(void);
|
void pgsm_attach_shmem(void);
|
||||||
bool IsHashInitialize(void);
|
bool IsHashInitialize(void);
|
||||||
|
bool IsSystemOOM(void);
|
||||||
void pgsm_shmem_startup(void);
|
void pgsm_shmem_startup(void);
|
||||||
void pgsm_shmem_shutdown(int code, Datum arg);
|
void pgsm_shmem_shutdown(int code, Datum arg);
|
||||||
int pgsm_get_bucket_size(void);
|
int pgsm_get_bucket_size(void);
|
||||||
|
|
Loading…
Reference in New Issue