From e93afd4adb36676298ef0ceb48721e4f1d1ce8b0 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Mon, 15 Jul 2019 21:26:41 +1200
Subject: [PATCH 2/3] Add smgrid column to pg_buffercache.

Buffer tags now include an SMGR selector.  Show it as a new column in the
pg_buffercache extension.

Author: Thomas Munro
Reviewed-by: Robert Haas
Discussion: https://postgr.es/m/CA%2BhUKG%2BOZqOiOuDm5tC5DyQZtJ3FH4%2BFSVMqtdC4P1atpJ%2Bqhg%40mail.gmail.com
Discussion: https://postgr.es/m/CA%2BhUKG%2BDE0mmiBZMtZyvwWtgv1sZCniSVhXYsXkvJ_Wo%2B83vvw%40mail.gmail.com
---
 contrib/pg_buffercache/Makefile               |  4 +-
 .../pg_buffercache/pg_buffercache--1.2.sql    | 21 ----------
 .../pg_buffercache--1.3--1.4.sql              | 36 ++++++++++++++++
 .../pg_buffercache/pg_buffercache--1.4.sql    | 41 +++++++++++++++++++
 contrib/pg_buffercache/pg_buffercache.control |  2 +-
 contrib/pg_buffercache/pg_buffercache_pages.c | 15 +++++--
 doc/src/sgml/pgbuffercache.sgml               |  7 ++++
 7 files changed, 100 insertions(+), 26 deletions(-)
 delete mode 100644 contrib/pg_buffercache/pg_buffercache--1.2.sql
 create mode 100644 contrib/pg_buffercache/pg_buffercache--1.3--1.4.sql
 create mode 100644 contrib/pg_buffercache/pg_buffercache--1.4.sql

diff --git a/contrib/pg_buffercache/Makefile b/contrib/pg_buffercache/Makefile
index 18f7a874524..d76ac243d3e 100644
--- a/contrib/pg_buffercache/Makefile
+++ b/contrib/pg_buffercache/Makefile
@@ -4,7 +4,9 @@ MODULE_big = pg_buffercache
 OBJS = pg_buffercache_pages.o $(WIN32RES)
 
 EXTENSION = pg_buffercache
-DATA = pg_buffercache--1.2.sql pg_buffercache--1.2--1.3.sql \
+DATA = \
+	pg_buffercache--1.4.sql \
+	pg_buffercache--1.3--1.4.sql pg_buffercache--1.2--1.3.sql \
 	pg_buffercache--1.1--1.2.sql pg_buffercache--1.0--1.1.sql \
 	pg_buffercache--unpackaged--1.0.sql
 PGFILEDESC = "pg_buffercache - monitoring of shared buffer cache in real-time"
diff --git a/contrib/pg_buffercache/pg_buffercache--1.2.sql b/contrib/pg_buffercache/pg_buffercache--1.2.sql
deleted file mode 100644
index 6ee5d8435bd..00000000000
--- a/contrib/pg_buffercache/pg_buffercache--1.2.sql
+++ /dev/null
@@ -1,21 +0,0 @@
-/* contrib/pg_buffercache/pg_buffercache--1.2.sql */
-
--- complain if script is sourced in psql, rather than via CREATE EXTENSION
-\echo Use "CREATE EXTENSION pg_buffercache" to load this file. \quit
-
--- Register the function.
-CREATE FUNCTION pg_buffercache_pages()
-RETURNS SETOF RECORD
-AS 'MODULE_PATHNAME', 'pg_buffercache_pages'
-LANGUAGE C PARALLEL SAFE;
-
--- Create a view for convenient access.
-CREATE VIEW pg_buffercache AS
-	SELECT P.* FROM pg_buffercache_pages() AS P
-	(bufferid integer, relfilenode oid, reltablespace oid, reldatabase oid,
-	 relforknumber int2, relblocknumber int8, isdirty bool, usagecount int2,
-	 pinning_backends int4);
-
--- Don't want these to be available to public.
-REVOKE ALL ON FUNCTION pg_buffercache_pages() FROM PUBLIC;
-REVOKE ALL ON pg_buffercache FROM PUBLIC;
diff --git a/contrib/pg_buffercache/pg_buffercache--1.3--1.4.sql b/contrib/pg_buffercache/pg_buffercache--1.3--1.4.sql
new file mode 100644
index 00000000000..ab6d20a5ccf
--- /dev/null
+++ b/contrib/pg_buffercache/pg_buffercache--1.3--1.4.sql
@@ -0,0 +1,36 @@
+/* contrib/pg_buffercache/pg_buffercache--1.3--1.4.sql */
+
+-- complain if script is sourced in psql, rather than via ALTER EXTENSION
+\echo Use "ALTER EXTENSION pg_buffercache UPDATE TO '1.4'" to load this file. \quit
+
+DROP VIEW pg_buffercache;
+
+CREATE VIEW pg_buffercache AS
+        SELECT bufferid,
+               smgrid,
+               relfilenode,
+               reltablespace,
+               reldatabase,
+               relforknumber,
+               relblocknumber,
+               isdirty,
+               usagecount,
+               pinning_backends
+          FROM pg_buffercache_pages() AS P(
+               bufferid integer,
+               relfilenode oid,
+               reltablespace oid,
+               reldatabase oid,
+               relforknumber int2,
+               relblocknumber int8,
+               isdirty bool,
+               usagecount int2,
+               pinning_backends int4,
+               smgrid int2);
+
+-- Don't want these to be available to public.
+REVOKE ALL ON FUNCTION pg_buffercache_pages() FROM PUBLIC;
+REVOKE ALL ON pg_buffercache FROM PUBLIC;
+
+GRANT EXECUTE ON FUNCTION pg_buffercache_pages() TO pg_monitor;
+GRANT SELECT ON pg_buffercache TO pg_monitor;
diff --git a/contrib/pg_buffercache/pg_buffercache--1.4.sql b/contrib/pg_buffercache/pg_buffercache--1.4.sql
new file mode 100644
index 00000000000..9ae167abf0e
--- /dev/null
+++ b/contrib/pg_buffercache/pg_buffercache--1.4.sql
@@ -0,0 +1,41 @@
+/* contrib/pg_buffercache/pg_buffercache--1.4.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION pg_buffercache" to load this file. \quit
+
+-- Register the function.
+CREATE FUNCTION pg_buffercache_pages()
+RETURNS SETOF RECORD
+AS 'MODULE_PATHNAME', 'pg_buffercache_pages'
+LANGUAGE C PARALLEL SAFE;
+
+-- Create a view for convenient access.
+CREATE VIEW pg_buffercache AS
+	SELECT bufferid,
+	       smgrid,
+	       relfilenode,
+	       reltablespace,
+	       reldatabase,
+	       relforknumber,
+	       relblocknumber,
+	       isdirty,
+	       usagecount,
+	       pinning_backends
+	  FROM pg_buffercache_pages() AS P(
+	       bufferid integer,
+	       relfilenode oid,
+	       reltablespace oid,
+	       reldatabase oid,
+	       relforknumber int2,
+	       relblocknumber int8,
+	       isdirty bool,
+	       usagecount int2,
+	       pinning_backends int4,
+	       smgrid int2);
+
+-- Don't want these to be available to public.
+REVOKE ALL ON FUNCTION pg_buffercache_pages() FROM PUBLIC;
+REVOKE ALL ON pg_buffercache FROM PUBLIC;
+
+GRANT EXECUTE ON FUNCTION pg_buffercache_pages() TO pg_monitor;
+GRANT SELECT ON pg_buffercache TO pg_monitor;
diff --git a/contrib/pg_buffercache/pg_buffercache.control b/contrib/pg_buffercache/pg_buffercache.control
index 8c060ae9abf..a82ae5f9bb5 100644
--- a/contrib/pg_buffercache/pg_buffercache.control
+++ b/contrib/pg_buffercache/pg_buffercache.control
@@ -1,5 +1,5 @@
 # pg_buffercache extension
 comment = 'examine the shared buffer cache'
-default_version = '1.3'
+default_version = '1.4'
 module_pathname = '$libdir/pg_buffercache'
 relocatable = true
diff --git a/contrib/pg_buffercache/pg_buffercache_pages.c b/contrib/pg_buffercache/pg_buffercache_pages.c
index 1bd579fcbb0..2754c1e40e9 100644
--- a/contrib/pg_buffercache/pg_buffercache_pages.c
+++ b/contrib/pg_buffercache/pg_buffercache_pages.c
@@ -16,7 +16,7 @@
 
 
 #define NUM_BUFFERCACHE_PAGES_MIN_ELEM	8
-#define NUM_BUFFERCACHE_PAGES_ELEM	9
+#define NUM_BUFFERCACHE_PAGES_ELEM	10
 
 PG_MODULE_MAGIC;
 
@@ -25,6 +25,7 @@ PG_MODULE_MAGIC;
  */
 typedef struct
 {
+	SmgrId		smgrid;
 	uint32		bufferid;
 	Oid			relfilenode;
 	Oid			reltablespace;
@@ -116,10 +117,12 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
 						   BOOLOID, -1, 0);
 		TupleDescInitEntry(tupledesc, (AttrNumber) 8, "usage_count",
 						   INT2OID, -1, 0);
-
-		if (expected_tupledesc->natts == NUM_BUFFERCACHE_PAGES_ELEM)
+		if (expected_tupledesc->natts >= 9)
 			TupleDescInitEntry(tupledesc, (AttrNumber) 9, "pinning_backends",
 							   INT4OID, -1, 0);
+		if (expected_tupledesc->natts >= 10)
+			TupleDescInitEntry(tupledesc, (AttrNumber) 10, "smgrid",
+							   INT2OID, -1, 0);
 
 		fctx->tupdesc = BlessTupleDesc(tupledesc);
 
@@ -153,6 +156,7 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
 			buf_state = LockBufHdr(bufHdr);
 
 			fctx->record[i].bufferid = BufferDescriptorGetBuffer(bufHdr);
+			fctx->record[i].smgrid = bufHdr->tag.smgrid;
 			fctx->record[i].relfilenode = bufHdr->tag.rnode.relNode;
 			fctx->record[i].reltablespace = bufHdr->tag.rnode.spcNode;
 			fctx->record[i].reldatabase = bufHdr->tag.rnode.dbNode;
@@ -206,6 +210,8 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
 			nulls[7] = true;
 			/* unused for v1.0 callers, but the array is always long enough */
 			nulls[8] = true;
+			/* unused for < v1.4 callers, but the array is always long enough */
+			nulls[9] = true;
 		}
 		else
 		{
@@ -226,6 +232,9 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
 			/* unused for v1.0 callers, but the array is always long enough */
 			values[8] = Int32GetDatum(fctx->record[i].pinning_backends);
 			nulls[8] = false;
+			/* unused for < v1.4 callers, but the array is always long enough */
+			values[9] = Int16GetDatum(fctx->record[i].smgrid);
+			nulls[9] = false;
 		}
 
 		/* Build and return the tuple. */
diff --git a/doc/src/sgml/pgbuffercache.sgml b/doc/src/sgml/pgbuffercache.sgml
index faf5a3115dc..a0a7be32b4b 100644
--- a/doc/src/sgml/pgbuffercache.sgml
+++ b/doc/src/sgml/pgbuffercache.sgml
@@ -57,6 +57,13 @@
       <entry>ID, in the range 1..<varname>shared_buffers</varname></entry>
      </row>
 
+     <row>
+      <entry><structfield>smgrid</structfield></entry>
+      <entry><type>smallint</type></entry>
+      <entry></entry>
+      <entry>Block storage manager ID.  0 for regular relation data.</entry>
+     </row>
+
      <row>
       <entry><structfield>relfilenode</structfield></entry>
       <entry><type>oid</type></entry>
-- 
2.21.0

