agora inbox for [email protected]  
help / color / mirror / Atom feed
From: Antonin Houska <[email protected]>
Subject: [PATCH 13/17] Make database OID constant for postgres database.
Date: Fri, 5 Jul 2019 16:24:02 +0200

Later in the patch series we teach pg_upgrade to preserve OIDs of
relfilenodes, tablespaces and databases. To ensure the last, we need to make
the OID of the "postgres" database constant because pg_upgrade can drop it in
the new cluster and create it again.
---
 src/backend/commands/dbcommands.c | 21 +++++++++++++++++----
 src/include/catalog/pg_database.h | 14 ++++++++++++++
 2 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 7ea783d096..4ffb6dccf4 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -513,11 +513,24 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
 	 */
 	pg_database_rel = table_open(DatabaseRelationId, RowExclusiveLock);
 
-	do
+	/* The "postgres" database has fixed OID. */
+	if (strcmp(dbname, "postgres") == 0)
 	{
-		dboid = GetNewOidWithIndex(pg_database_rel, DatabaseOidIndexId,
-								   Anum_pg_database_oid);
-	} while (check_db_file_conflict(dboid));
+		dboid = PostgresDbOid;
+
+		if (check_db_file_conflict(dboid))
+			ereport(ERROR,
+					(errcode(ERRCODE_DUPLICATE_DATABASE),
+					 errmsg("database \"%s\" already exists", dbname)));
+	}
+	else
+	{
+		do
+		{
+			dboid = GetNewOidWithIndex(pg_database_rel, DatabaseOidIndexId,
+									   Anum_pg_database_oid);
+		} while (check_db_file_conflict(dboid));
+	}
 
 	/*
 	 * Insert a new tuple into pg_database.  This establishes our ownership of
diff --git a/src/include/catalog/pg_database.h b/src/include/catalog/pg_database.h
index 06fea45f53..ebb17e3051 100644
--- a/src/include/catalog/pg_database.h
+++ b/src/include/catalog/pg_database.h
@@ -80,4 +80,18 @@ CATALOG(pg_database,1262,DatabaseRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID
  */
 typedef FormData_pg_database *Form_pg_database;
 
+/*
+ * The "postgres" database has reserved pg_database(oid) because initially
+ * it's below FirstNormalObjectId, and thus pg_upgrade cannot guarantee that
+ * the same OID will be assigned in the new cluster (unlike TemplateDbOid,
+ * which has always OID=1). Since database OID is used to construct encryption
+ * initialization vector (tweak), different OID would break data decryption in
+ * the new cluster.
+ *
+ * The easiest way to avoid collision with any system OID is to use the
+ * maximum system OID. initdb won't reach this value and GetNewObjectId() will
+ * always skip that.
+ */
+#define PostgresDbOid	(FirstNormalObjectId - 1)
+
 #endif							/* PG_DATABASE_H */
-- 
2.13.7


--=-=-=
Content-Type: text/x-diff
Content-Disposition: attachment;
 filename=v04-0014-Teach-pg_upgrade-to-preserve-OIDs-of-relfilenode-dat.patch



view thread (3+ messages)  latest in thread

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected]
  Subject: Re: [PATCH 13/17] Make database OID constant for postgres database.
  In-Reply-To: <no-message-id-1881969@localhost>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox