Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd537549

Browse files
committed
Improve management of "sticky" entries in contrib/pg_stat_statements.
This patch addresses a deficiency in the previous pg_stat_statements patch.We want to give sticky entries an initial "usage" factor high enough thatthey probably will stick around until their query is completed. However,if the query never completes (eg it gets an error during execution), theentry shouldn't persist indefinitely. Manage this by starting out witha usage setting equal to the (approximate) median usage value within thewhole hashtable, but decaying the value much more aggressively than wedo for normal entries.Peter Geoghegan
1 parent03529a3 commitd537549

File tree

1 file changed

+42
-15
lines changed

1 file changed

+42
-15
lines changed

‎contrib/pg_stat_statements/pg_stat_statements.c

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ static const uint32 PGSS_FILE_HEADER = 0x20120328;
7272
/* XXX: Should USAGE_EXEC reflect execution time and/or buffer usage? */
7373
#defineUSAGE_EXEC(duration)(1.0)
7474
#defineUSAGE_INIT(1.0)/* including initial planning */
75-
#defineUSAGE_NON_EXEC_STICK(3.0)/*to make new entries sticky */
75+
#defineASSUMED_MEDIAN_INIT(10.0)/*initial assumed median usage */
7676
#defineUSAGE_DECREASE_FACTOR(0.99)/* decreased every entry_dealloc */
77+
#defineSTICKY_DECREASE_FACTOR(0.50)/* factor for sticky entries */
7778
#defineUSAGE_DEALLOC_PERCENT5/* free this % of entries at once */
7879

7980
#defineJUMBLE_SIZE1024/* query serialization buffer size */
@@ -139,6 +140,7 @@ typedef struct pgssSharedState
139140
{
140141
LWLockIdlock;/* protects hashtable search/modification */
141142
intquery_size;/* max query length in bytes */
143+
doublecur_median_usage;/* current median usage in hashtable */
142144
}pgssSharedState;
143145

144146
/*
@@ -413,6 +415,7 @@ pgss_shmem_startup(void)
413415
/* First time through ... */
414416
pgss->lock=LWLockAssign();
415417
pgss->query_size=pgstat_track_activity_query_size;
418+
pgss->cur_median_usage=ASSUMED_MEDIAN_INIT;
416419
}
417420

418421
/* Be sure everyone agrees on the hash table entry size */
@@ -908,7 +911,7 @@ pgss_match_fn(const void *key1, const void *key2, Size keysize)
908911
/*
909912
* Given an arbitrarily long query string, produce a hash for the purposes of
910913
* identifying the query, without normalizing constants. Used when hashing
911-
* utility statements, or for legacy compatibility mode.
914+
* utility statements.
912915
*/
913916
staticuint32
914917
pgss_hash_string(constchar*str)
@@ -951,17 +954,28 @@ pgss_store(const char *query, uint32 queryId,
951954

952955
entry= (pgssEntry*)hash_search(pgss_hash,&key,HASH_FIND,NULL);
953956

954-
/*
955-
* When creating an entry just to store the normalized string, make it
956-
* artificially sticky so that it will probably still be there when
957-
* executed. Strictly speaking, query strings are normalized on a best
958-
* effort basis, though it would be difficult to demonstrate this even
959-
* under artificial conditions.
960-
*/
961-
if (jstate&& !entry)
962-
usage=USAGE_NON_EXEC_STICK;
957+
if (jstate)
958+
{
959+
/*
960+
* When creating an entry just to store the normalized string, make it
961+
* artificially sticky so that it will probably still be there when
962+
* the query gets executed. We do this by giving it a median usage
963+
* value rather than the normal value. (Strictly speaking, query
964+
* strings are normalized on a best effort basis, though it would be
965+
* difficult to demonstrate this even under artificial conditions.)
966+
* But if we found the entry already present, don't let this call
967+
* increment its usage.
968+
*/
969+
if (!entry)
970+
usage=pgss->cur_median_usage;
971+
else
972+
usage=0;
973+
}
963974
else
975+
{
976+
/* normal case, increment usage by normal amount */
964977
usage=USAGE_EXEC(duration);
978+
}
965979

966980
if (!entry)
967981
{
@@ -1185,8 +1199,8 @@ pg_stat_statements(PG_FUNCTION_ARGS)
11851199
values[i++]=Float8GetDatumFast(tmp.time_write);
11861200
}
11871201

1188-
Assert(i==sql_supports_v1_1_counters ?
1189-
PG_STAT_STATEMENTS_COLS :PG_STAT_STATEMENTS_COLS_V1_0);
1202+
Assert(i==(sql_supports_v1_1_counters ?
1203+
PG_STAT_STATEMENTS_COLS :PG_STAT_STATEMENTS_COLS_V1_0));
11901204

11911205
tuplestore_putvalues(tupstore,tupdesc,values,nulls);
11921206
}
@@ -1288,7 +1302,11 @@ entry_dealloc(void)
12881302
intnvictims;
12891303
inti;
12901304

1291-
/* Sort entries by usage and deallocate USAGE_DEALLOC_PERCENT of them. */
1305+
/*
1306+
* Sort entries by usage and deallocate USAGE_DEALLOC_PERCENT of them.
1307+
* While we're scanning the table, apply the decay factor to the usage
1308+
* values.
1309+
*/
12921310

12931311
entries=palloc(hash_get_num_entries(pgss_hash)*sizeof(pgssEntry*));
12941312

@@ -1297,10 +1315,19 @@ entry_dealloc(void)
12971315
while ((entry=hash_seq_search(&hash_seq))!=NULL)
12981316
{
12991317
entries[i++]=entry;
1300-
entry->counters.usage *=USAGE_DECREASE_FACTOR;
1318+
/* "Sticky" entries get a different usage decay rate. */
1319+
if (entry->counters.calls==0)
1320+
entry->counters.usage *=STICKY_DECREASE_FACTOR;
1321+
else
1322+
entry->counters.usage *=USAGE_DECREASE_FACTOR;
13011323
}
13021324

13031325
qsort(entries,i,sizeof(pgssEntry*),entry_cmp);
1326+
1327+
/* Also, record the (approximate) median usage */
1328+
if (i>0)
1329+
pgss->cur_median_usage=entries[i /2]->counters.usage;
1330+
13041331
nvictims=Max(10,i*USAGE_DEALLOC_PERCENT /100);
13051332
nvictims=Min(nvictims,i);
13061333

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp