diff --git a/src/backend/utils/hash/dynahash.c b/src/backend/utils/hash/dynahash.c
index d0843551007..a10415feae0 100644
--- a/src/backend/utils/hash/dynahash.c
+++ b/src/backend/utils/hash/dynahash.c
@@ -205,8 +205,9 @@ struct HASHHDR
 	 * Count statistics here.  NB: stats code doesn't bother with mutex, so
 	 * counts could be corrupted a bit in a partitioned table.
 	 */
-	long		accesses;
-	long		collisions;
+	uint64		accesses;
+	uint64		collisions;
+	uint64		expansions;
 #endif
 };
 
@@ -266,12 +267,6 @@ struct HTAB
  */
 #define MOD(x,y)			   ((x) & ((y)-1))
 
-#ifdef HASH_STATISTICS
-static long hash_accesses,
-			hash_collisions,
-			hash_expansions;
-#endif
-
 /*
  * Private function prototypes
  */
@@ -661,7 +656,7 @@ hdefault(HTAB *hashp)
 	hctl->isfixed = false;		/* can be enlarged */
 
 #ifdef HASH_STATISTICS
-	hctl->accesses = hctl->collisions = 0;
+	hctl->accesses = hctl->collisions = hctl->expansions = 0;
 #endif
 }
 
@@ -776,15 +771,9 @@ init_htab(HTAB *hashp, long nelem)
 	hctl->nelem_alloc = choose_nelem_alloc(hctl->entrysize);
 
 #ifdef HASH_DEBUG
-	fprintf(stderr, "init_htab:\n%s%p\n%s%ld\n%s%ld\n%s%d\n%s%u\n%s%x\n%s%x\n%s%ld\n",
-			"TABLE POINTER   ", hashp,
-			"DIRECTORY SIZE  ", hctl->dsize,
-			"SEGMENT SIZE    ", hctl->ssize,
-			"SEGMENT SHIFT   ", hctl->sshift,
-			"MAX BUCKET      ", hctl->max_bucket,
-			"HIGH MASK       ", hctl->high_mask,
-			"LOW  MASK       ", hctl->low_mask,
-			"NSEGS           ", hctl->nsegs);
+	elog(DEBUG4, "init_htab: Table Name: \"%s\"  Directory Size: %ld  Segment Size: %ld  Segment Shift: %d  Max Bucket: %u  High Mask: %x  Low Mask: %x  Number Segments: %ld",
+		 hashp->tabname, hctl->dsize, hctl->ssize, hctl->sshift, hctl->max_bucket,
+		 hctl->high_mask, hctl->low_mask, hctl->nsegs);
 #endif
 	return true;
 }
@@ -888,7 +877,7 @@ hash_destroy(HTAB *hashp)
 		/* so this hashtable must have its own context */
 		Assert(hashp->hcxt != NULL);
 
-		hash_stats("destroy", hashp);
+		hash_stats(__func__, hashp);
 
 		/*
 		 * Free everything by destroying the hash table's memory context.
@@ -898,19 +887,16 @@ hash_destroy(HTAB *hashp)
 }
 
 void
-hash_stats(const char *where, HTAB *hashp)
+hash_stats(const char *caller, HTAB *hashp)
 {
 #ifdef HASH_STATISTICS
-	fprintf(stderr, "%s: this HTAB -- accesses %ld collisions %ld\n",
-			where, hashp->hctl->accesses, hashp->hctl->collisions);
-
-	fprintf(stderr, "hash_stats: entries %ld keysize %ld maxp %u segmentcount %ld\n",
-			hash_get_num_entries(hashp), (long) hashp->hctl->keysize,
-			hashp->hctl->max_bucket, hashp->hctl->nsegs);
-	fprintf(stderr, "%s: total accesses %ld total collisions %ld\n",
-			where, hash_accesses, hash_collisions);
-	fprintf(stderr, "hash_stats: total expansions %ld\n",
-			hash_expansions);
+	HASHHDR    *hctl = hashp->hctl;
+
+	elog(DEBUG4,
+		 "hash_stats:  Caller: %s  Table Name: \"%s\"  Accesses: " UINT64_FORMAT "  Collisions: " UINT64_FORMAT "  Expansions: " UINT64_FORMAT "  Entries: %ld  Key Size: %zu  Max Bucket: %u  Segment Count: %ld",
+		 caller != NULL ? caller : "(unknown)", hashp->tabname, hctl->accesses,
+		 hctl->collisions, hctl->expansions, hash_get_num_entries(hashp),
+		 hctl->keysize, hctl->max_bucket, hctl->nsegs);
 #endif
 }
 
@@ -996,7 +982,6 @@ hash_search_with_hash_value(HTAB *hashp,
 	HashCompareFunc match;
 
 #ifdef HASH_STATISTICS
-	hash_accesses++;
 	hctl->accesses++;
 #endif
 
@@ -1040,7 +1025,6 @@ hash_search_with_hash_value(HTAB *hashp,
 		prevBucketPtr = &(currBucket->link);
 		currBucket = *prevBucketPtr;
 #ifdef HASH_STATISTICS
-		hash_collisions++;
 		hctl->collisions++;
 #endif
 	}
@@ -1176,7 +1160,6 @@ hash_update_hash_key(HTAB *hashp,
 #ifdef HASH_STATISTICS
 	HASHHDR    *hctl = hashp->hctl;
 
-	hash_accesses++;
 	hctl->accesses++;
 #endif
 
@@ -1230,7 +1213,6 @@ hash_update_hash_key(HTAB *hashp,
 		prevBucketPtr = &(currBucket->link);
 		currBucket = *prevBucketPtr;
 #ifdef HASH_STATISTICS
-		hash_collisions++;
 		hctl->collisions++;
 #endif
 	}
@@ -1586,7 +1568,7 @@ expand_table(HTAB *hashp)
 	Assert(!IS_PARTITIONED(hctl));
 
 #ifdef HASH_STATISTICS
-	hash_expansions++;
+	hctl->expansions++;
 #endif
 
 	new_bucket = hctl->max_bucket + 1;
diff --git a/src/include/utils/hsearch.h b/src/include/utils/hsearch.h
index 932cc4f34d9..80deb8e543e 100644
--- a/src/include/utils/hsearch.h
+++ b/src/include/utils/hsearch.h
@@ -132,7 +132,7 @@ typedef struct
 extern HTAB *hash_create(const char *tabname, long nelem,
 						 const HASHCTL *info, int flags);
 extern void hash_destroy(HTAB *hashp);
-extern void hash_stats(const char *where, HTAB *hashp);
+extern void hash_stats(const char *caller, HTAB *hashp);
 extern void *hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action,
 						 bool *foundPtr);
 extern uint32 get_hash_value(HTAB *hashp, const void *keyPtr);
