Skip to content

Commit 67a54c7

Browse files
author
Hamid Akhtar
authored
Merge pull request #399 from codeforall/main
Merging changes back to the main branch after the 2.0.1 release
2 parents 7623f15 + d2f1336 commit 67a54c7

File tree

6 files changed

+52
-30
lines changed

6 files changed

+52
-30
lines changed

META.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22
"name": "pg_stat_monitor",
33
"abstract": "PostgreSQL Query Performance Monitoring Tool",
44
"description": "pg_stat_monitor is a PostgreSQL Query Performance Monitoring tool, based on PostgreSQL's contrib module pg_stat_statements. PostgreSQL’s pg_stat_statements provides the basic statistics, which is sometimes not enough. The major shortcoming in pg_stat_statements is that it accumulates all the queries and their statistics and does not provide aggregated statistics nor histogram information. In this case, a user would need to calculate the aggregates, which is quite an expensive operation.",
5-
"version": "2.0.0",
5+
"version": "2.0.1",
66
"maintainer": [
77
88
],
99
"license": "postgresql",
1010
"provides": {
1111
"pg_stat_monitor": {
1212
"abstract": "PostgreSQL Query Performance Monitoring Tool",
13-
"file": "pg_stat_monitor--1.0.sql",
13+
"file": "pg_stat_monitor--2.0.sql",
1414
"docfile": "README.md",
15-
"version": "2.0.0"
15+
"version": "2.0.1"
1616
}
1717
},
1818
"prereqs": {

hash_query.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ static PGSM_HASH_TABLE_HANDLE pgsm_create_bucket_hash(pgsmSharedState * pgsm, ds
2323
static Size pgsm_get_shared_area_size(void);
2424
static void InitializeSharedState(pgsmSharedState * pgsm);
2525

26+
#define PGSM_BUCKET_INFO_SIZE (sizeof(TimestampTz) * pgsm_max_buckets)
27+
#define PGSM_SHARED_STATE_SIZE (sizeof(pgsmSharedState) + PGSM_BUCKET_INFO_SIZE)
28+
2629
#if USE_DYNAMIC_HASH
2730
/* parameter for the shared hash */
2831
static dshash_parameters dsh_params = {
@@ -56,7 +59,7 @@ pgsm_query_area_size(void)
5659
Size
5760
pgsm_ShmemSize(void)
5861
{
59-
Size sz = MAXALIGN(sizeof(pgsmSharedState));
62+
Size sz = MAXALIGN(PGSM_SHARED_STATE_SIZE);
6063

6164
sz = add_size(sz, MAX_QUERY_BUF);
6265
#if USE_DYNAMIC_HASH
@@ -114,7 +117,7 @@ pgsm_startup(void)
114117
SpinLockInit(&pgsm->mutex);
115118
InitializeSharedState(pgsm);
116119
/* the allocation of pgsmSharedState itself */
117-
p += MAXALIGN(sizeof(pgsmSharedState));
120+
p += MAXALIGN(PGSM_SHARED_STATE_SIZE);
118121
pgsm->raw_dsa_area = p;
119122
dsa = dsa_create_in_place(pgsm->raw_dsa_area,
120123
pgsm_query_area_size(),
@@ -138,6 +141,10 @@ pgsm_startup(void)
138141
* references.
139142
*/
140143
dsa_detach(dsa);
144+
145+
pgsmStateLocal.pgsm_mem_cxt = AllocSetContextCreate(TopMemoryContext,
146+
"pg_stat_monitor local store",
147+
ALLOCSET_DEFAULT_SIZES);
141148
}
142149

143150
#ifdef BENCHMARK
@@ -158,10 +165,6 @@ InitializeSharedState(pgsmSharedState * pgsm)
158165
{
159166
pg_atomic_init_u64(&pgsm->current_wbucket, 0);
160167
pg_atomic_init_u64(&pgsm->prev_bucket_sec, 0);
161-
memset(&pgsm->bucket_entry, 0, MAX_BUCKETS * sizeof(uint64));
162-
pgsm->pgsm_mem_cxt = AllocSetContextCreate(TopMemoryContext,
163-
"pg_stat_monitor local store",
164-
ALLOCSET_DEFAULT_SIZES);
165168
}
166169

167170

@@ -235,6 +238,11 @@ pgsm_attach_shmem(void)
235238
MemoryContextSwitchTo(oldcontext);
236239
}
237240

241+
MemoryContext GetPgsmMemoryContext(void)
242+
{
243+
return pgsmStateLocal.pgsm_mem_cxt;
244+
}
245+
238246
dsa_area *
239247
get_dsa_area_for_query_text(void)
240248
{
@@ -290,7 +298,6 @@ hash_entry_alloc(pgsmSharedState * pgsm, pgsmHashKey * key, int encoding)
290298
elog(DEBUG1, "[pg_stat_monitor] hash_entry_alloc: OUT OF MEMORY.");
291299
else if (!found)
292300
{
293-
pgsm->bucket_entry[pg_atomic_read_u64(&pgsm->current_wbucket)]++;
294301
/* New entry, initialize it */
295302
/* reset the statistics */
296303
memset(&entry->counters, 0, sizeof(Counters));

pg_stat_monitor.c

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ typedef enum pgsmVersion
3636

3737
PG_MODULE_MAGIC;
3838

39-
#define BUILD_VERSION "2.0.0"
39+
#define BUILD_VERSION "2.0.1"
4040

4141
/* Number of output arguments (columns) for various API versions */
4242
#define PG_STAT_MONITOR_COLS_V1_0 52
@@ -692,9 +692,30 @@ pgsm_ExecutorEnd(QueryDesc *queryDesc)
692692
/* Extract the plan information in case of SELECT statement */
693693
if (queryDesc->operation == CMD_SELECT && pgsm_enable_query_plan)
694694
{
695-
plan_info.plan_len = snprintf(plan_info.plan_text, PLAN_TEXT_LEN, "%s", pgsm_explain(queryDesc));
696-
plan_info.planid = pgsm_hash_string(plan_info.plan_text, plan_info.plan_len);
697-
plan_ptr = &plan_info;
695+
int rv;
696+
MemoryContext oldctx;
697+
698+
/*
699+
* Making sure it is a per query context so that there's no memory
700+
* leak when executor ends.
701+
*/
702+
oldctx = MemoryContextSwitchTo(queryDesc->estate->es_query_cxt);
703+
704+
rv = snprintf(plan_info.plan_text, PLAN_TEXT_LEN, "%s", pgsm_explain(queryDesc));
705+
706+
/*
707+
* If snprint didn't write anything or there was an error, let's keep
708+
* planinfo as NULL.
709+
*/
710+
if (rv > 0)
711+
{
712+
plan_info.plan_len = (rv < PLAN_TEXT_LEN) ? rv : PLAN_TEXT_LEN - 1;
713+
plan_info.planid = pgsm_hash_string(plan_info.plan_text, plan_info.plan_len);
714+
plan_ptr = &plan_info;
715+
}
716+
717+
/* Switch back to old context */
718+
MemoryContextSwitchTo(oldctx);
698719
}
699720

700721
if (queryId != UINT64CONST(0) && queryDesc->totaltime && pgsm_enabled(exec_nested_level))
@@ -1569,7 +1590,7 @@ static void
15691590
pgsm_add_to_list(pgsmEntry * entry, char *query_text, int query_len)
15701591
{
15711592
/* Switch to pgsm memory context */
1572-
MemoryContext oldctx = MemoryContextSwitchTo(pgsm_get_ss()->pgsm_mem_cxt);
1593+
MemoryContext oldctx = MemoryContextSwitchTo(GetPgsmMemoryContext());
15731594

15741595
entry->query_text.query_pointer = pnstrdup(query_text, query_len);
15751596
lentries = lappend(lentries, entry);
@@ -1624,7 +1645,8 @@ static void
16241645
pgsm_cleanup_callback(void *arg)
16251646
{
16261647
/* Reset the memory context holding the list */
1627-
MemoryContextReset(pgsm_get_ss()->pgsm_mem_cxt);
1648+
MemoryContextReset(GetPgsmMemoryContext());
1649+
16281650
lentries = NIL;
16291651
callback_setup = false;
16301652
}
@@ -1645,7 +1667,7 @@ pgsm_create_hash_entry(uint64 bucket_id, uint64 queryid, PlanInfo * plan_info)
16451667
char *username = NULL;
16461668

16471669
/* Create an entry in the pgsm memory context */
1648-
oldctx = MemoryContextSwitchTo(pgsm_get_ss()->pgsm_mem_cxt);
1670+
oldctx = MemoryContextSwitchTo(GetPgsmMemoryContext());
16491671
entry = palloc0(sizeof(pgsmEntry));
16501672

16511673
/*

pg_stat_monitor.h

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@
7777
#define HISTOGRAM_MAX_TIME 50000000
7878
#define MAX_RESPONSE_BUCKET 50
7979
#define INVALID_BUCKET_ID -1
80-
#define MAX_BUCKETS 10
8180
#define TEXT_LEN 255
8281
#define ERROR_MESSAGE_LEN 100
8382
#define REL_TYPENAME_LEN 64
@@ -388,8 +387,6 @@ typedef struct pgsmSharedState
388387
slock_t mutex; /* protects following fields only: */
389388
pg_atomic_uint64 current_wbucket;
390389
pg_atomic_uint64 prev_bucket_sec;
391-
uint64 bucket_entry[MAX_BUCKETS];
392-
TimestampTz bucket_start_time[MAX_BUCKETS]; /* start time of the bucket */
393390
int hash_tranche_id;
394391
void *raw_dsa_area; /* DSA area pointer to store query texts.
395392
* dshash also lives in this memory when
@@ -400,16 +397,9 @@ typedef struct pgsmSharedState
400397
* hash table handle. can be either classic shared memory hash or dshash
401398
* (if we are using USE_DYNAMIC_HASH)
402399
*/
403-
MemoryContext pgsm_mem_cxt;
404400

405-
/*
406-
* context to store stats in local memory until they are pushed to shared
407-
* hash
408-
*/
409-
int resp_calls[MAX_RESPONSE_BUCKET + 2]; /* execution time's in
410-
* msec; including 2
411-
* outlier buckets */
412401
bool pgsm_oom;
402+
TimestampTz bucket_start_time[]; /* start time of the bucket */
413403
} pgsmSharedState;
414404

415405
typedef struct pgsmLocalState
@@ -418,6 +408,8 @@ typedef struct pgsmLocalState
418408
dsa_area *dsa; /* local dsa area for backend attached to the
419409
* dsa area created by postmaster at startup. */
420410
PGSM_HASH_TABLE *shared_hash;
411+
MemoryContext pgsm_mem_cxt;
412+
421413
} pgsmLocalState;
422414

423415
#if PG_VERSION_NUM < 140000
@@ -479,6 +471,7 @@ void pgsm_startup(void);
479471

480472
/* hash_query.c */
481473
void pgsm_startup(void);
474+
MemoryContext GetPgsmMemoryContext(void);
482475

483476
/* guc.c */
484477
void init_guc(void);

regression/expected/version.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ CREATE EXTENSION pg_stat_monitor;
22
SELECT pg_stat_monitor_version();
33
pg_stat_monitor_version
44
-------------------------
5-
2.0.0
5+
2.0.1
66
(1 row)
77

88
DROP EXTENSION pg_stat_monitor;

rpm/pg-stat-monitor.spec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ It provides all the features of pg_stat_statment plus its own feature set.
3333

3434

3535
%build
36-
sed -i 's:PG_CONFIG = pg_config:PG_CONFIG = /usr/pgsql-%{pgrel}/bin/pg_config:' Makefile
36+
sed -i 's:PG_CONFIG ?= pg_config:PG_CONFIG = /usr/pgsql-%{pgrel}/bin/pg_config:' Makefile
3737
%{__make} USE_PGXS=1 %{?_smp_mflags}
3838

3939

0 commit comments

Comments
 (0)