pg_stat_statements_decay_2012_04_06.patch

application/octet-stream

Filename: pg_stat_statements_decay_2012_04_06.patch
Type: application/octet-stream
Part: 1
Message: Re: Re: pg_stat_statements normalisation without invasive changes to the parser (was: Next steps on pg_stat_statements normalisation)

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: context
File+
contrib/pg_stat_statements/pg_stat_statements.c 14 4
diff contrib/pg_stat_statements/pg_stat_statements.c
index 178fdb9..823a62d
*** a/contrib/pg_stat_statements/pg_stat_statements.c
--- b/contrib/pg_stat_statements/pg_stat_statements.c
*************** static const uint32 PGSS_FILE_HEADER = 0
*** 72,79 ****
  /* XXX: Should USAGE_EXEC reflect execution time and/or buffer usage? */
  #define USAGE_EXEC(duration)	(1.0)
  #define USAGE_INIT				(1.0)	/* including initial planning */
! #define USAGE_NON_EXEC_STICK	(3.0)	/* to make new entries sticky */
  #define USAGE_DECREASE_FACTOR	(0.99)	/* decreased every entry_dealloc */
  #define USAGE_DEALLOC_PERCENT	5		/* free this % of entries at once */

  #define JUMBLE_SIZE				1024	/* query serialization buffer size */
--- 72,80 ----
  /* XXX: Should USAGE_EXEC reflect execution time and/or buffer usage? */
  #define USAGE_EXEC(duration)	(1.0)
  #define USAGE_INIT				(1.0)	/* including initial planning */
! #define ASSUMED_MED_INIT		(10.0)	/* initial assumed median usage */
  #define USAGE_DECREASE_FACTOR	(0.99)	/* decreased every entry_dealloc */
+ #define STICKY_DECREASE_FACTOR	(0.50)	/* separate sticky decrease factor */
  #define USAGE_DEALLOC_PERCENT	5		/* free this % of entries at once */

  #define JUMBLE_SIZE				1024	/* query serialization buffer size */
*************** typedef struct pgssSharedState
*** 139,144 ****
--- 140,146 ----
  {
  	LWLockId	lock;			/* protects hashtable search/modification */
  	int			query_size;		/* max query length in bytes */
+ 	double		cur_med_usage;	/* current median of usage for hashtable */
  } pgssSharedState;

  /*
*************** pgss_shmem_startup(void)
*** 413,418 ****
--- 415,421 ----
  		/* First time through ... */
  		pgss->lock = LWLockAssign();
  		pgss->query_size = pgstat_track_activity_query_size;
+ 		pgss->cur_med_usage = ASSUMED_MED_INIT;
  	}

  	/* Be sure everyone agrees on the hash table entry size */
*************** pgss_match_fn(const void *key1, const vo
*** 908,914 ****
  /*
   * Given an arbitrarily long query string, produce a hash for the purposes of
   * identifying the query, without normalizing constants.  Used when hashing
!  * utility statements, or for legacy compatibility mode.
   */
  static uint32
  pgss_hash_string(const char *str)
--- 911,917 ----
  /*
   * Given an arbitrarily long query string, produce a hash for the purposes of
   * identifying the query, without normalizing constants.  Used when hashing
!  * utility statements.
   */
  static uint32
  pgss_hash_string(const char *str)
*************** pgss_store(const char *query, uint32 que
*** 959,965 ****
  	 * under artificial conditions.
  	 */
  	if (jstate && !entry)
! 		usage = USAGE_NON_EXEC_STICK;
  	else
  		usage = USAGE_EXEC(duration);

--- 962,970 ----
  	 * under artificial conditions.
  	 */
  	if (jstate && !entry)
! 		usage = pgss->cur_med_usage;
! 	else if (jstate && entry)
! 		usage = 0;
  	else
  		usage = USAGE_EXEC(duration);

*************** entry_dealloc(void)
*** 1297,1309 ****
  	while ((entry = hash_seq_search(&hash_seq)) != NULL)
  	{
  		entries[i++] = entry;
! 		entry->counters.usage *= USAGE_DECREASE_FACTOR;
  	}

  	qsort(entries, i, sizeof(pgssEntry *), entry_cmp);
  	nvictims = Max(10, i * USAGE_DEALLOC_PERCENT / 100);
  	nvictims = Min(nvictims, i);

  	for (i = 0; i < nvictims; i++)
  	{
  		hash_search(pgss_hash, &entries[i]->key, HASH_REMOVE, NULL);
--- 1302,1321 ----
  	while ((entry = hash_seq_search(&hash_seq)) != NULL)
  	{
  		entries[i++] = entry;
!
! 		if (entry->counters.calls == 0)
! 			entry->counters.usage *= STICKY_DECREASE_FACTOR;
! 		else
! 			entry->counters.usage *= USAGE_DECREASE_FACTOR;
  	}

  	qsort(entries, i, sizeof(pgssEntry *), entry_cmp);
  	nvictims = Max(10, i * USAGE_DEALLOC_PERCENT / 100);
  	nvictims = Min(nvictims, i);

+ 	/* Record the median usage */
+ 	pgss->cur_med_usage = entries[i / 2]->counters.usage;
+
  	for (i = 0; i < nvictims; i++)
  	{
  		hash_search(pgss_hash, &entries[i]->key, HASH_REMOVE, NULL);