strcpy(out_dbname, dbname);
    }
 
-   /* Now we can mark our PGPROC entry with the database ID */
-   /* (We assume this is an atomic store so no lock is needed) */
-   MyProc->databaseId = MyDatabaseId;
-
-   /*
-    * We established a catalog snapshot while reading pg_authid and/or
-    * pg_database; but until we have set up MyDatabaseId, we won't react to
-    * incoming sinval messages for unshared catalogs, so we won't realize it
-    * if the snapshot has been invalidated.  Assume it's no good anymore.
-    */
-   InvalidateCatalogSnapshot();
-
    /*
     * Now, take a writer's lock on the database we are trying to connect to.
     * If there is a concurrently running DROP DATABASE on that database, this
     * pg_database).
     *
     * Note that the lock is not held long, only until the end of this startup
-    * transaction.  This is OK since we are already advertising our use of
-    * the database in the PGPROC array; anyone trying a DROP DATABASE after
-    * this point will see us there.
+    * transaction.  This is OK since we will advertise our use of the
+    * database in the ProcArray before dropping the lock (in fact, that's the
+    * next thing to do).  Anyone trying a DROP DATABASE after this point will
+    * see us in the array once they have the lock.  Ordering is important for
+    * this because we don't want to advertise ourselves as being in this
+    * database until we have the lock; otherwise we create what amounts to a
+    * deadlock with CountOtherDBBackends().
     *
     * Note: use of RowExclusiveLock here is reasonable because we envision
     * our session as being a concurrent writer of the database.  If we had a
        LockSharedObject(DatabaseRelationId, MyDatabaseId, 0,
                         RowExclusiveLock);
 
+   /*
+    * Now we can mark our PGPROC entry with the database ID.
+    *
+    * We assume this is an atomic store so no lock is needed; though actually
+    * things would work fine even if it weren't atomic.  Anyone searching the
+    * ProcArray for this database's ID should hold the database lock, so they
+    * would not be executing concurrently with this store.  A process looking
+    * for another database's ID could in theory see a chance match if it read
+    * a partially-updated databaseId value; but as long as all such searches
+    * wait and retry, as in CountOtherDBBackends(), they will certainly see
+    * the correct value on their next try.
+    */
+   MyProc->databaseId = MyDatabaseId;
+
+   /*
+    * We established a catalog snapshot while reading pg_authid and/or
+    * pg_database; but until we have set up MyDatabaseId, we won't react to
+    * incoming sinval messages for unshared catalogs, so we won't realize it
+    * if the snapshot has been invalidated.  Assume it's no good anymore.
+    */
+   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