Skip to content

Commit

Permalink
PG-147: Stored Procedure Support add parentid to track caller.
Browse files Browse the repository at this point in the history
 Patch By: Martin Sun
 Reviewed By: Hamid Akhtar
  • Loading branch information
ibrarahmad committed Feb 12, 2021
1 parent 38619a4 commit 6910813
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 8 deletions.
41 changes: 41 additions & 0 deletions docs/USER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -376,3 +376,44 @@ postgres=# SELECT bucket, substr(query,0, 50) AS query, cmd_type FROM pg_stat_mo
4 | UPDATE pgbench_branches SET bbalance = bbalance + | UPDATE
(14 rows)
```

#### Function Execution Tracking

**`parentid`**: Outer layer caller's query id.

```sql
postgres=# select prosrc from pg_proc where proname = 'getnum';
prosrc
--------------------------------
select * from t1 where a >= $1
(1 row)

postgresr=# select pg_stat_monitor_reset();
pg_stat_monitor_reset
-----------------------

(1 row)

postgres=# select prosrc from pg_proc where proname = 'getnum';
prosrc
--------------------------------
select * from t1 where a >= $1
(1 row)

postgres=# select * from getnum(2);
a
---
2
3
4
(3 rows)

postgres=# select queryid,parentid,query,calls from pg_stat_monitor;
queryid | parentid | query | calls
------------------+------------------+-----------------------------------------------+-------
3FEC80684AFE7FC7 | DD2A4843140299C2 | select * from t1 where a >= $1 | 1
6ED05FFB78DD52FA | | select pg_stat_monitor_reset() | 1
DD2A4843140299C2 | | select * from getnum($1) | 1
42517D48FB98ACF7 | | select prosrc from pg_proc where proname = $1 | 1
(4 rows)
```
2 changes: 1 addition & 1 deletion expected/basic.out
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ SELECT 1;
1
(1 row)

SELECT query FROM pg_stat_monitor ORDER BY query;
SELECT query FROM pg_stat_monitor ORDER BY query COLLATE "C";
query
--------------------------------
SELECT $1
Expand Down
4 changes: 2 additions & 2 deletions expected/guc.out
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ SELECT * FROM pg_stat_monitor_settings;
pg_stat_monitor.pgsm_track_utility | 0 | 0 | Selects whether utility commands are tracked. | 0 | 0 | 0
pg_stat_monitor.pgsm_normalized_query | 1 | 1 | Selects whether save query in normalized format. | 0 | 0 | 0
pg_stat_monitor.pgsm_max_buckets | 10 | 10 | Sets the maximum number of buckets. | 1 | 10 | 1
pg_stat_monitor.pgsm_bucket_time | 300 | 60 | Sets the time in seconds per bucket. | 1 | 2147483647 | 1
pg_stat_monitor.pgsm_bucket_time | 300 | 300 | Sets the time in seconds per bucket. | 1 | 2147483647 | 1
pg_stat_monitor.pgsm_histogram_min | 0 | 0 | Sets the time in millisecond. | 0 | 2147483647 | 1
pg_stat_monitor.pgsm_histogram_max | 100000 | 10 | Sets the time in millisecond. | 10 | 2147483647 | 1
pg_stat_monitor.pgsm_histogram_max | 100000 | 100000 | Sets the time in millisecond. | 10 | 2147483647 | 1
pg_stat_monitor.pgsm_histogram_buckets | 10 | 10 | Sets the maximum number of histogram buckets | 2 | 2147483647 | 1
(10 rows)

Expand Down
4 changes: 2 additions & 2 deletions guc.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ init_guc(void)
conf[i] = (GucVariable) {
.guc_name = "pg_stat_monitor.pgsm_bucket_time",
.guc_desc = "Sets the time in seconds per bucket.",
.guc_default = 60,
.guc_default = 300,
.guc_min = 1,
.guc_max = INT_MAX,
.guc_restart = true,
Expand All @@ -128,7 +128,7 @@ init_guc(void)
conf[i] = (GucVariable) {
.guc_name = "pg_stat_monitor.pgsm_histogram_max",
.guc_desc = "Sets the time in millisecond.",
.guc_default = 10,
.guc_default = 100000,
.guc_min = 10,
.guc_max = INT_MAX,
.guc_restart = true,
Expand Down
5 changes: 4 additions & 1 deletion pg_stat_monitor--1.0.sql
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ CREATE FUNCTION pg_stat_monitor(IN showtext boolean,
OUT client_ip int8,

OUT queryid text,
OUT parentid text,
OUT query text,
OUT application_name text,
OUT relations text,
Expand Down Expand Up @@ -125,10 +126,12 @@ CREATE VIEW pg_stat_monitor AS SELECT
datname,
'0.0.0.0'::inet + client_ip AS client_ip,
queryid,
parentid,
query,
(SELECT query from pg_stat_monitor(true) s where s.queryid = p.parentid) AS parent_query,
application_name,
string_to_array(relations, ',') AS relations,
cmd_type,
cmd_type,
get_cmd_type(cmd_type) AS cmd_type_text,
elevel,
sqlcode,
Expand Down
42 changes: 41 additions & 1 deletion pg_stat_monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
PG_MODULE_MAGIC;

#define BUILD_VERSION "0.8.0"
#define PG_STAT_STATEMENTS_COLS 46 /* maximum of above */
#define PG_STAT_STATEMENTS_COLS 47 /* maximum of above */
#define PGSM_TEXT_FILE "/tmp/pg_stat_monitor_query"

#define PGUNSIXBIT(val) (((val) & 0x3F) + '0')
Expand Down Expand Up @@ -63,6 +63,11 @@ void _PG_fini(void);
/* Current nesting depth of ExecutorRun+ProcessUtility calls */
static int nested_level = 0;

/* the current max level a query can nested */
int cur_max_nested_level;
/* The array to store outer layer query id*/
uint64 *nested_queryids;

#if PG_VERSION_NUM >= 130000
static int plan_nested_level = 0;
static int exec_nested_level = 0;
Expand Down Expand Up @@ -240,6 +245,9 @@ _PG_init(void)
prev_ExecutorCheckPerms_hook = ExecutorCheckPerms_hook;
ExecutorCheckPerms_hook = pgss_ExecutorCheckPerms;

cur_max_nested_level = max_stack_depth;
nested_queryids = (uint64*)malloc(sizeof(uint64)*cur_max_nested_level);

system_init = true;
}

Expand All @@ -257,6 +265,9 @@ _PG_fini(void)
ExecutorFinish_hook = prev_ExecutorFinish;
ExecutorEnd_hook = prev_ExecutorEnd;
ProcessUtility_hook = prev_ProcessUtility;

free(nested_queryids);

hash_entry_reset();
}

Expand Down Expand Up @@ -389,6 +400,12 @@ static void
pgss_ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count,
bool execute_once)
{
nested_queryids[nested_level] = queryDesc->plannedstmt->queryId;
if(nested_level + 1 >= cur_max_nested_level)
{
cur_max_nested_level *= 2;
nested_queryids = realloc(nested_queryids, cur_max_nested_level);
}
nested_level++;
PG_TRY();
{
Expand All @@ -397,10 +414,12 @@ pgss_ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count,
else
standard_ExecutorRun(queryDesc, direction, count, execute_once);
nested_level--;
nested_queryids[nested_level] = UINT64CONST(0);
}
PG_CATCH();
{
nested_level--;
nested_queryids[nested_level] = UINT64CONST(0);
PG_RE_THROW();
}
PG_END_TRY();
Expand Down Expand Up @@ -985,6 +1004,11 @@ static void pgss_store(uint64 queryId,
_snprintf(e->counters.error.sqlcode, sqlcode, sqlcode_len, SQLCODE_LEN);
_snprintf(e->counters.error.message, message, message_len, ERROR_MESSAGE_LEN);

if(nested_level > 0)
e->counters.info.parentid = nested_queryids[nested_level - 1];
else
e->counters.info.parentid = UINT64CONST(0);

e->counters.calls[kind].rows += rows;
e->counters.blocks.shared_blks_hit += bufusage->shared_blks_hit;
e->counters.blocks.shared_blks_read += bufusage->shared_blks_read;
Expand Down Expand Up @@ -1075,6 +1099,7 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
pgssEntry *entry;
char *query_txt;
char queryid_txt[64];
char parentid_txt[64];
pgssSharedState *pgss = pgsm_get_ss();
HTAB *pgss_hash = pgsm_get_hash();

Expand Down Expand Up @@ -1179,7 +1204,19 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
tmp = e->counters;
SpinLockRelease(&e->mutex);
}

values[i++] = CStringGetTextDatum(queryid_txt);

if (tmp.info.parentid != UINT64CONST(0))
{
sprintf(parentid_txt,"%08lX",tmp.info.parentid);
values[i++] = CStringGetTextDatum(parentid_txt);
}
else
{
nulls[i++] = true;
}

if (is_allowed_role || entry->key.userid == userid)
{
if (showtext)
Expand All @@ -1205,6 +1242,9 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
}
else
{
/*skip the query id and parent id*/
nulls[i++] = true;
nulls[i++] = true;
/*
* Don't show query text, but hint as to the reason for not doing
* so if it was requested
Expand Down
3 changes: 3 additions & 0 deletions pg_stat_monitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ typedef enum pgssStoreKind
PGSS_NUMKIND /* Must be last value of this enum */
} pgssStoreKind;

/* the assumption of query max nested level */
#define DEFAULT_MAX_NESTED_LEVEL 10

/*
* Type of aggregate keys
Expand Down Expand Up @@ -161,6 +163,7 @@ typedef struct QueryInfo
Oid userid; /* user OID */
Oid dbid; /* database OID */
uint host; /* client IP */
uint64 parentid; /* parent queryid of current query*/
int64 type; /* type of query, options are query, info, warning, error, fatal */
char application_name[APPLICATIONNAME_LEN];
char relations[REL_LST][REL_LEN]; /* List of relation involved in the query */
Expand Down
2 changes: 1 addition & 1 deletion sql/basic.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ CREATE EXTENSION pg_stat_monitor;
SELECT pg_stat_monitor_reset();
select pg_sleep(.5);
SELECT 1;
SELECT query FROM pg_stat_monitor ORDER BY query;
SELECT query FROM pg_stat_monitor ORDER BY query COLLATE "C";
SELECT pg_stat_monitor_reset();
DROP EXTENSION pg_stat_monitor;

0 comments on commit 6910813

Please sign in to comment.