Commit 04011cc9 authored by Tom Lane's avatar Tom Lane

Allow backends to start up without use of the flat-file copy of pg_database.

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.
parent a1f0c9ba
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.347 2009/08/08 16:39:17 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.348 2009/08/12 20:53:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -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.
......
......@@ -55,7 +55,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.100 2009/07/31 20:26:22 tgl Exp $
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.101 2009/08/12 20:53:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -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,
......
......@@ -13,7 +13,7 @@
*
* Copyright (c) 2001-2009, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.189 2009/06/11 14:49:01 momjian Exp $
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.190 2009/08/12 20:53:30 tgl Exp $
* ----------
*/
#include "postgres.h"
......@@ -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);
/*
* If we got as far as discovering our own database ID, we can report
* what we did to the collector. Otherwise, we'd be sending an invalid
* database ID, so forget it. (This means that accesses to pg_database
* during failed backend starts might never get counted.)
*/
if (OidIsValid(MyDatabaseId))
pgstat_report_stat(true);
/*
* Clear my status entry, following the protocol of bumping st_changecount
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.207 2009/06/11 14:49:02 momjian Exp $
* $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.208 2009/08/12 20:53:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -332,22 +332,14 @@ InitProcess(void)
* InitProcessPhase2 -- make MyProc visible in the shared ProcArray.
*
* This is separate from InitProcess because we can't acquire LWLocks until
* we've created a PGPROC, but in the EXEC_BACKEND case there is a good deal
* of stuff to be done before this step that will require LWLock access.
* we've created a PGPROC, but in the EXEC_BACKEND case ProcArrayAdd won't
* work until after we've done CreateSharedMemoryAndSemaphores.
*/
void
InitProcessPhase2(void)
{
Assert(MyProc != NULL);
/*
* We should now know what database we're in, so advertise that. (We need
* not do any locking here, since no other backend can yet see our
* PGPROC.)
*/
Assert(OidIsValid(MyDatabaseId));
MyProc->databaseId = MyDatabaseId;
/*
* Add our PGPROC to the PGPROC array in shared memory.
*/
......
This diff is collapsed.
......@@ -23,7 +23,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/backend/utils/init/flatfiles.c,v 1.36 2009/01/01 17:23:51 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/init/flatfiles.c,v 1.37 2009/08/12 20:53:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -37,7 +37,6 @@
#include "access/twophase_rmgr.h"
#include "access/xact.h"
#include "access/xlogutils.h"
#include "catalog/catalog.h"
#include "catalog/pg_auth_members.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_database.h"
......@@ -51,7 +50,6 @@
#include "storage/pmsignal.h"
#include "utils/builtins.h"
#include "utils/flatfiles.h"
#include "utils/relcache.h"
#include "utils/resowner.h"
#include "utils/tqual.h"
......@@ -171,14 +169,9 @@ name_okay(const char *str)
*
* A side effect is to determine the oldest database's datfrozenxid
* so we can set or update the XID wrap limit.
*
* Also, if "startup" is true, we tell relcache.c to clear out the relcache
* init file in each database. That's a bit nonmodular, but scanning
* pg_database twice during system startup seems too high a price for keeping
* things better separated.
*/
static void
write_database_file(Relation drel, bool startup)
write_database_file(Relation drel)
{
char *filename,
*tempname;
......@@ -259,17 +252,6 @@ write_database_file(Relation drel, bool startup)
fputs_quote(datname, fp);
fprintf(fp, " %u %u %u\n",
datoid, dattablespace, datfrozenxid);
/*
* Also clear relcache init file for each DB if starting up.
*/
if (startup)
{
char *dbpath = GetDatabasePath(datoid, dattablespace);
RelationCacheInitFileRemove(dbpath);
pfree(dbpath);
}
}
heap_endscan(scan);
......@@ -688,9 +670,6 @@ write_auth_file(Relation rel_authid, Relation rel_authmem)
* policy means we need not force initdb to change the format of the
* flat files.
*
* We also cause relcache init files to be flushed, for largely the same
* reasons.
*
* In a standalone backend we pass database_only = true to skip processing
* the auth file. We won't need it, and building it could fail if there's
* something corrupt in the authid/authmem catalogs.
......@@ -720,7 +699,7 @@ BuildFlatFiles(bool database_only)
* No locking is needed because no one else is alive yet.
*/
rel_db = CreateFakeRelcacheEntry(rnode);
write_database_file(rel_db, true);
write_database_file(rel_db);
FreeFakeRelcacheEntry(rel_db);
if (!database_only)
......@@ -833,7 +812,7 @@ AtEOXact_UpdateFlatFiles(bool isCommit)
if (database_file_update_subid != InvalidSubTransactionId)
{
database_file_update_subid = InvalidSubTransactionId;
write_database_file(drel, false);
write_database_file(drel);
heap_close(drel, NoLock);
}
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.175 2009/06/11 14:49:05 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.176 2009/08/12 20:53:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -40,6 +40,7 @@
#include "storage/procarray.h"
#include "utils/builtins.h"
#include "utils/guc.h"
#include "utils/memutils.h"
#include "utils/syscache.h"
......@@ -128,17 +129,9 @@ ResetReindexProcessing(void)
void
SetDatabasePath(const char *path)
{
if (DatabasePath)
{
free(DatabasePath);
DatabasePath = NULL;
}
/* use strdup since this is done before memory contexts are set up */
if (path)
{
DatabasePath = strdup(path);
AssertState(DatabasePath);
}
/* This should happen only once per process */
Assert(!DatabasePath);
DatabasePath = MemoryContextStrdup(TopMemoryContext, path);
}
/*
......
This diff is collapsed.
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.151 2009/08/04 04:04:11 tgl Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.152 2009/08/12 20:53:30 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
......@@ -465,6 +465,29 @@ DATA(insert ( 1259 xmax 28 0 0 4 -5 0 -1 -1 t p i t f f t 0 _null_));
DATA(insert ( 1259 cmax 29 0 0 4 -6 0 -1 -1 t p i t f f t 0 _null_));
DATA(insert ( 1259 tableoid 26 0 0 4 -7 0 -1 -1 t p i t f f t 0 _null_));
/* ----------------
* pg_database
*
* pg_database is not bootstrapped in the same way as the other relations that
* have hardwired pg_attribute entries in this file. However, we do need
* a "Schema_xxx" macro for it --- see relcache.c.
* ----------------
*/
#define Schema_pg_database \
{ 1262, {"datname"}, 19, -1, 0, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'c', true, false, false, true, 0, { 0 } }, \
{ 1262, {"datdba"}, 26, -1, 0, 4, 2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
{ 1262, {"encoding"}, 23, -1, 0, 4, 3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
{ 1262, {"datcollate"}, 19, -1, 0, NAMEDATALEN, 4, 0, -1, -1, false, 'p', 'c', true, false, false, true, 0, { 0 } }, \
{ 1262, {"datctype"}, 19, -1, 0, NAMEDATALEN, 5, 0, -1, -1, false, 'p', 'c', true, false, false, true, 0, { 0 } }, \
{ 1262, {"datistemplate"}, 16, -1, 0, 1, 6, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
{ 1262, {"datallowconn"}, 16, -1, 0, 1, 7, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
{ 1262, {"datconnlimit"}, 23, -1, 0, 4, 8, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
{ 1262, {"datlastsysoid"}, 26, -1, 0, 4, 9, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
{ 1262, {"datfrozenxid"}, 28, -1, 0, 4, 10, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
{ 1262, {"dattablespace"}, 26, -1, 0, 4, 11, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
{ 1262, {"datconfig"}, 1009, -1, 0, -1, 12, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
{ 1262, {"datacl"}, 1034, -1, 0, -1, 13, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }
/* ----------------
* pg_index
*
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.207 2009/07/11 21:15:32 petere Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.208 2009/08/12 20:53:30 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
......@@ -333,13 +333,9 @@ DESCR("array of oids, used in system tables");
/* hand-built rowtype entries for bootstrapped catalogs: */
DATA(insert OID = 71 ( pg_type PGNSP PGUID -1 f c C f t \054 1247 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ ));
#define PG_TYPE_RELTYPE_OID 71
DATA(insert OID = 75 ( pg_attribute PGNSP PGUID -1 f c C f t \054 1249 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ ));
#define PG_ATTRIBUTE_RELTYPE_OID 75
DATA(insert OID = 81 ( pg_proc PGNSP PGUID -1 f c C f t \054 1255 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ ));
#define PG_PROC_RELTYPE_OID 81
DATA(insert OID = 83 ( pg_class PGNSP PGUID -1 f c C f t \054 1259 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ ));
#define PG_CLASS_RELTYPE_OID 83
/* OIDS 100 - 199 */
DATA(insert OID = 142 ( xml PGNSP PGUID -1 f b U f t \054 0 0 143 xml_in xml_out xml_recv xml_send - - - i x f 0 -1 0 _null_ _null_ ));
......
......@@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.211 2009/06/11 14:49:08 momjian Exp $
* $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.212 2009/08/12 20:53:30 tgl Exp $
*
* NOTES
* some of the information in this file should be moved to other files.
......@@ -324,7 +324,7 @@ extern ProcessingMode Mode;
/* in utils/init/postinit.c */
extern bool InitPostgres(const char *in_dbname, Oid dboid, const char *username,
char **out_dbname);
char *out_dbname);
extern void BaseInit(void);
/* in utils/init/miscinit.c */
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.112 2009/02/23 09:28:50 heikki Exp $
* $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.113 2009/08/12 20:53:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -84,7 +84,9 @@ struct PGPROC
* vacuum must not remove tuples deleted by
* xid >= xmin ! */
int pid; /* This backend's process id, or 0 */
int pid; /* Backend's process ID; 0 if prepared xact */
/* These fields are zero while a backend is still starting up: */
BackendId backendId; /* This backend's backend ID (if assigned) */
Oid databaseId; /* OID of database this backend is using */
Oid roleId; /* OID of role using this backend */
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/relcache.h,v 1.63 2009/01/01 17:24:02 momjian Exp $
* $PostgreSQL: pgsql/src/include/utils/relcache.h,v 1.64 2009/08/12 20:53:31 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -54,6 +54,7 @@ extern void RelationInitIndexAccessInfo(Relation relation);
*/
extern void RelationCacheInitialize(void);
extern void RelationCacheInitializePhase2(void);
extern void RelationCacheInitializePhase3(void);
/*
* Routine to create a relcache entry for an about-to-be-created relation
......@@ -81,13 +82,15 @@ extern void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid,
extern void RelationCacheMarkNewRelfilenode(Relation rel);
/*
* Routines to help manage rebuilding of relcache init file
* Routines to help manage rebuilding of relcache init files
*/
extern bool RelationIdIsInInitFile(Oid relationId);
extern void RelationCacheInitFileInvalidate(bool beforeSend);
extern void RelationCacheInitFileRemove(const char *dbPath);
extern void RelationCacheInitFileRemove(void);
/* should be used only by relcache.c and catcache.c */
extern bool criticalRelcachesBuilt;
/* should be used only by relcache.c and postinit.c */
extern bool criticalSharedRelcachesBuilt;
#endif /* RELCACHE_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment