v4-0001-GetNewOidWithIndex_log_output.patch

application/octet-stream

Filename: v4-0001-GetNewOidWithIndex_log_output.patch
Type: application/octet-stream
Part: 0
Message: Re: BUG #16722: PG hanging on COPY when table has close to 2^32 toasts in the table.

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: format-patch
Series: patch v4-0001
Subject: GetNewOidWithIndex_log_output
File+
src/backend/catalog/catalog.c 41 0
From 73199ecd55a838969297cb0a46acf764a32cf319 Mon Sep 17 00:00:00 2001
From: Tomohiro <hiramit.tm@gmail.com>
Date: Wed, 17 Mar 2021 13:31:58 +0900
Subject: [PATCH v4] GetNewOidWithIndex_log_output

---
 src/backend/catalog/catalog.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/src/backend/catalog/catalog.c b/src/backend/catalog/catalog.c
index e2ed80a..f71da30 100644
--- a/src/backend/catalog/catalog.c
+++ b/src/backend/catalog/catalog.c
@@ -47,6 +47,10 @@
 #include "utils/snapmgr.h"
 #include "utils/syscache.h"
 
+/* Parameters for loop count notification in GetNewOidWithIndex() function */
+#define GETNEWOID_NOTIFY_MINVAL 1000000
+#define GETNEWOID_NOTIFY_MAXVAL 100000000
+
 /*
  * IsSystemRelation
  *		True iff the relation is either a system catalog or a toast table.
@@ -318,6 +322,8 @@ GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
 	SysScanDesc scan;
 	ScanKeyData key;
 	bool		collides;
+	uint64		retry_count;
+	uint64		next_notify;
 
 	/* Only system relations are supported */
 	Assert(IsSystemRelation(relation));
@@ -335,6 +341,8 @@ GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
 	Assert(!IsBinaryUpgrade || RelationGetRelid(relation) != TypeRelationId);
 
 	/* Generate new OIDs until we find one not in the table */
+	retry_count = 0;
+	next_notify = GETNEWOID_NOTIFY_MINVAL; /* next notify timing */
 	do
 	{
 		CHECK_FOR_INTERRUPTS();
@@ -353,8 +361,41 @@ GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
 		collides = HeapTupleIsValid(systable_getnext(scan));
 
 		systable_endscan(scan);
+
+		/*
+ 		 * Notify users when we iterate more than expected. Repeated notifications
+ 		 * are logged with exponentially increasing intervals so that we don't 
+ 		 * fill up the server log with the same messages.
+ 		 */
+		if (retry_count == next_notify)
+		{
+			ereport(LOG,
+				(errmsg("still finding an unused OID within relation \"%s\"", 
+					RelationGetRelationName(relation)),
+				errdetail("\"%llu\" OID candidates were checked, but no unused OID is yet found.",
+					(unsigned long long) retry_count)));
+
+			if (next_notify*2 <= GETNEWOID_NOTIFY_MAXVAL)
+			{
+				next_notify *= 2; /* double it for the next notification */
+			}
+			else
+			{
+				next_notify += GETNEWOID_NOTIFY_MAXVAL;
+			}
+		}
+		retry_count++;
+
 	} while (collides);
 
+	/* if the retry log is output, the OID generation completion log is also output */
+	if (retry_count >= GETNEWOID_NOTIFY_MINVAL)
+	{
+		ereport(LOG,
+			(errmsg("the new OID has been assigned in relation \"%s\" after \"%llu\" retries",
+				RelationGetRelationName(relation), (unsigned long long) retry_count)));
+	}
+
 	return newOid;
 }
 
-- 
1.8.3.1