From be82f60f1a8097d042674678e177e6c28a4ebdfe Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Sun, 23 Oct 2022 14:41:46 -0700
Subject: [PATCH v1 12/12] bufmgr: debug: Add PrintBuffer[Desc]

Useful for development. Perhaps we should polish these and keep them?
---
 src/include/storage/buf_internals.h |  3 ++
 src/backend/storage/buffer/bufmgr.c | 49 +++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+)

diff --git a/src/include/storage/buf_internals.h b/src/include/storage/buf_internals.h
index 34b28eea906..337e94e4b4e 100644
--- a/src/include/storage/buf_internals.h
+++ b/src/include/storage/buf_internals.h
@@ -390,6 +390,9 @@ extern void WritebackContextInit(WritebackContext *context, int *max_pending);
 extern void IssuePendingWritebacks(WritebackContext *context);
 extern void ScheduleBufferTagForWriteback(WritebackContext *context, BufferTag *tag);
 
+extern void PrintBuffer(Buffer buffer, const char *msg);
+extern void PrintBufferDesc(BufferDesc *buf_hdr, const char *msg);
+
 /* freelist.c */
 extern BufferDesc *StrategyGetBuffer(BufferAccessStrategy strategy,
 									 uint32 *buf_state);
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 196b7d1ff25..a77a1205cf8 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -3723,6 +3723,55 @@ DropDatabaseBuffers(Oid dbid)
  *		use only.
  * -----------------------------------------------------------------
  */
+
+#include "utils/memutils.h"
+
+void
+PrintBufferDesc(BufferDesc *buf_hdr, const char *msg)
+{
+	Buffer		buffer = BufferDescriptorGetBuffer(buf_hdr);
+	uint32		buf_state = pg_atomic_read_u32(&buf_hdr->state);
+	char	   *path = "";
+	BlockNumber blockno = InvalidBlockNumber;
+
+	CurrentMemoryContext->allowInCritSection = true;
+	if (buf_state & BM_TAG_VALID)
+	{
+		path = relpathbackend(BufTagGetRelFileLocator(&buf_hdr->tag),
+							  InvalidBackendId, BufTagGetForkNum(&buf_hdr->tag));
+		blockno = buf_hdr->tag.blockNum;
+	}
+
+	fprintf(stderr, "%d: [%u] msg: %s, rel: %s, block %u: refcount: %u / %u, usagecount: %u, flags:%s%s%s%s%s%s%s%s%s%s\n",
+			MyProcPid,
+			buffer,
+			msg,
+			path,
+			blockno,
+			BUF_STATE_GET_REFCOUNT(buf_state),
+			GetPrivateRefCount(buffer),
+			BUF_STATE_GET_USAGECOUNT(buf_state),
+			buf_state & BM_LOCKED ? " BM_LOCKED" : "",
+			buf_state & BM_DIRTY ? " BM_DIRTY" : "",
+			buf_state & BM_VALID ? " BM_VALID" : "",
+			buf_state & BM_TAG_VALID ? " BM_TAG_VALID" : "",
+			buf_state & BM_IO_IN_PROGRESS ? " BM_IO_IN_PROGRESS" : "",
+			buf_state & BM_IO_ERROR ? " BM_IO_ERROR" : "",
+			buf_state & BM_JUST_DIRTIED ? " BM_JUST_DIRTIED" : "",
+			buf_state & BM_PIN_COUNT_WAITER ? " BM_PIN_COUNT_WAITER" : "",
+			buf_state & BM_CHECKPOINT_NEEDED ? " BM_CHECKPOINT_NEEDED" : "",
+			buf_state & BM_PERMANENT ? " BM_PERMANENT" : ""
+		);
+}
+
+void
+PrintBuffer(Buffer buffer, const char *msg)
+{
+	BufferDesc *buf_hdr = GetBufferDescriptor(buffer - 1);
+
+	PrintBufferDesc(buf_hdr, msg);
+}
+
 #ifdef NOT_USED
 void
 PrintBufferDescs(void)
-- 
2.38.0

