Allow backends to start up without use of the flat-file copy of pg_database.
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 12 Aug 2009 20:53:31 +0000 (20:53 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 12 Aug 2009 20:53:31 +0000 (20:53 +0000)
To make this work in the base case, pg_database now has a nailed-in-cache
relation descriptor that is initialized using hardwired knowledge in
relcache.c.  This means pg_database is added to the set of relations that
need to have a Schema_pg_xxx macro maintained in pg_attribute.h.  When this
path is taken, we'll have to do a seqscan of pg_database to find the row
we need.

In the normal case, we are able to do an indexscan to find the database's row
by name.  This is made possible by storing a global relcache init file that
describes only the shared catalogs and their indexes (and therefore is usable
by all backends in any database).  A new backend loads this cache file,
finds its database OID after an indexscan on pg_database, and then loads
the local relcache init file for that database.

This change should effectively eliminate number of databases as a factor
in backend startup time, even with large numbers of databases.  However,
the real reason for doing it is as a first step towards getting rid of
the flat files altogether.  There are still several other sub-projects
to be tackled before that can happen.

13 files changed:
src/backend/access/transam/xlog.c
src/backend/postmaster/autovacuum.c
src/backend/postmaster/pgstat.c
src/backend/storage/lmgr/proc.c
src/backend/utils/cache/relcache.c
src/backend/utils/init/flatfiles.c
src/backend/utils/init/miscinit.c
src/backend/utils/init/postinit.c
src/include/catalog/pg_attribute.h
src/include/catalog/pg_type.h
src/include/miscadmin.h
src/include/storage/proc.h
src/include/utils/relcache.h

index 528c205f6fb8abc0346d7cc583b72ae5ec8482f6..cc6be167ef6ecb52e193890603f8ad5419f996ec 100644 (file)
@@ -5249,6 +5249,16 @@ StartupXLOG(void)
         */
        ValidateXLOGDirectoryStructure();
 
+       /*
+        * Clear out any old relcache cache files.  This is *necessary* if we
+        * do any WAL replay, since that would probably result in the cache files
+        * being out of sync with database reality.  In theory we could leave
+        * them in place if the database had been cleanly shut down, but it
+        * seems safest to just remove them always and let them be rebuilt
+        * during the first backend startup.
+        */
+       RelationCacheInitFileRemove();
+
        /*
         * Initialize on the assumption we want to recover to the same timeline
         * that's active according to pg_control.
index db2585d3db4f288aa2932113ee12b6763007585d..2e97f6726eed31e9c29ac3e6bf147597bccfcfac 100644 (file)
@@ -1602,7 +1602,7 @@ AutoVacWorkerMain(int argc, char *argv[])
 
        if (OidIsValid(dbid))
        {
-               char       *dbname;
+               char            dbname[NAMEDATALEN];
 
                /*
                 * Report autovac startup to the stats collector.  We deliberately do
@@ -1620,7 +1620,7 @@ AutoVacWorkerMain(int argc, char *argv[])
                 * Note: if we have selected a just-deleted database (due to using
                 * stale stats info), we'll fail and exit here.
                 */
-               InitPostgres(NULL, dbid, NULL, &dbname);
+               InitPostgres(NULL, dbid, NULL, dbname);
                SetProcessingMode(NormalProcessing);
                set_ps_display(dbname, false);
                ereport(DEBUG1,
index be791e54b0fad47bacb4d8581d395677eca88bc2..dbb9f95cc33b47cef3b21f881e046066d0a57e8a 100644 (file)
@@ -2138,6 +2138,7 @@ CreateSharedBackendStatus(void)
  *     Called from InitPostgres.  MyBackendId must be set,
  *     but we must not have started any transaction yet (since the
  *     exit hook must run after the last transaction exit).
+ *     NOTE: MyDatabaseId isn't set yet; so the shutdown hook has to be careful.
  * ----------
  */
 void
@@ -2232,7 +2233,14 @@ pgstat_beshutdown_hook(int code, Datum arg)
 {
        volatile PgBackendStatus *beentry = MyBEEntry;
 
-       pgstat_report_stat(true);
+       /