pgstat-mydatabase-fix-prototype.diff
text/x-diff
Filename: pgstat-mydatabase-fix-prototype.diff
Type: text/x-diff
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/utils/activity/pgstat_database.c | 14 | 0 |
| src/backend/utils/init/postinit.c | 44 | 47 |
diff --git i/src/backend/utils/activity/pgstat_database.c w/src/backend/utils/activity/pgstat_database.c
index 7149f22f729..3efcc9bb7c3 100644
--- i/src/backend/utils/activity/pgstat_database.c
+++ w/src/backend/utils/activity/pgstat_database.c
@@ -271,6 +271,14 @@ pgstat_update_dbstats(TimestampTz ts)
{
PgStat_StatDBEntry *dbentry;
+ /*
+ * If we haven't connected to a database yet, don't attribute time to
+ * "shared state" (InvalidOid is used to track stats for shared relations
+ * etc).
+ */
+ if (!OidIsValid(MyDatabaseId))
+ return;
+
dbentry = pgstat_prep_database_pending(MyDatabaseId);
/*
@@ -327,6 +335,12 @@ pgstat_prep_database_pending(Oid dboid)
{
PgStat_EntryRef *entry_ref;
+ /*
+ * Shouldn't report stats on database objects before having connected to
+ * database.
+ */
+ Assert(!OidIsValid(dboid) || OidIsValid(MyDatabaseId));
+
entry_ref = pgstat_prep_pending_entry(PGSTAT_KIND_DATABASE, dboid, InvalidOid,
NULL);
diff --git i/src/backend/utils/init/postinit.c w/src/backend/utils/init/postinit.c
index 561bd13ed24..a40f70503a4 100644
--- i/src/backend/utils/init/postinit.c
+++ w/src/backend/utils/init/postinit.c
@@ -1006,7 +1006,7 @@ InitPostgres(const char *in_dbname, Oid dboid,
*/
if (bootstrap)
{
- MyDatabaseId = Template1DbOid;
+ dboid = Template1DbOid;
MyDatabaseTableSpace = DEFAULTTABLESPACE_OID;
}
else if (in_dbname != NULL)
@@ -1020,32 +1020,9 @@ InitPostgres(const char *in_dbname, Oid dboid,
(errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("database \"%s\" does not exist", in_dbname)));
dbform = (Form_pg_database) GETSTRUCT(tuple);
- MyDatabaseId = dbform->oid;
- MyDatabaseTableSpace = dbform->dattablespace;
- /* take database name from the caller, just for paranoia */
- strlcpy(dbname, in_dbname, sizeof(dbname));
+ dboid = dbform->oid;
}
- else if (OidIsValid(dboid))
- {
- /* caller specified database by OID */
- HeapTuple tuple;
- Form_pg_database dbform;
-
- tuple = GetDatabaseTupleByOid(dboid);
- if (!HeapTupleIsValid(tuple))
- ereport(FATAL,
- (errcode(ERRCODE_UNDEFINED_DATABASE),
- errmsg("database %u does not exist", dboid)));
- dbform = (Form_pg_database) GETSTRUCT(tuple);
- MyDatabaseId = dbform->oid;
- MyDatabaseTableSpace = dbform->dattablespace;
- Assert(MyDatabaseId == dboid);
- strlcpy(dbname, NameStr(dbform->datname), sizeof(dbname));
- /* pass the database name back to the caller */
- if (out_dbname)
- strcpy(out_dbname, dbname);
- }
- else
+ else if (!OidIsValid(dboid))
{
/*
* If this is a background worker not bound to any particular
@@ -1083,8 +1060,47 @@ InitPostgres(const char *in_dbname, Oid dboid,
* CREATE DATABASE.
*/
if (!bootstrap)
- LockSharedObject(DatabaseRelationId, MyDatabaseId, 0,
- RowExclusiveLock);
+ LockSharedObject(DatabaseRelationId, dboid, 0, RowExclusiveLock);
+
+ /*
+ * Recheck pg_database to make sure the target database hasn't gone away.
+ * If there was a concurrent DROP DATABASE, this ensures we will die
+ * cleanly without creating a mess.
+ */
+ if (!bootstrap)
+ {
+ HeapTuple tuple;
+ Form_pg_database dbform;
+
+ tuple = GetDatabaseTupleByOid(dboid);
+ if (HeapTupleIsValid(tuple))
+ dbform = (Form_pg_database) GETSTRUCT(tuple);
+
+ if (!HeapTupleIsValid(tuple) ||
+ (in_dbname && namestrcmp(&dbform->datname, in_dbname)))
+ {
+ if (in_dbname)
+ ereport(PANIC,
+ (errcode(ERRCODE_UNDEFINED_DATABASE),
+ errmsg("database \"%s\" does not exist", in_dbname),
+ errdetail("It seems to have just been dropped or renamed.")));
+ else
+ ereport(FATAL,
+ (errcode(ERRCODE_UNDEFINED_DATABASE),
+ errmsg("database %u does not exist", dboid)));
+ }
+
+ MyDatabaseTableSpace = dbform->dattablespace;
+ strlcpy(dbname, NameStr(dbform->datname), sizeof(dbname));
+ if (out_dbname)
+ strcpy(out_dbname, dbname);
+ }
+
+ /*
+ * Now that we rechecked, we can be certain we're connected to a database
+ * and thus can set MyDatabaseId.
+ */
+ MyDatabaseId = dboid;
/*
* Now we can mark our PGPROC entry with the database ID.
@@ -1108,25 +1124,6 @@ InitPostgres(const char *in_dbname, Oid dboid,
*/
InvalidateCatalogSnapshot();
- /*
- * Recheck pg_database to make sure the target database hasn't gone away.
- * If there was a concurrent DROP DATABASE, this ensures we will die
- * cleanly without creating a mess.
- */
- if (!bootstrap)
- {
- HeapTuple tuple;
-
- tuple = GetDatabaseTuple(dbname);
- if (!HeapTupleIsValid(tuple) ||
- MyDatabaseId != ((Form_pg_database) GETSTRUCT(tuple))->oid ||
- MyDatabaseTableSpace != ((Form_pg_database) GETSTRUCT(tuple))->dattablespace)
- ereport(FATAL,
- (errcode(ERRCODE_UNDEFINED_DATABASE),
- errmsg("database \"%s\" does not exist", dbname),
- errdetail("It seems to have just been dropped or renamed.")));
- }
-
/*
* Now we should be able to access the database directory safely. Verify
* it's there and looks reasonable.