OSDN Git Service

First batch of object rename commands.
[pg-rex/syncrep.git] / src / backend / utils / init / postinit.c
1 /*-------------------------------------------------------------------------
2  *
3  * postinit.c
4  *        postgres initialization utilities
5  *
6  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.122 2003/06/27 14:45:30 petere Exp $
12  *
13  *
14  *-------------------------------------------------------------------------
15  */
16 #include "postgres.h"
17
18 #include <fcntl.h>
19 #include <sys/file.h>
20 #include <math.h>
21 #include <unistd.h>
22
23 #include "catalog/catalog.h"
24 #include "access/heapam.h"
25 #include "catalog/catname.h"
26 #include "catalog/namespace.h"
27 #include "catalog/pg_database.h"
28 #include "catalog/pg_shadow.h"
29 #include "commands/trigger.h"
30 #include "mb/pg_wchar.h"
31 #include "miscadmin.h"
32 #include "storage/backendid.h"
33 #include "storage/ipc.h"
34 #include "storage/proc.h"
35 #include "storage/sinval.h"
36 #include "storage/smgr.h"
37 #include "utils/fmgroids.h"
38 #include "utils/guc.h"
39 #include "utils/portal.h"
40 #include "utils/relcache.h"
41 #include "utils/syscache.h"
42
43
44 static void ReverifyMyDatabase(const char *name);
45 static void InitCommunication(void);
46 static void ShutdownPostgres(void);
47 static bool ThereIsAtLeastOneUser(void);
48
49
50 /*** InitPostgres support ***/
51
52
53 /* --------------------------------
54  *              ReverifyMyDatabase
55  *
56  * Since we are forced to fetch the database OID out of pg_database without
57  * benefit of locking or transaction ID checking (see utils/misc/database.c),
58  * we might have gotten a wrong answer.  Or, we might have attached to a
59  * database that's in process of being destroyed by destroydb().  This
60  * routine is called after we have all the locking and other infrastructure
61  * running --- now we can check that we are really attached to a valid
62  * database.
63  *
64  * In reality, if destroydb() is running in parallel with our startup,
65  * it's pretty likely that we will have failed before now, due to being
66  * unable to read some of the system tables within the doomed database.
67  * This routine just exists to make *sure* we have not started up in an
68  * invalid database.  If we quit now, we should have managed to avoid
69  * creating any serious problems.
70  *
71  * This is also a handy place to fetch the database encoding info out
72  * of pg_database.
73  *
74  * To avoid having to read pg_database more times than necessary
75  * during session startup, this place is also fitting to set up any
76  * database-specific configuration variables.
77  * --------------------------------
78  */
79 static void
80 ReverifyMyDatabase(const char *name)
81 {
82         Relation        pgdbrel;
83         HeapScanDesc pgdbscan;
84         ScanKeyData key;
85         HeapTuple       tup;
86         Form_pg_database dbform;
87
88         /*
89          * Because we grab AccessShareLock here, we can be sure that destroydb
90          * is not running in parallel with us (any more).
91          */
92         pgdbrel = heap_openr(DatabaseRelationName, AccessShareLock);
93
94         ScanKeyEntryInitialize(&key, 0, Anum_pg_database_datname,
95                                                    F_NAMEEQ, NameGetDatum(name));
96
97         pgdbscan = heap_beginscan(pgdbrel, SnapshotNow, 1, &key);
98
99         tup = heap_getnext(pgdbscan, ForwardScanDirection);
100         if (!HeapTupleIsValid(tup) ||
101                 HeapTupleGetOid(tup) != MyDatabaseId)
102         {
103                 /* OOPS */
104                 heap_close(pgdbrel, AccessShareLock);
105
106                 /*
107                  * The only real problem I could have created is to load dirty
108                  * buffers for the dead database into shared buffer cache; if I
109                  * did, some other backend will eventually try to write them and
110                  * die in mdblindwrt.  Flush any such pages to forestall trouble.
111                  */
112                 DropBuffers(MyDatabaseId);
113                 /* Now I can commit hara-kiri with a clear conscience... */
114                 elog(FATAL, "Database \"%s\", OID %u, has disappeared from pg_database",
115                          name, MyDatabaseId);
116         }
117
118         /*
119          * Also check that the database is currently allowing connections.
120          */
121         dbform = (Form_pg_database) GETSTRUCT(tup);
122         if (!dbform->datallowconn)
123                 elog(FATAL, "Database \"%s\" is not currently accepting connections",
124                          name);
125
126         /*
127          * OK, we're golden.  Only other to-do item is to save the encoding
128          * info out of the pg_database tuple.
129          */
130         SetDatabaseEncoding(dbform->encoding);
131         /* Record it as a GUC internal option, too */
132         SetConfigOption("server_encoding", GetDatabaseEncodingName(),
133                                         PGC_INTERNAL, PGC_S_OVERRIDE);
134         /* If we have no other source of client_encoding, use server encoding */
135         SetConfigOption("client_encoding", GetDatabaseEncodingName(),
136                                         PGC_BACKEND, PGC_S_DEFAULT);
137
138         /*
139          * Set up database-specific configuration variables.
140          */
141         if (IsUnderPostmaster)
142         {
143                 Datum           datum;
144                 bool            isnull;
145
146                 datum = heap_getattr(tup, Anum_pg_database_datconfig,
147                                                          RelationGetDescr(pgdbrel), &isnull);
148                 if (!isnull)
149                 {
150                         ArrayType  *a = DatumGetArrayTypeP(datum);
151
152                         ProcessGUCArray(a, PGC_S_DATABASE);
153                 }
154         }
155
156         heap_endscan(pgdbscan);
157         heap_close(pgdbrel, AccessShareLock);
158 }
159
160
161
162 /* --------------------------------
163  *              InitCommunication
164  *
165  *              This routine initializes stuff needed for ipc, locking, etc.
166  *              it should be called something more informative.
167  * --------------------------------
168  */
169 static void
170 InitCommunication(void)
171 {
172         /*
173          * initialize shared memory and semaphores appropriately.
174          */
175         if (!IsUnderPostmaster)         /* postmaster already did this */
176         {
177                 /*
178                  * We're running a postgres bootstrap process or a standalone backend.
179                  * Create private "shmem" and semaphores.  Force MaxBackends to 1 so
180                  * that we don't allocate more resources than necessary.
181                  */
182                 SetConfigOption("max_connections", "1",
183                                                 PGC_POSTMASTER, PGC_S_OVERRIDE);
184
185                 CreateSharedMemoryAndSemaphores(true, MaxBackends, 0);
186         }
187 }
188
189
190 /*
191  * Early initialization of a backend (either standalone or under postmaster).
192  * This happens even before InitPostgres.
193  *
194  * If you're wondering why this is separate from InitPostgres at all:
195  * the critical distinction is that this stuff has to happen before we can
196  * run XLOG-related initialization, which is done before InitPostgres --- in
197  * fact, for cases such as checkpoint creation processes, InitPostgres may
198  * never be done at all.
199  */
200 void
201 BaseInit(void)
202 {
203         /*
204          * Attach to shared memory and semaphores, and initialize our
205          * input/output/debugging file descriptors.
206          */
207         InitCommunication();
208         DebugFileOpen();
209
210         /* Do local initialization of storage and buffer managers */
211         smgrinit();
212         InitBufferPoolAccess();
213         InitLocalBuffer();
214 }
215
216
217 /* --------------------------------
218  * InitPostgres
219  *              Initialize POSTGRES.
220  *
221  * Note:
222  *              Be very careful with the order of calls in the InitPostgres function.
223  * --------------------------------
224  */
225 void
226 InitPostgres(const char *dbname, const char *username)
227 {
228         bool            bootstrap = IsBootstrapProcessingMode();
229
230         /*
231          * Set up the global variables holding database id and path.
232          *
233          * We take a shortcut in the bootstrap case, otherwise we have to look up
234          * the db name in pg_database.
235          */
236         if (bootstrap)
237         {
238                 MyDatabaseId = TemplateDbOid;
239                 SetDatabasePath(GetDatabasePath(MyDatabaseId));
240         }
241         else
242         {
243                 char       *fullpath,
244                                         datpath[MAXPGPATH];
245
246                 /*
247                  * Formerly we validated DataDir here, but now that's done
248                  * earlier.
249                  */
250
251                 /*
252                  * Find oid and path of the database we're about to open. Since
253                  * we're not yet up and running we have to use the hackish
254                  * GetRawDatabaseInfo.
255                  */
256                 GetRawDatabaseInfo(dbname, &MyDatabaseId, datpath);
257
258                 if (!OidIsValid(MyDatabaseId))
259                         elog(FATAL,
260                                  "Database \"%s\" does not exist in the system catalog.",
261                                  dbname);
262
263                 fullpath = GetDatabasePath(MyDatabaseId);
264
265                 /* Verify the database path */
266
267                 if (access(fullpath, F_OK) == -1)
268                         elog(FATAL, "Database \"%s\" does not exist.\n\t"
269                                  "The database subdirectory '%s' is missing.",
270                                  dbname, fullpath);
271
272                 ValidatePgVersion(fullpath);
273
274                 if (chdir(fullpath) == -1)
275                         elog(FATAL, "Unable to change directory to '%s': %m", fullpath);
276
277                 SetDatabasePath(fullpath);
278         }
279
280         /*
281          * Code after this point assumes we are in the proper directory!
282          */
283
284         /*
285          * Set up my per-backend PGPROC struct in shared memory.        (We need
286          * to know MyDatabaseId before we can do this, since it's entered into
287          * the PGPROC struct.)
288          */
289         InitProcess();
290
291         /*
292          * Initialize my entry in the shared-invalidation manager's array of
293          * per-backend data.  (Formerly this came before InitProcess, but now
294          * it must happen after, because it uses MyProc.)  Once I have done
295          * this, I am visible to other backends!
296          *
297          * Sets up MyBackendId, a unique backend identifier.
298          */
299         MyBackendId = InvalidBackendId;
300
301         InitBackendSharedInvalidationState();
302
303         if (MyBackendId > MaxBackends || MyBackendId <= 0)
304                 elog(FATAL, "InitPostgres: bad backend id %d", MyBackendId);
305
306         /*
307          * Initialize the transaction system override state.
308          */
309         AmiTransactionOverride(bootstrap);
310
311         /*
312          * Initialize the relation descriptor cache.  This must create at
313          * least the minimum set of "nailed-in" cache entries.  No catalog
314          * access happens here.
315          */
316         RelationCacheInitialize();
317
318         /*
319          * Initialize all the system catalog caches.  Note that no catalog
320          * access happens here; we only set up the cache structure.
321          */
322         InitCatalogCache();
323
324         /* Initialize portal manager */
325         EnablePortalManager();
326
327         /*
328          * Initialize the deferred trigger manager --- must happen before
329          * first transaction start.
330          */
331         DeferredTriggerInit();
332
333         /* start a new transaction here before access to db */
334         if (!bootstrap)
335                 StartTransactionCommand();
336
337         /*
338          * It's now possible to do real access to the system catalogs.
339          *
340          * Replace faked-up relcache entries with correct info.
341          */
342         RelationCacheInitializePhase2();
343
344         /*
345          * Figure out our postgres user id.  In standalone mode we use a fixed
346          * id, otherwise we figure it out from the authenticated user name.
347          */
348         if (bootstrap)
349                 InitializeSessionUserIdStandalone();
350         else if (!IsUnderPostmaster)
351         {
352                 InitializeSessionUserIdStandalone();
353                 if (!ThereIsAtLeastOneUser())
354                 {
355                         elog(WARNING, "There are currently no users defined in this database system.");
356                         elog(WARNING, "You should immediately run 'CREATE USER \"%s\" WITH SYSID %d CREATEUSER;'.",
357                                  username, BOOTSTRAP_USESYSID);
358                 }
359         }
360         else
361         {
362                 /* normal multiuser case */
363                 InitializeSessionUserId(username);
364         }
365
366         /*
367          * Unless we are bootstrapping, double-check that InitMyDatabaseInfo()
368          * got a correct result.  We can't do this until all the
369          * database-access infrastructure is up.
370          */
371         if (!bootstrap)
372                 ReverifyMyDatabase(dbname);
373
374         /*
375          * Final phase of relation cache startup: write a new cache file if
376          * necessary.  This is done after ReverifyMyDatabase to avoid writing
377          * a cache file into a dead database.
378          */
379         RelationCacheInitializePhase3();
380
381         /*
382          * Check a normal user hasn't connected to a superuser reserved slot.
383          * We can't do this till after we've read the user information, and
384          * we must do it inside a transaction since checking superuserness
385          * may require database access.  The superuser check is probably the
386          * most expensive part; don't do it until necessary.
387          */
388         if (ReservedBackends > 0 &&
389                 CountEmptyBackendSlots() < ReservedBackends &&
390                 !superuser())
391                 elog(FATAL, "Non-superuser connection limit exceeded");
392
393         /*
394          * Initialize various default states that can't be set up until we've
395          * selected the active user and done ReverifyMyDatabase.
396          */
397
398         /* set default namespace search path */
399         InitializeSearchPath();
400
401         /* initialize client encoding */
402         InitializeClientEncoding();
403
404         /*
405          * Now all default states are fully set up.  Report them to client
406          * if appropriate.
407          */
408         BeginReportingGUCOptions();
409
410         /*
411          * Set up process-exit callback to do pre-shutdown cleanup.  This
412          * should be last because we want shmem_exit to call this routine
413          * before the exit callbacks that are registered by buffer manager,
414          * lock manager, etc. We need to run this code before we close down
415          * database access!
416          */
417         on_shmem_exit(ShutdownPostgres, 0);
418
419         /* close the transaction we started above */
420         if (!bootstrap)
421                 CommitTransactionCommand();
422 }
423
424 /*
425  * Backend-shutdown callback.  Do cleanup that we want to be sure happens
426  * before all the supporting modules begin to nail their doors shut via
427  * their own callbacks.  Note that because this has to be registered very
428  * late in startup, it will not get called if we suffer a failure *during*
429  * startup.
430  *
431  * User-level cleanup, such as temp-relation removal and UNLISTEN, happens
432  * via separate callbacks that execute before this one.  We don't combine the
433  * callbacks because we still want this one to happen if the user-level
434  * cleanup fails.
435  */
436 static void
437 ShutdownPostgres(void)
438 {
439         /*
440          * These operations are really just a minimal subset of
441          * AbortTransaction(). We don't want to do any inessential cleanup,
442          * since that just raises the odds of failure --- but there's some
443          * stuff we need to do.
444          *
445          * Release any LW locks and buffer context locks we might be holding.
446          * This is a kluge to improve the odds that we won't get into a
447          * self-made stuck-lock scenario while trying to shut down.
448          */
449         LWLockReleaseAll();
450         AbortBufferIO();
451         UnlockBuffers();
452
453         /*
454          * In case a transaction is open, delete any files it created.  This
455          * has to happen before bufmgr shutdown, so having smgr register a
456          * callback for it wouldn't work.
457          */
458         smgrDoPendingDeletes(false);    /* delete as though aborting xact */
459 }
460
461
462
463 /*
464  * Returns true if at least one user is defined in this database cluster.
465  */
466 static bool
467 ThereIsAtLeastOneUser(void)
468 {
469         Relation        pg_shadow_rel;
470         TupleDesc       pg_shadow_dsc;
471         HeapScanDesc scan;
472         bool            result;
473
474         pg_shadow_rel = heap_openr(ShadowRelationName, AccessExclusiveLock);
475         pg_shadow_dsc = RelationGetDescr(pg_shadow_rel);
476
477         scan = heap_beginscan(pg_shadow_rel, SnapshotNow, 0, NULL);
478         result = (heap_getnext(scan, ForwardScanDirection) != NULL);
479
480         heap_endscan(scan);
481         heap_close(pg_shadow_rel, AccessExclusiveLock);
482
483         return result;
484 }