diff --git a/src/backend/executor/nodeGatherMerge.c b/src/backend/executor/nodeGatherMerge.c
index ce19e0837a..6ed6aea7af 100644
--- a/src/backend/executor/nodeGatherMerge.c
+++ b/src/backend/executor/nodeGatherMerge.c
@@ -422,8 +422,7 @@ gather_merge_setup(GatherMergeState *gm_state)
 	/* Allocate the resources for the merge */
 	gm_state->gm_heap = binaryheap_allocate(nreaders + 1,
 											heap_compare_slots,
-											false,
-											gm_state);
+											gm_state, NULL);
 }
 
 /*
diff --git a/src/backend/executor/nodeMergeAppend.c b/src/backend/executor/nodeMergeAppend.c
index 3efebd537f..7493421331 100644
--- a/src/backend/executor/nodeMergeAppend.c
+++ b/src/backend/executor/nodeMergeAppend.c
@@ -125,8 +125,8 @@ ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags)
 	mergestate->ms_nplans = nplans;
 
 	mergestate->ms_slots = (TupleTableSlot **) palloc0(sizeof(TupleTableSlot *) * nplans);
-	mergestate->ms_heap = binaryheap_allocate(nplans, heap_compare_slots, false,
-											  mergestate);
+	mergestate->ms_heap = binaryheap_allocate(nplans, heap_compare_slots,
+											  mergestate, NULL);
 
 	/*
 	 * Miscellaneous initialization
diff --git a/src/backend/postmaster/pgarch.c b/src/backend/postmaster/pgarch.c
index 251f75e91d..fe2091498f 100644
--- a/src/backend/postmaster/pgarch.c
+++ b/src/backend/postmaster/pgarch.c
@@ -258,7 +258,7 @@ PgArchiverMain(char *startup_data, size_t startup_data_len)
 
 	/* Initialize our max-heap for prioritizing files to archive. */
 	arch_files->arch_heap = binaryheap_allocate(NUM_FILES_PER_DIRECTORY_SCAN,
-												ready_file_comparator, false,
+												ready_file_comparator, NULL,
 												NULL);
 
 	/* Initialize our memory context. */
diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c
index 5cf28d4df4..9940c14d48 100644
--- a/src/backend/replication/logical/reorderbuffer.c
+++ b/src/backend/replication/logical/reorderbuffer.c
@@ -106,6 +106,7 @@
 #include "access/xact.h"
 #include "access/xlog_internal.h"
 #include "catalog/catalog.h"
+#include "common/hashfn_unstable.h"
 #include "common/int.h"
 #include "lib/binaryheap.h"
 #include "miscadmin.h"
@@ -293,6 +294,7 @@ static void ReorderBufferSerializedPath(char *path, ReplicationSlot *slot,
 static void ReorderBufferBuildMaxHeap(ReorderBuffer *rb);
 static void ReorderBufferMaybeResetMaxHeap(ReorderBuffer *rb);
 static int	ReorderBufferTXNSizeCompare(Datum a, Datum b, void *arg);
+static uint32 ReorderBufferXidHash(Datum d);
 
 static void ReorderBufferFreeSnap(ReorderBuffer *rb, Snapshot snap);
 static Snapshot ReorderBufferCopySnap(ReorderBuffer *rb, Snapshot orig_snap,
@@ -399,7 +401,7 @@ ReorderBufferAllocate(void)
 	 */
 	buffer->txn_heap = binaryheap_allocate(MAX_HEAP_TXN_COUNT_THRESHOLD * 2,
 										   ReorderBufferTXNSizeCompare,
-										   true, NULL);
+										   NULL, ReorderBufferXidHash);
 
 	buffer->spillTxns = 0;
 	buffer->spillCount = 0;
@@ -1340,8 +1342,7 @@ ReorderBufferIterTXNInit(ReorderBuffer *rb, ReorderBufferTXN *txn,
 	/* allocate heap */
 	state->heap = binaryheap_allocate(state->nr_txns,
 									  ReorderBufferIterCompare,
-									  false,
-									  state);
+									  state, NULL);
 
 	/* Now that the state fields are initialized, it is safe to return it. */
 	*iter_state = state;
@@ -3552,6 +3553,14 @@ ReorderBufferSerializeReserve(ReorderBuffer *rb, Size sz)
 	}
 }
 
+/* Hash function for rb->txn_heap */
+static uint32
+ReorderBufferXidHash(Datum d)
+{
+	ReorderBufferTXN *txn = (ReorderBufferTXN *) DatumGetPointer(d);
+
+	return fasthash32((const char *) &(txn->xid), sizeof(TransactionId), 0);
+}
 
 /* Compare two transactions by size */
 static int
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 44836751b7..5c80ea4370 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -3014,8 +3014,7 @@ BufferSync(int flags)
 	 */
 	ts_heap = binaryheap_allocate(num_spaces,
 								  ts_ckpt_progress_comparator,
-								  false,
-								  NULL);
+								  NULL, NULL);
 
 	for (i = 0; i < num_spaces; i++)
 	{
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index 465e9ce777..aed7ca8786 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -4200,8 +4200,7 @@ restore_toc_entries_parallel(ArchiveHandle *AH, ParallelState *pstate,
 	/* Set up ready_heap with enough room for all known TocEntrys */
 	ready_heap = binaryheap_allocate(AH->tocCount,
 									 TocEntrySizeCompareBinaryheap,
-									 false,
-									 NULL);
+									 NULL, NULL);
 
 	/*
 	 * The pending_list contains all items that we need to restore.  Move all
diff --git a/src/bin/pg_dump/pg_dump_sort.c b/src/bin/pg_dump/pg_dump_sort.c
index 7362f7c961..9004704733 100644
--- a/src/bin/pg_dump/pg_dump_sort.c
+++ b/src/bin/pg_dump/pg_dump_sort.c
@@ -405,7 +405,7 @@ TopoSort(DumpableObject **objs,
 		return true;
 
 	/* Create workspace for the above-described heap */
-	pendingHeap = binaryheap_allocate(numObjs, int_cmp, false, NULL);
+	pendingHeap = binaryheap_allocate(numObjs, int_cmp, NULL, NULL);
 
 	/*
 	 * Scan the constraints, and for each item in the input, generate a count
diff --git a/src/common/binaryheap.c b/src/common/binaryheap.c
index c20ed50acc..e077905bd1 100644
--- a/src/common/binaryheap.c
+++ b/src/common/binaryheap.c
@@ -25,6 +25,12 @@
 #include "common/hashfn.h"
 #include "lib/binaryheap.h"
 
+/*
+ * Need to be declared before the hash table code generation as it is
+ * referenced during the code generation.
+ */
+static inline uint32 binaryheap_hash(bh_nodeidx_hash *tab, bh_node_type key);
+
 /*
  * Define parameters for hash table code generation. The interface is *also*
  * declared in binaryheap.h (to generate the types, which are externally
@@ -34,8 +40,7 @@
 #define SH_ELEMENT_TYPE bh_nodeidx_entry
 #define SH_KEY_TYPE bh_node_type
 #define SH_KEY key
-#define SH_HASH_KEY(tb, key) \
-	hash_bytes((const unsigned char *) &key, sizeof(bh_node_type))
+#define SH_HASH_KEY(tb, key) binaryheap_hash(tb, key)
 #define SH_EQUAL(tb, a, b) (memcmp(&a, &b, sizeof(bh_node_type)) == 0)
 #define SH_SCOPE extern
 #ifdef FRONTEND
@@ -63,7 +68,7 @@ static void sift_up(binaryheap *heap, int node_off);
  */
 binaryheap *
 binaryheap_allocate(int num_nodes, binaryheap_comparator compare,
-					bool indexed, void *arg)
+					void *arg, binaryheap_hashfunc hashfunc)
 {
 	binaryheap *heap;
 
@@ -77,13 +82,15 @@ binaryheap_allocate(int num_nodes, binaryheap_comparator compare,
 	heap->bh_nodes = (bh_node_type *) palloc(sizeof(bh_node_type) * num_nodes);
 	heap->bh_nodeidx = NULL;
 
-	if (indexed)
+	if (hashfunc != NULL)
 	{
+		void *private_data = (void *) hashfunc;
+
 #ifdef FRONTEND
-		heap->bh_nodeidx = bh_nodeidx_create(num_nodes, NULL);
+		heap->bh_nodeidx = bh_nodeidx_create(num_nodes, private_data);
 #else
 		heap->bh_nodeidx = bh_nodeidx_create(CurrentMemoryContext, num_nodes,
-											 NULL);
+											 private_data);
 #endif
 	}
 
@@ -220,6 +227,18 @@ replace_node(binaryheap *heap, int index, bh_node_type new_node)
 	Assert(!binaryheap_indexed(heap) || found);
 }
 
+/*
+ * Return the hash value of the given key using the caller-specified hash
+ * function.
+ */
+static inline uint32
+binaryheap_hash(bh_nodeidx_hash *tab, bh_node_type key)
+{
+	binaryheap_hashfunc hashfunc = tab->private_data;
+
+	return hashfunc(key);
+}
+
 /*
  * binaryheap_add_unordered
  *
diff --git a/src/include/lib/binaryheap.h b/src/include/lib/binaryheap.h
index 4c1a1bb274..91537da291 100644
--- a/src/include/lib/binaryheap.h
+++ b/src/include/lib/binaryheap.h
@@ -29,6 +29,12 @@ typedef Datum bh_node_type;
  */
 typedef int (*binaryheap_comparator) (bh_node_type a, bh_node_type b, void *arg);
 
+/*
+ * The hash function must returns a hash value of the given key. The
+ * returned hash value is used as the key of bh_nodeidx hash table.
+ */
+typedef uint32 (*binaryheap_hashfunc) (bh_node_type key);
+
 /*
  * Struct for a hash table element to store the node's index in the bh_nodes
  * array.
@@ -81,7 +87,8 @@ typedef struct binaryheap
 
 extern binaryheap *binaryheap_allocate(int num_nodes,
 									   binaryheap_comparator compare,
-									   bool indexed, void *arg);
+									   void *arg,
+									   binaryheap_hashfunc hashfunc);
 extern void binaryheap_reset(binaryheap *heap);
 extern void binaryheap_free(binaryheap *heap);
 extern void binaryheap_add_unordered(binaryheap *heap, bh_node_type d);
