📄 postinit.c
字号:
/*------------------------------------------------------------------------- * * postinit.c * postgres initialization utilities * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION * $Header: /usr/local/cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.40.2.1 1999/08/02 05:25:10 scrappy Exp $ * * NOTES * InitPostgres() is the function called from PostgresMain * which does all non-trival initialization, mainly by calling * all the other initialization functions. InitPostgres() * is only used within the "postgres" backend and so that routine * is in tcop/postgres.c InitPostgres() is needed in cinterface.a * because things like the bootstrap backend program need it. Hence * you find that in this file... * * If you feel the need to add more initialization code, it should be * done in InitPostgres() or someplace lower. Do not start * putting stuff in PostgresMain - if you do then someone * will have to clean it up later, and it's not going to be me! * -cim 10/3/90 * *------------------------------------------------------------------------- */#include <fcntl.h>#include <sys/file.h>#include <sys/types.h>#include <math.h>#include <unistd.h>#include "postgres.h"#include "access/heapam.h"#include "catalog/catname.h"#include "libpq/libpq.h"#include "miscadmin.h"#include "storage/backendid.h"#include "storage/proc.h"#include "storage/sinval.h"#include "storage/smgr.h"#include "utils/inval.h"#include "utils/portal.h"#include "utils/relcache.h"#include "utils/syscache.h"#include "version.h"#ifdef MULTIBYTE#include "mb/pg_wchar.h"#endifstatic void VerifySystemDatabase(void);static void VerifyMyDatabase(void);static void InitCommunication(void);static void InitMyDatabaseInfo(char *name);static void InitStdio(void);static void InitUserid(void);extern char *ExpandDatabasePath(char *name);extern void GetRawDatabaseInfo(char *name, int4 *owner, Oid *db_id, char *path, int *encoding);static IPCKey PostgresIpcKey;/* ---------------------------------------------------------------- * InitPostgres support * ---------------------------------------------------------------- *//* -------------------------------- * InitMyDatabaseInfo() -- Find and record the OID of the database we are * to open. * * The database's oid forms half of the unique key for the system * caches and lock tables. We therefore want it initialized before * we open any relations, since opening relations puts things in the * cache. To get around this problem, this code opens and scans the * pg_database relation by hand. * * This algorithm relies on the fact that first attribute in the * pg_database relation schema is the database name. It also knows * about the internal format of tuples on disk and the length of * the datname attribute. It knows the location of the pg_database * file. * Actually, the code looks as though it is using the pg_database * tuple definition to locate the database name, so the above statement * seems to be no longer correct. - thomas 1997-11-01 * * This code is called from InitPostgres(), before we chdir() to the * local database directory and before we open any relations. * Used to be called after the chdir(), but we now want to confirm * the location of the target database using pg_database info. * - thomas 1997-11-01 * -------------------------------- */static voidInitMyDatabaseInfo(char *name){ int4 owner; char *path, myPath[MAXPGPATH + 1]; int encoding; SetDatabaseName(name); GetRawDatabaseInfo(name, &owner, &MyDatabaseId, myPath, &encoding); if (!OidIsValid(MyDatabaseId)) elog(FATAL, "Database %s does not exist in %s", DatabaseName, DatabaseRelationName); path = ExpandDatabasePath(myPath); SetDatabasePath(path);#ifdef MULTIBYTE SetDatabaseEncoding(encoding);#endif return;} /* InitMyDatabaseInfo() *//* * DoChdirAndInitDatabaseNameAndPath * Set current directory to the database directory for the database * named <name>. * Also set global variables DatabasePath and DatabaseName to those * values. Also check for proper version of database system and * database. Exit program via elog() if anything doesn't check out. * * Arguments: * Path and name are invalid if it invalid as a string. * Path is "badly formatted" if it is not a string containing a path * to a writable directory. * Name is "badly formatted" if it contains more than 16 characters or if * it is a bad file name (e.g., it contains a '/' or an 8-bit character). * * Exceptions: * BadState if called more than once. * BadArg if both path and name are "badly formatted" or invalid. * BadArg if path and name are both "inconsistent" and valid. * * This routine is inappropriate in bootstrap mode, since the directories * and version files need not exist yet if we're in bootstrap mode. */static voidVerifySystemDatabase(){ char *reason; /* Failure reason returned by some function. NULL if no failure */ int fd; char errormsg[1000]; errormsg[0] = '\0';#ifndef __CYGWIN32__ if ((fd = open(DataDir, O_RDONLY, 0)) == -1)#else if ((fd = open(DataDir, O_RDONLY | O_DIROPEN, 0)) == -1)#endif sprintf(errormsg, "Database system does not exist. " "PGDATA directory '%s' not found.\n\tNormally, you " "create a database system by running initdb.", DataDir); else { close(fd); ValidatePgVersion(DataDir, &reason); if (reason != NULL) sprintf(errormsg, "InitPostgres could not validate that the database" " system version is compatible with this level of" " Postgres.\n\tYou may need to run initdb to create" " a new database system.\n\t%s", reason); } if (errormsg[0] != '\0') elog(FATAL, errormsg); /* Above does not return */} /* VerifySystemDatabase() */static voidVerifyMyDatabase(){ const char *name; const char *myPath; /* Failure reason returned by some function. NULL if no failure */ char *reason; int fd; char errormsg[1000]; name = DatabaseName; myPath = DatabasePath;#ifndef __CYGWIN32__ if ((fd = open(myPath, O_RDONLY, 0)) == -1)#else if ((fd = open(myPath, O_RDONLY | O_DIROPEN, 0)) == -1)#endif sprintf(errormsg, "Database '%s' does not exist." "\n\tWe know this because the directory '%s' does not exist." "\n\tYou can create a database with the SQL command" " CREATE DATABASE.\n\tTo see what databases exist," " look at the subdirectories of '%s/base/'.", name, myPath, DataDir); else { close(fd); ValidatePgVersion(myPath, &reason); if (reason != NULL) sprintf(errormsg, "InitPostgres could not validate that the database" " version is compatible with this level of Postgres" "\n\teven though the database system as a whole" " appears to be at a compatible level." "\n\tYou may need to recreate the database with SQL" " commands DROP DATABASE and CREATE DATABASE." "\n\t%s", reason); else { /* * The directories and PG_VERSION files are in order. */ int rc; /* return code from some function we call */#ifdef FILEDEBUG printf("Try changing directory for database %s to %s\n", name, myPath);#endif rc = chdir(myPath); if (rc < 0) sprintf(errormsg, "InitPostgres unable to change " "current directory to '%s', errno = %s (%d).", myPath, strerror(errno), errno); else errormsg[0] = '\0'; } } if (errormsg[0] != '\0') elog(FATAL, errormsg); /* Above does not return */} /* VerifyMyDatabase() *//* -------------------------------- * InitUserid * * initializes crap associated with the user id. * -------------------------------- */static voidInitUserid(){ setuid(geteuid()); SetUserId();}/* -------------------------------- * InitCommunication * * This routine initializes stuff needed for ipc, locking, etc. * it should be called something more informative. * * Note: * This does not set MyBackendId. MyBackendTag is set, however. * -------------------------------- */static voidInitCommunication(){ char *postid; /* value of environment variable */ char *postport; /* value of environment variable */ char *ipc_key; /* value of environemnt variable */ IPCKey key = 0; /* ---------------- * try and get the backend tag from POSTID * ---------------- */ MyBackendId = -1; postid = getenv("POSTID"); if (!PointerIsValid(postid)) MyBackendTag = -1; else { MyBackendTag = atoi(postid); Assert(MyBackendTag >= 0); } ipc_key = getenv("IPC_KEY"); if (!PointerIsValid(ipc_key)) key = -1; else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -