From a1e2ec7044feadd3209678b8c153dfd069ec2037 Mon Sep 17 00:00:00 2001 From: Tomohiro Date: Mon, 22 Mar 2021 14:24:39 +0900 Subject: [PATCH v6] GetNewOidWithIndex_log_output --- src/backend/catalog/catalog.c | 49 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/backend/catalog/catalog.c b/src/backend/catalog/catalog.c index e2ed80a..4afa979 100644 --- a/src/backend/catalog/catalog.c +++ b/src/backend/catalog/catalog.c @@ -48,6 +48,13 @@ #include "utils/syscache.h" /* + * Parameters to determine when to emit a warning in + * GetNewOidWithIndex() + */ +#define GETNEWOID_WARN_THRESHOLD 1000000 +#define GETNEWOID_WARN_MAX_INTERVAL 128000000 + +/* * IsSystemRelation * True iff the relation is either a system catalog or a toast table. * See IsCatalogRelation for the exact definition of a system catalog. @@ -318,6 +325,8 @@ GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn) SysScanDesc scan; ScanKeyData key; bool collides; + uint64 retries = 0; + uint64 retries_before_warn = GETNEWOID_WARN_THRESHOLD; /* Only system relations are supported */ Assert(IsSystemRelation(relation)); @@ -353,8 +362,48 @@ GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn) collides = HeapTupleIsValid(systable_getnext(scan)); systable_endscan(scan); + + /* + * Warn users that we iterate more than GETNEWOID_WARN_THRESHOLD but + * have not yet found OID unused in the relation. Then repeat warning + * with exponentially increasing intervals until we iterate more than + * GETNEWOID_WARN_MAX_INTERVAL. Finally repeat warning every + * GETNEWOID_WARN_MAX_INTERVAL unless an unused OID is found. This + * logic is necessary not to fill up the server log with the similar + * messages. + */ + if (retries >= retries_before_warn) + { + ereport(WARNING, + (errmsg("still finding an unused OID within relation \"%s\"", + RelationGetRelationName(relation)), + errdetail("OID candidates were checked \"%llu\" times, but no unused OID is yet found.", + (unsigned long long) retries))); + + /* + * Double the number of retries to do before warning next until it + * reaches GETNEWOID_WARN_MAX_INTERVAL. + */ + if (retries_before_warn * 2 <= GETNEWOID_WARN_MAX_INTERVAL) + retries_before_warn *= 2; + else + retries_before_warn += GETNEWOID_WARN_MAX_INTERVAL; + } + + retries++; } while (collides); + /* + * If at least one warning is emitted, also warn the completion of OID + * assignment. + */ + if (retries > GETNEWOID_WARN_THRESHOLD) + { + ereport(WARNING, + (errmsg("new OID has been assigned in relation \"%s\" after \"%llu\" retries", + RelationGetRelationName(relation), (unsigned long long) retries))); + } + return newOid; } -- 1.8.3.1