diff --git a/docs/USER_GUIDE.md b/docs/USER_GUIDE.md index 480b1e6..1bdad8d 100644 --- a/docs/USER_GUIDE.md +++ b/docs/USER_GUIDE.md @@ -15,33 +15,6 @@ CREATE EXTENSION Here is the complete list of configuration parameters. ```sql postgres=# select * from pg_stat_monitor_settings; - name | value | default_value | description | minimum | maximum -| restart -------------------------------------------+-------+---------------+----------------------------------------------------------------------------------------------------------+---------+------------ -+--------- - pg_stat_monitor.pgsm_max | 100 | 100 | Sets the maximum size of shared memory in (MB) used for statement's metadata tracked by pg_stat_monitor. | 1 | 1000 -| 1 - pg_stat_monitor.pgsm_query_max_len | 1024 | 1024 | Sets the maximum length of query. | 1024 | 2147483647 -| 1 - pg_stat_monitor.pgsm_enable | 1 | 1 | Enable/Disable statistics collector. | 0 | 0 -| 1 - pg_stat_monitor.pgsm_track_utility | 1 | 0 | Selects whether utility commands are tracked. | 0 | 0 -| 0 - pg_stat_monitor.pgsm_normalized_query | 0 | 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 | 60 | 60 | 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 | 10 | 10 | 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 - pg_stat_monitor.pgsm_query_shared_buffer | 20 | 20 | Sets the maximum size of shared memory in (MB) used for query tracked by pg_stat_monitor. | 1 | 10000 -| 1 -(11 rows) ``` Some configuration parameters require the server restart and should be set before the server startup. These must be set in the ``postgresql.conf`` file. Other parameters do not require server restart and can be set permanently either in the ``postgresql.conf`` or from the client (``psql``). @@ -416,4 +389,4 @@ postgres=# select queryid,parentid,query,calls from pg_stat_monitor; DD2A4843140299C2 | | select * from getnum($1) | 1 42517D48FB98ACF7 | | select prosrc from pg_proc where proname = $1 | 1 (4 rows) -``` \ No newline at end of file +``` diff --git a/expected/guc.out b/expected/guc.out index d4198fe..11f90bb 100644 --- a/expected/guc.out +++ b/expected/guc.out @@ -22,10 +22,11 @@ SELECT * FROM pg_stat_monitor_settings ORDER BY name COLLATE "C"; pg_stat_monitor.pgsm_max | 100 | 100 | Sets the maximum size of shared memory in (MB) used for statement's metadata tracked by pg_stat_monitor. | 1 | 1000 | 1 pg_stat_monitor.pgsm_max_buckets | 10 | 10 | Sets the maximum number of buckets. | 1 | 10 | 1 pg_stat_monitor.pgsm_normalized_query | 1 | 1 | Selects whether save query in normalized format. | 0 | 0 | 0 + pg_stat_monitor.pgsm_overflow_target | 0 | 1 | Sets the overflow target for pg_stat_monitor | 0 | 1 | 1 pg_stat_monitor.pgsm_query_max_len | 1024 | 1024 | Sets the maximum length of query. | 1024 | 2147483647 | 1 pg_stat_monitor.pgsm_query_shared_buffer | 20 | 20 | Sets the maximum size of shared memory in (MB) used for query tracked by pg_stat_monitor. | 1 | 10000 | 1 pg_stat_monitor.pgsm_track_utility | 1 | 1 | Selects whether utility commands are tracked. | 0 | 0 | 0 -(11 rows) +(12 rows) SELECT pg_stat_monitor_reset(); pg_stat_monitor_reset diff --git a/expected/guc_1.out b/expected/guc_1.out index 093fb2c..c840a74 100644 --- a/expected/guc_1.out +++ b/expected/guc_1.out @@ -22,11 +22,12 @@ SELECT * FROM pg_stat_monitor_settings ORDER BY name COLLATE "C"; pg_stat_monitor.pgsm_max | 100 | 100 | Sets the maximum size of shared memory in (MB) used for statement's metadata tracked by pg_stat_monitor. | 1 | 1000 | 1 pg_stat_monitor.pgsm_max_buckets | 10 | 10 | Sets the maximum number of buckets. | 1 | 10 | 1 pg_stat_monitor.pgsm_normalized_query | 1 | 1 | Selects whether save query in normalized format. | 0 | 0 | 0 + pg_stat_monitor.pgsm_overflow_target | 1 | 1 | Sets the overflow target for pg_stat_monitor | 0 | 1 | 1 pg_stat_monitor.pgsm_query_max_len | 1024 | 1024 | Sets the maximum length of query. | 1024 | 2147483647 | 1 pg_stat_monitor.pgsm_query_shared_buffer | 20 | 20 | Sets the maximum size of shared memory in (MB) used for query tracked by pg_stat_monitor. | 1 | 10000 | 1 - pg_stat_monitor.pgsm_track_planning | 1 | 1 | Selects whether planning statistics are tracked. | 0 | 0 | 0 + pg_stat_monitor.pgsm_track_planning | 0 | 1 | Selects whether planning statistics are tracked. | 0 | 0 | 0 pg_stat_monitor.pgsm_track_utility | 1 | 1 | Selects whether utility commands are tracked. | 0 | 0 | 0 -(12 rows) +(13 rows) SELECT pg_stat_monitor_reset(); pg_stat_monitor_reset diff --git a/guc.c b/guc.c index 3f1d75d..58b6e17 100644 --- a/guc.c +++ b/guc.c @@ -18,7 +18,7 @@ #include "pg_stat_monitor.h" -GucVariable conf[13]; +GucVariable conf[MAX_SETTINGS]; static void DefineIntGUC(GucVariable *conf); static void DefineBoolGUC(GucVariable *conf); @@ -161,6 +161,18 @@ init_guc(void) }; DefineIntGUC(&conf[i++]); + conf[i] = (GucVariable) { + .guc_name = "pg_stat_monitor.pgsm_overflow_target", + .guc_desc = "Sets the overflow target for pg_stat_monitor", + .guc_default = 1, + .guc_min = 0, + .guc_max = 1, + .guc_restart = true, + .guc_unit = 0, + .guc_value = &PGSM_OVERFLOW_TARGET + }; + DefineIntGUC(&conf[i++]); + #if PG_VERSION_NUM >= 130000 conf[i] = (GucVariable) { .guc_name = "pg_stat_monitor.pgsm_track_planning", diff --git a/pg_stat_monitor.c b/pg_stat_monitor.c index 2439715..f57581f 100644 --- a/pg_stat_monitor.c +++ b/pg_stat_monitor.c @@ -1179,9 +1179,19 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo, unsigned char *buf = pgss_qbuf[entry->key.bucket_id]; if(read_query(buf, queryid, query_txt) == 0) { - len = read_query_buffer(entry->key.bucket_id, queryid, query_txt); - if (len != MAX_QUERY_BUFFER_BUCKET) - sprintf(query_txt, "%s", "pg_stat_monitor: query not found either in hash nor in temporay file"); + switch(PGSM_OVERFLOW_TARGET) + { + case OVERFLOW_TARGET_NONE: + sprintf(query_txt, "%s", "query not found in query shared_buffer, no space left"); + break; + case OVERFLOW_TARGET_DISK: + { + len = read_query_buffer(entry->key.bucket_id, queryid, query_txt); + if (len != MAX_QUERY_BUFFER_BUCKET) + sprintf(query_txt, "%s", "query not found either in hash nor in temporay file"); + } + break; + } } } if (query_txt) @@ -2405,8 +2415,19 @@ store_query(int bucket_id, uint64 queryid, const char *query, uint64 query_len) if (QUERY_BUFFER_OVERFLOW(buf_len, query_len)) { - dump_queries_buffer(bucket_id, buf, MAX_QUERY_BUFFER_BUCKET); - buf_len = sizeof (uint64); + switch(PGSM_OVERFLOW_TARGET) + { + case OVERFLOW_TARGET_NONE: + return; + case OVERFLOW_TARGET_DISK: + { + dump_queries_buffer(bucket_id, buf, MAX_QUERY_BUFFER_BUCKET); + buf_len = sizeof (uint64); + } + break; + default: + break; + } } memcpy(&buf[buf_len], &queryid, sizeof (uint64)); /* query id */ @@ -2554,11 +2575,7 @@ pg_stat_monitor_settings(PG_FUNCTION_ARGS) MemoryContextSwitchTo(oldcontext); -#if PG_VERSION_NUM >= 130000 - for(i = 0; i < 12; i++) -#else - for(i = 0; i < 11; i++) -#endif + for(i = 0; i < MAX_SETTINGS; i++) { Datum values[7]; bool nulls[7]; diff --git a/pg_stat_monitor.h b/pg_stat_monitor.h index 84d51a4..9b224ff 100644 --- a/pg_stat_monitor.h +++ b/pg_stat_monitor.h @@ -86,12 +86,19 @@ #define MAX_QUERY_BUF (PGSM_QUERY_SHARED_BUFFER * 1024 * 1024) #define MAX_BUCKETS_MEM (PGSM_MAX * 1024 * 1024) #define BUCKETS_MEM_OVERFLOW() ((hash_get_num_entries(pgss_hash) * sizeof(pgssEntry)) >= MAX_BUCKETS_MEM) -#define MAX_QUERY_BUFFER_BUCKET MAX_QUERY_BUF / PGSM_MAX_BUCKETS +#define MAX_QUERY_BUFFER_BUCKET MAX_QUERY_BUF / PGSM_MAX_BUCKETS #define MAX_BUCKET_ENTRIES (MAX_BUCKETS_MEM / sizeof(pgssEntry)) #define QUERY_BUFFER_OVERFLOW(x,y) ((x + y + sizeof(uint64) + sizeof(uint64)) > MAX_QUERY_BUFFER_BUCKET) #define QUERY_MARGIN 100 #define MIN_QUERY_LEN 10 #define SQLCODE_LEN 20 + +#if PG_VERSION_NUM >= 130000 +#define MAX_SETTINGS 13 +#else +#define MAX_SETTINGS 12 +#endif + typedef struct GucVariables { int guc_variable; @@ -105,6 +112,12 @@ typedef struct GucVariables bool guc_restart; } GucVariable; +typedef enum OVERFLOW_TARGET +{ + OVERFLOW_TARGET_NONE = 0, + OVERFLOW_TARGET_DISK +} OVERFLOW_TARGET; + typedef enum pgssStoreKind { PGSS_INVALID = -1, @@ -357,5 +370,6 @@ void pgss_startup(void); #define PGSM_HISTOGRAM_BUCKETS get_conf(9)->guc_variable #define PGSM_QUERY_SHARED_BUFFER get_conf(10)->guc_variable #define PGSM_TRACK_PLANNING get_conf(11)->guc_variable +#define PGSM_OVERFLOW_TARGET get_conf(12)->guc_variable #endif