⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bootstrap.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * bootstrap.c *	  routines to support running postgres in 'bootstrap' mode *	bootstrap mode is used to create the initial template database * * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION *	  $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.208.2.1 2005/11/22 18:23:05 momjian Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include <unistd.h>#include <signal.h>#ifdef HAVE_GETOPT_H#include <getopt.h>#endif#define BOOTSTRAP_INCLUDE		/* mask out stuff in tcop/tcopprot.h */#include "access/genam.h"#include "access/heapam.h"#include "access/xlog.h"#include "bootstrap/bootstrap.h"#include "catalog/index.h"#include "catalog/pg_type.h"#include "executor/executor.h"#include "libpq/pqsignal.h"#include "miscadmin.h"#include "nodes/makefuncs.h"#include "postmaster/bgwriter.h"#include "storage/freespace.h"#include "storage/ipc.h"#include "storage/pg_shmem.h"#include "storage/proc.h"#include "tcop/tcopprot.h"#include "utils/builtins.h"#include "utils/flatfiles.h"#include "utils/fmgroids.h"#include "utils/guc.h"#include "utils/lsyscache.h"#include "utils/memutils.h"#include "utils/ps_status.h"#include "utils/relcache.h"extern int	optind;extern char *optarg;#define ALLOC(t, c)		((t *) calloc((unsigned)(c), sizeof(t)))extern int	Int_yyparse(void);static void usage(void);static void bootstrap_signals(void);static hashnode *AddStr(char *str, int strlength, int mderef);static Form_pg_attribute AllocateAttribute(void);static int	CompHash(char *str, int len);static hashnode *FindStr(char *str, int length, hashnode *mderef);static Oid	gettype(char *type);static void cleanup(void);/* ---------------- *		global variables * ---------------- */Relation	boot_reldesc;		/* current relation descriptor *//* * In the lexical analyzer, we need to get the reference number quickly from * the string, and the string from the reference number.  Thus we have * as our data structure a hash table, where the hashing key taken from * the particular string.  The hash table is chained.  One of the fields * of the hash table node is an index into the array of character pointers. * The unique index number that every string is assigned is simply the * position of its string pointer in the array of string pointers. */#define STRTABLESIZE	10000#define HASHTABLESIZE	503/* Hash function numbers */#define NUM		23#define NUMSQR	529#define NUMCUBE 12167char	   *strtable[STRTABLESIZE];hashnode   *hashtable[HASHTABLESIZE];static int	strtable_end = -1;	/* Tells us last occupied string space *//*- * Basic information associated with each type.  This is used before * pg_type is created. * *		XXX several of these input/output functions do catalog scans *			(e.g., F_REGPROCIN scans pg_proc).	this obviously creates some *			order dependencies in the catalog creation process. */struct typinfo{	char		name[NAMEDATALEN];	Oid			oid;	Oid			elem;	int16		len;	bool		byval;	char		align;	char		storage;	Oid			inproc;	Oid			outproc;};static const struct typinfo TypInfo[] = {	{"bool", BOOLOID, 0, 1, true, 'c', 'p',	F_BOOLIN, F_BOOLOUT},	{"bytea", BYTEAOID, 0, -1, false, 'i', 'x',	F_BYTEAIN, F_BYTEAOUT},	{"char", CHAROID, 0, 1, true, 'c', 'p',	F_CHARIN, F_CHAROUT},	{"name", NAMEOID, CHAROID, NAMEDATALEN, false, 'i', 'p',	F_NAMEIN, F_NAMEOUT},	{"int2", INT2OID, 0, 2, true, 's', 'p',	F_INT2IN, F_INT2OUT},	{"int4", INT4OID, 0, 4, true, 'i', 'p',	F_INT4IN, F_INT4OUT},	{"regproc", REGPROCOID, 0, 4, true, 'i', 'p',	F_REGPROCIN, F_REGPROCOUT},	{"regclass", REGCLASSOID, 0, 4, true, 'i', 'p',	F_REGCLASSIN, F_REGCLASSOUT},	{"regtype", REGTYPEOID, 0, 4, true, 'i', 'p',	F_REGTYPEIN, F_REGTYPEOUT},	{"text", TEXTOID, 0, -1, false, 'i', 'x',	F_TEXTIN, F_TEXTOUT},	{"oid", OIDOID, 0, 4, true, 'i', 'p',	F_OIDIN, F_OIDOUT},	{"tid", TIDOID, 0, 6, false, 's', 'p',	F_TIDIN, F_TIDOUT},	{"xid", XIDOID, 0, 4, true, 'i', 'p',	F_XIDIN, F_XIDOUT},	{"cid", CIDOID, 0, 4, true, 'i', 'p',	F_CIDIN, F_CIDOUT},	{"int2vector", INT2VECTOROID, INT2OID, -1, false, 'i', 'p',	F_INT2VECTORIN, F_INT2VECTOROUT},	{"oidvector", OIDVECTOROID, OIDOID, -1, false, 'i', 'p',	F_OIDVECTORIN, F_OIDVECTOROUT},	{"_int4", INT4ARRAYOID, INT4OID, -1, false, 'i', 'x',	F_ARRAY_IN, F_ARRAY_OUT},	{"_text", 1009, TEXTOID, -1, false, 'i', 'x',	F_ARRAY_IN, F_ARRAY_OUT},	{"_oid", 1028, OIDOID, -1, false, 'i', 'x',	F_ARRAY_IN, F_ARRAY_OUT},	{"_char", 1002, CHAROID, -1, false, 'i', 'x',	F_ARRAY_IN, F_ARRAY_OUT},	{"_aclitem", 1034, ACLITEMOID, -1, false, 'i', 'x',	F_ARRAY_IN, F_ARRAY_OUT}};static const int n_types = sizeof(TypInfo) / sizeof(struct typinfo);struct typmap{								/* a hack */	Oid			am_oid;	FormData_pg_type am_typ;};static struct typmap **Typ = NULL;static struct typmap *Ap = NULL;static int	Warnings = 0;static char Blanks[MAXATTR];Form_pg_attribute attrtypes[MAXATTR];	/* points to attribute info */static Datum values[MAXATTR];	/* corresponding attribute values */int			numattr;			/* number of attributes for cur. rel */static MemoryContext nogc = NULL;		/* special no-gc mem context *//* *	At bootstrap time, we first declare all the indices to be built, and *	then build them.  The IndexList structure stores enough information *	to allow us to build the indices after they've been declared. */typedef struct _IndexList{	Oid			il_heap;	Oid			il_ind;	IndexInfo  *il_info;	struct _IndexList *il_next;} IndexList;static IndexList *ILHead = NULL;/* *	 The main entry point for running the backend in bootstrap mode * *	 The bootstrap mode is used to initialize the template database. *	 The bootstrap backend doesn't speak SQL, but instead expects *	 commands in a special bootstrap language. * *	 For historical reasons, BootstrapMain is also used as the control *	 routine for non-backend subprocesses launched by the postmaster, *	 such as startup and shutdown. */intBootstrapMain(int argc, char *argv[]){	char	   *progname = argv[0];	int			i;	char	   *dbname;	int			flag;	int			xlogop = BS_XLOG_NOP;	char	   *userDoption = NULL;	/*	 * initialize globals	 */	MyProcPid = getpid();	/*	 * Fire up essential subsystems: error and memory management	 *	 * If we are running under the postmaster, this is done already.	 */	if (!IsUnderPostmaster)		MemoryContextInit();	/* Compute paths, if we didn't inherit them from postmaster */	if (my_exec_path[0] == '\0')	{		if (find_my_exec(progname, my_exec_path) < 0)			elog(FATAL, "%s: could not locate my own executable path",				 progname);	}	/*	 * process command arguments	 */	/* Set defaults, to be overriden by explicit options below */	dbname = NULL;	if (!IsUnderPostmaster)		InitializeGUCOptions();	/* Ignore the initial -boot argument, if present */	if (argc > 1 && strcmp(argv[1], "-boot") == 0)	{		argv++;		argc--;	}	while ((flag = getopt(argc, argv, "B:c:d:D:Fo:p:x:-:")) != -1)	{		switch (flag)		{			case 'D':				userDoption = optarg;				break;			case 'd':				{					/* Turn on debugging for the bootstrap process. */					char	   *debugstr = palloc(strlen("debug") + strlen(optarg) + 1);					sprintf(debugstr, "debug%s", optarg);					SetConfigOption("log_min_messages", debugstr,									PGC_POSTMASTER, PGC_S_ARGV);					SetConfigOption("client_min_messages", debugstr,									PGC_POSTMASTER, PGC_S_ARGV);					pfree(debugstr);				}				break;			case 'F':				SetConfigOption("fsync", "false", PGC_POSTMASTER, PGC_S_ARGV);				break;			case 'o':				StrNCpy(OutputFileName, optarg, MAXPGPATH);				break;			case 'x':				xlogop = atoi(optarg);				break;			case 'p':				dbname = strdup(optarg);				break;			case 'B':				SetConfigOption("shared_buffers", optarg, PGC_POSTMASTER, PGC_S_ARGV);				break;			case 'c':			case '-':				{					char	   *name,							   *value;					ParseLongOption(optarg, &name, &value);					if (!value)					{						if (flag == '-')							ereport(ERROR,									(errcode(ERRCODE_SYNTAX_ERROR),									 errmsg("--%s requires a value",											optarg)));						else							ereport(ERROR,									(errcode(ERRCODE_SYNTAX_ERROR),									 errmsg("-c %s requires a value",											optarg)));					}					SetConfigOption(name, value, PGC_POSTMASTER, PGC_S_ARGV);					free(name);					if (value)						free(value);					break;				}			default:				usage();				break;		}	}	if (!dbname && argc - optind == 1)	{		dbname = argv[optind];		optind++;	}	if (!dbname || argc != optind)		usage();	/*	 * Identify myself via ps	 */	if (IsUnderPostmaster)	{		const char *statmsg;		switch (xlogop)		{			case BS_XLOG_STARTUP:				statmsg = "startup process";				break;			case BS_XLOG_BGWRITER:				statmsg = "writer process";				break;			default:				statmsg = "??? process";				break;		}		init_ps_display(statmsg, "", "");		set_ps_display("");	}	/* Acquire configuration parameters, unless inherited from postmaster */	if (!IsUnderPostmaster)	{		if (!SelectConfigFiles(userDoption, progname))			proc_exit(1);		/* If timezone is not set, determine what the OS uses */		pg_timezone_initialize();	}	/* Validate we have been given a reasonable-looking DataDir */	Assert(DataDir);	ValidatePgVersion(DataDir);	/* Change into DataDir (if under postmaster, should be done already) */	if (!IsUnderPostmaster)		ChangeToDataDir();	/* If standalone, create lockfile for data directory */	if (!IsUnderPostmaster)		CreateDataDirLockFile(false);	SetProcessingMode(BootstrapProcessing);	IgnoreSystemIndexes(true);	BaseInit();	/*	 * We aren't going to do the full InitPostgres pushups, but there are a	 * couple of things that need to get lit up even in a dummy process.	 */	if (IsUnderPostmaster)	{		/* set up proc.c to get use of LWLocks */		switch (xlogop)		{			case BS_XLOG_BGWRITER:				InitDummyProcess(DUMMY_PROC_BGWRITER);				break;			default:				InitDummyProcess(DUMMY_PROC_DEFAULT);				break;		}		/* finish setting up bufmgr.c */		InitBufferPoolBackend();	}	/*	 * XLOG operations	 */	SetProcessingMode(NormalProcessing);	switch (xlogop)	{		case BS_XLOG_NOP:			bootstrap_signals();			break;		case BS_XLOG_BOOTSTRAP:			bootstrap_signals();			BootStrapXLOG();			StartupXLOG();			break;		case BS_XLOG_STARTUP:			bootstrap_signals();			StartupXLOG();			LoadFreeSpaceMap();			BuildFlatFiles(false);			proc_exit(0);		/* startup done */		case BS_XLOG_BGWRITER:			/* don't set signals, bgwriter has its own agenda */			InitXLOGAccess();			BackgroundWriterMain();			proc_exit(1);		/* should never return */		default:			elog(PANIC, "unrecognized XLOG op: %d", xlogop);			proc_exit(1);	}	SetProcessingMode(BootstrapProcessing);	/*	 * backend initialization	 */	(void) InitPostgres(dbname, NULL);	/*	 * In NOP mode, all we really want to do is create shared memory and	 * semaphores (just to prove we can do it with the current GUC settings).	 * So, quit now.	 */	if (xlogop == BS_XLOG_NOP)		proc_exit(0);	/* Initialize stuff for bootstrap-file processing */	for (i = 0; i < MAXATTR; i++)	{		attrtypes[i] = NULL;		Blanks[i] = ' ';	}	for (i = 0; i < STRTABLESIZE; ++i)		strtable[i] = NULL;	for (i = 0; i < HASHTABLESIZE; ++i)		hashtable[i] = NULL;	/*	 * Process bootstrap input.	 *	 * the sed script boot.sed renamed yyparse to Int_yyparse for the	 * bootstrap parser to avoid conflicts with the normal SQL parser	 */	Int_yyparse();	/* Perform a checkpoint to ensure everything's down to disk */	SetProcessingMode(NormalProcessing);	CreateCheckPoint(true, true);	SetProcessingMode(BootstrapProcessing);	/* Clean up and exit */	StartTransactionCommand();	cleanup();	/* not reached, here to make compiler happy */	return 0;}/* ---------------------------------------------------------------- *						misc functions * ---------------------------------------------------------------- *//* usage: *		usage help for the bootstrap backend */static voidusage(void){	write_stderr("Usage:\n"				 "  postgres -boot [OPTION]... DBNAME\n"				 "  -c NAME=VALUE    set run-time parameter\n"				 "  -d 1-5           debug level\n"				 "  -D datadir       data directory\n"				 "  -F               turn off fsync\n"				 "  -o file          send debug output to file\n"				 "  -x num           internal use\n");	proc_exit(1);}/* * Set up signal handling for a bootstrap process */static voidbootstrap_signals(void){	if (IsUnderPostmaster)	{		/*		 * Properly accept or ignore signals the postmaster might send us		 */		pqsignal(SIGHUP, SIG_IGN);		pqsignal(SIGINT, SIG_IGN);		/* ignore query-cancel */		pqsignal(SIGTERM, die);		pqsignal(SIGQUIT, quickdie);		pqsignal(SIGALRM, SIG_IGN);		pqsignal(SIGPIPE, SIG_IGN);		pqsignal(SIGUSR1, SIG_IGN);		pqsignal(SIGUSR2, SIG_IGN);		/*		 * Reset some signals that are accepted by postmaster but not here		 */		pqsignal(SIGCHLD, SIG_DFL);		pqsignal(SIGTTIN, SIG_DFL);		pqsignal(SIGTTOU, SIG_DFL);		pqsignal(SIGCONT, SIG_DFL);		pqsignal(SIGWINCH, SIG_DFL);		/*		 * Unblock signals (they were blocked when the postmaster forked us)		 */		PG_SETMASK(&UnBlockSig);	}	else	{		/* Set up appropriately for interactive use */		pqsignal(SIGHUP, die);		pqsignal(SIGINT, die);		pqsignal(SIGTERM, die);		pqsignal(SIGQUIT, die);	}}/* ---------------- *		error handling / abort routines * ---------------- */voiderr_out(void){	Warnings++;	cleanup();}/* ---------------------------------------------------------------- *				MANUAL BACKEND INTERACTIVE INTERFACE COMMANDS * ---------------------------------------------------------------- *//* ---------------- *		boot_openrel * ---------------- */voidboot_openrel(char *relname){	int			i;	struct typmap **app;	Relation	rel;	HeapScanDesc scan;	HeapTuple	tup;	if (strlen(relname) >= NAMEDATALEN)		relname[NAMEDATALEN - 1] = '\0';	if (Typ == NULL)	{		rel = heap_open(TypeRelationId, NoLock);		scan = heap_beginscan(rel, SnapshotNow, 0, NULL);		i = 0;		while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL)			++i;		heap_endscan(scan);		app = Typ = ALLOC(struct typmap *, i + 1);		while (i-- > 0)			*app++ = ALLOC(struct typmap, 1);		*app = NULL;		scan = heap_beginscan(rel, SnapshotNow, 0, NULL);		app = Typ;		while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL)		{			(*app)->am_oid = HeapTupleGetOid(tup);			memcpy((char *) &(*app)->am_typ,				   (char *) GETSTRUCT(tup),				   sizeof((*app)->am_typ));			app++;		}		heap_endscan(scan);		heap_close(rel, NoLock);	}	if (boot_reldesc != NULL)		closerel(NULL);	elog(DEBUG4, "open relation %s, attrsize %d",		 relname, (int) ATTRIBUTE_TUPLE_SIZE);	boot_reldesc = heap_openrv(makeRangeVar(NULL, relname), NoLock);	numattr = boot_reldesc->rd_rel->relnatts;	for (i = 0; i < numattr; i++)	{		if (attrtypes[i] == NULL)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -