📄 bootstrap.c
字号:
CreateDataDirLockFile(DataDir, false); } SetProcessingMode(BootstrapProcessing); IgnoreSystemIndexes(true); XLOGPathInit(); BaseInit(); if (IsUnderPostmaster) InitDummyProcess(); /* needed to get LWLocks */ /* * XLOG operations */ SetProcessingMode(NormalProcessing); switch (xlogop) { case BS_XLOG_NOP: break; case BS_XLOG_BOOTSTRAP: BootStrapXLOG(); StartupXLOG(); break; case BS_XLOG_CHECKPOINT: CreateDummyCaches(); CreateCheckPoint(false, false); SetSavedRedoRecPtr(); /* pass redo ptr back to * postmaster */ proc_exit(0); /* done */ case BS_XLOG_STARTUP: StartupXLOG(); LoadFreeSpaceMap(); proc_exit(0); /* done */ case BS_XLOG_SHUTDOWN: ShutdownXLOG(); DumpFreeSpaceMap(); proc_exit(0); /* done */ default: elog(PANIC, "unrecognized XLOG op: %d", xlogop); proc_exit(0); } SetProcessingMode(BootstrapProcessing); /* * backend initialization */ 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] = (Form_pg_attribute) NULL; Blanks[i] = ' '; } for (i = 0; i < STRTABLESIZE; ++i) strtable[i] = NULL; for (i = 0; i < HASHTABLESIZE; ++i) hashtable[i] = NULL; /* * abort processing resumes here (this is probably dead code?) */ if (sigsetjmp(Warn_restart, 1) != 0) { Warnings++; AbortCurrentTransaction(); } /* * 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;}/* ---------------------------------------------------------------- * 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 - 1) relname[NAMEDATALEN - 1] = '\0'; if (Typ == (struct typmap **) NULL) { rel = heap_openr(TypeRelationName, NoLock); scan = heap_beginscan(rel, SnapshotNow, 0, (ScanKey) 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 = (struct typmap *) NULL; scan = heap_beginscan(rel, SnapshotNow, 0, (ScanKey) 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 ? relname : "(null)", (int) ATTRIBUTE_TUPLE_SIZE); boot_reldesc = heap_openr(relname, NoLock); numattr = boot_reldesc->rd_rel->relnatts; for (i = 0; i < numattr; i++) { if (attrtypes[i] == NULL) attrtypes[i] = AllocateAttribute(); memmove((char *) attrtypes[i], (char *) boot_reldesc->rd_att->attrs[i], ATTRIBUTE_TUPLE_SIZE); { Form_pg_attribute at = attrtypes[i]; elog(DEBUG4, "create attribute %d name %s len %d num %d type %u", i, NameStr(at->attname), at->attlen, at->attnum, at->atttypid); } }}/* ---------------- * closerel * ---------------- */voidcloserel(char *name){ if (name) { if (boot_reldesc) { if (strcmp(RelationGetRelationName(boot_reldesc), name) != 0) elog(ERROR, "close of %s when %s was expected", name, relname ? relname : "(null)"); } else elog(ERROR, "close of %s before any relation was opened", name); } if (boot_reldesc == NULL) elog(ERROR, "no open relation to close"); else { elog(DEBUG4, "close relation %s", relname ? relname : "(null)"); heap_close(boot_reldesc, NoLock); boot_reldesc = (Relation) NULL; }}/* ---------------- * DEFINEATTR() * * define a <field,type> pair * if there are n fields in a relation to be created, this routine * will be called n times * ---------------- */voidDefineAttr(char *name, char *type, int attnum){ int attlen; Oid typeoid; if (boot_reldesc != NULL) { elog(WARNING, "no open relations allowed with CREATE command"); closerel(relname); } if (attrtypes[attnum] == (Form_pg_attribute) NULL) attrtypes[attnum] = AllocateAttribute(); MemSet(attrtypes[attnum], 0, ATTRIBUTE_TUPLE_SIZE); namestrcpy(&attrtypes[attnum]->attname, name); elog(DEBUG4, "column %s %s", NameStr(attrtypes[attnum]->attname), type); attrtypes[attnum]->attnum = attnum + 1; /* fillatt */ typeoid = gettype(type); if (Typ != (struct typmap **) NULL) { attrtypes[attnum]->atttypid = Ap->am_oid; attlen = attrtypes[attnum]->attlen = Ap->am_typ.typlen; attrtypes[attnum]->attbyval = Ap->am_typ.typbyval; attrtypes[attnum]->attstorage = Ap->am_typ.typstorage; attrtypes[attnum]->attalign = Ap->am_typ.typalign; } else { attrtypes[attnum]->atttypid = Procid[typeoid].oid; attlen = attrtypes[attnum]->attlen = Procid[typeoid].len; /* * Cheat like mad to fill in these items from the length only. * This only has to work for types that appear in Procid[]. */ switch (attlen) { case 1: attrtypes[attnum]->attbyval = true; attrtypes[attnum]->attstorage = 'p'; attrtypes[attnum]->attalign = 'c'; break; case 2: attrtypes[attnum]->attbyval = true; attrtypes[attnum]->attstorage = 'p'; attrtypes[attnum]->attalign = 's'; break; case 4: attrtypes[attnum]->attbyval = true; attrtypes[attnum]->attstorage = 'p'; attrtypes[attnum]->attalign = 'i'; break; case -1: attrtypes[attnum]->attbyval = false; attrtypes[attnum]->attstorage = 'x'; attrtypes[attnum]->attalign = 'i'; break; default: /* TID and fixed-length arrays, such as oidvector */ attrtypes[attnum]->attbyval = false; attrtypes[attnum]->attstorage = 'p'; attrtypes[attnum]->attalign = 'i'; break; } } attrtypes[attnum]->attcacheoff = -1; attrtypes[attnum]->atttypmod = -1; attrtypes[attnum]->attislocal = true; /* * Mark as "not null" if type is fixed-width and prior columns are * too. This corresponds to case where column can be accessed directly * via C struct declaration. */ if (attlen > 0) { int i; for (i = 0; i < attnum; i++) { if (attrtypes[i]->attlen <= 0) break; } if (i == attnum) attrtypes[attnum]->attnotnull = true; }}/* ---------------- * InsertOneTuple * * If objectid is not zero, it is a specific OID to assign to the tuple. * Otherwise, an OID will be assigned (if necessary) by heap_insert. * ---------------- */voidInsertOneTuple(Oid objectid){ HeapTuple tuple; TupleDesc tupDesc; int i; elog(DEBUG4, "inserting row oid %u, %d columns", objectid, numattr); tupDesc = CreateTupleDesc(numattr, RelationGetForm(boot_reldesc)->relhasoids, attrtypes); tuple = heap_formtuple(tupDesc, values, Blanks); if (objectid != (Oid) 0) HeapTupleSetOid(tuple, objectid); pfree(tupDesc); /* just free's tupDesc, not the attrtypes */ simple_heap_insert(boot_reldesc, tuple); heap_freetuple(tuple); elog(DEBUG4, "row inserted"); /* * Reset blanks for next tuple */ for (i = 0; i < numattr; i++) Blanks[i] = ' ';}/* ---------------- * InsertOneValue * ---------------- */voidInsertOneValue(char *value, int i){ int typeindex; char *prt; struct typmap **app; AssertArg(i >= 0 || i < MAXATTR); elog(DEBUG4, "inserting column %d value \"%s\"", i, value); if (Typ != (struct typmap **) NULL) { struct typmap *ap; elog(DEBUG4, "Typ != NULL"); app = Typ; while (*app && (*app)->am_oid != boot_reldesc->rd_att->attrs[i]->atttypid) ++app; ap = *app; if (ap == NULL) { elog(FATAL, "could not find atttypid %u in Typ list", boot_reldesc->rd_att->attrs[i]->atttypid); } values[i] = OidFunctionCall3(ap->am_typ.typinput, CStringGetDatum(value), ObjectIdGetDatum(ap->am_typ.typelem), Int32GetDatum(-1)); prt = DatumGetCString(OidFunctionCall3(ap->am_typ.typoutput, values[i], ObjectIdGetDatum(ap->am_typ.typelem), Int32GetDatum(-1))); elog(DEBUG4, " -> %s", prt); pfree(prt); } else { for (typeindex = 0; typeindex < n_types; typeindex++) { if (Procid[typeindex].oid == attrtypes[i]->atttypid) break; } if (typeindex >= n_types) elog(ERROR, "type oid %u not found", attrtypes[i]->atttypid); elog(DEBUG4, "Typ == NULL, typeindex = %u", typeindex); values[i] = OidFunctionCall3(Procid[typeindex].inproc, CStringGetDatum(value), ObjectIdGetDatum(Procid[typeindex].elem), Int32GetDatum(-1)); prt = DatumGetCString(OidFunctionCall3(Procid[typeindex].outproc, values[i], ObjectIdGetDatum(Procid[typeindex].elem), Int32GetDatum(-1))); elog(DEBUG4, " -> %s", prt); pfree(prt); } elog(DEBUG4, "inserted");}/* ---------------- * InsertOneNull * ---------------- */voidInsertOneNull(int i){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -