📄 pg_backup_archiver.c
字号:
if (AH->currUser) free(AH->currUser); AH->currUser = strdup(user);}/* * Become the owner of the the given TOC entry object. If * changes in ownership are not allowed, this doesn't do anything. */static void_becomeOwner(ArchiveHandle *AH, TocEntry *te){ if (AH->ropt && (AH->ropt->noOwner || !AH->ropt->use_setsessauth)) return; _becomeUser(AH, te->owner);}/* * Set the proper default_with_oids value for the table. */static void_setWithOids(ArchiveHandle *AH, TocEntry *te){ if (AH->currWithOids != te->withOids) { _doSetWithOids(AH, te->withOids); AH->currWithOids = te->withOids; }}/* * Issue the commands to select the specified schema as the current schema * in the target database. */static void_selectOutputSchema(ArchiveHandle *AH, const char *schemaName){ PQExpBuffer qry; if (!schemaName || *schemaName == '\0' || strcmp(AH->currSchema, schemaName) == 0) return; /* no need to do anything */ qry = createPQExpBuffer(); appendPQExpBuffer(qry, "SET search_path = %s", fmtId(schemaName)); if (strcmp(schemaName, "pg_catalog") != 0) appendPQExpBuffer(qry, ", pg_catalog"); if (RestoringToDB(AH)) { PGresult *res; res = PQexec(AH->connection, qry->data); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) warn_or_die_horribly(AH, modulename, "could not set search_path to \"%s\": %s", schemaName, PQerrorMessage(AH->connection)); PQclear(res); } else ahprintf(AH, "%s;\n\n", qry->data); if (AH->currSchema) free(AH->currSchema); AH->currSchema = strdup(schemaName); destroyPQExpBuffer(qry);}/* * Issue the commands to select the specified tablespace as the current one * in the target database. */static void_selectTablespace(ArchiveHandle *AH, const char *tablespace){ PQExpBuffer qry; const char *want, *have; have = AH->currTablespace; want = tablespace; /* no need to do anything for non-tablespace object */ if (!want) return; if (have && strcmp(want, have) == 0) return; /* no need to do anything */ qry = createPQExpBuffer(); if (strcmp(want, "") == 0) { /* We want the tablespace to be the database's default */ appendPQExpBuffer(qry, "SET default_tablespace = ''"); } else { /* We want an explicit tablespace */ appendPQExpBuffer(qry, "SET default_tablespace = %s", fmtId(want)); } if (RestoringToDB(AH)) { PGresult *res; res = PQexec(AH->connection, qry->data); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) warn_or_die_horribly(AH, modulename, "could not set default_tablespace to %s: %s", fmtId(want), PQerrorMessage(AH->connection)); PQclear(res); } else ahprintf(AH, "%s;\n\n", qry->data); if (AH->currTablespace) free(AH->currTablespace); AH->currTablespace = strdup(want); destroyPQExpBuffer(qry);}/* * Extract an object description for a TOC entry, and append it to buf. * * This is not quite as general as it may seem, since it really only * handles constructing the right thing to put into ALTER ... OWNER TO. * * The whole thing is pretty grotty, but we are kind of stuck since the * information used is all that's available in older dump files. */static void_getObjectDescription(PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH){ const char *type = te->desc; /* Use ALTER TABLE for views and sequences */ if (strcmp(type, "VIEW") == 0 || strcmp(type, "SEQUENCE") == 0) type = "TABLE"; /* objects named by a schema and name */ if (strcmp(type, "CONVERSION") == 0 || strcmp(type, "DOMAIN") == 0 || strcmp(type, "TABLE") == 0 || strcmp(type, "TYPE") == 0) { appendPQExpBuffer(buf, "%s ", type); if (te->namespace && te->namespace[0]) /* is null pre-7.3 */ appendPQExpBuffer(buf, "%s.", fmtId(te->namespace)); /* * Pre-7.3 pg_dump would sometimes (not always) put a fmtId'd name * into te->tag for an index. This check is heuristic, so make its * scope as narrow as possible. */ if (AH->version < K_VERS_1_7 && te->tag[0] == '"' && te->tag[strlen(te->tag) - 1] == '"' && strcmp(type, "INDEX") == 0) appendPQExpBuffer(buf, "%s", te->tag); else appendPQExpBuffer(buf, "%s", fmtId(te->tag)); return; } /* objects named by just a name */ if (strcmp(type, "DATABASE") == 0 || strcmp(type, "SCHEMA") == 0) { appendPQExpBuffer(buf, "%s %s", type, fmtId(te->tag)); return; } /* * These object types require additional decoration. Fortunately, the * information needed is exactly what's in the DROP command. */ if (strcmp(type, "AGGREGATE") == 0 || strcmp(type, "FUNCTION") == 0 || strcmp(type, "OPERATOR") == 0 || strcmp(type, "OPERATOR CLASS") == 0) { /* Chop "DROP " off the front and make a modifiable copy */ char *first = strdup(te->dropStmt + 5); char *last; /* point to last character in string */ last = first + strlen(first) - 1; /* Strip off any ';' or '\n' at the end */ while (last >= first && (*last == '\n' || *last == ';')) last--; *(last + 1) = '\0'; appendPQExpBufferStr(buf, first); free(first); return; } write_msg(modulename, "WARNING: don't know how to set owner for object type %s\n", type);}static void_printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData, bool acl_pass){ /* ACLs are dumped only during acl pass */ if (acl_pass) { if (strcmp(te->desc, "ACL") != 0) return; } else { if (strcmp(te->desc, "ACL") == 0) return; } /* * Avoid dumping the public schema, as it will already be created ... * unless we are using --clean mode, in which case it's been deleted and * we'd better recreate it. */ if (!ropt->dropSchema && strcmp(te->desc, "SCHEMA") == 0 && strcmp(te->tag, "public") == 0) return; /* Select owner, schema, and tablespace as necessary */ _becomeOwner(AH, te); _selectOutputSchema(AH, te->namespace); _selectTablespace(AH, te->tablespace); /* Set up OID mode too */ if (strcmp(te->desc, "TABLE") == 0) _setWithOids(AH, te); /* Emit header comment for item */ if (!AH->noTocComments) { const char *pfx; if (isData) pfx = "Data for "; else pfx = ""; ahprintf(AH, "--\n"); if (AH->public.verbose) { ahprintf(AH, "-- TOC entry %d (class %u OID %u)\n", te->dumpId, te->catalogId.tableoid, te->catalogId.oid); if (te->nDeps > 0) { int i; ahprintf(AH, "-- Dependencies:"); for (i = 0; i < te->nDeps; i++) ahprintf(AH, " %d", te->dependencies[i]); ahprintf(AH, "\n"); } } ahprintf(AH, "-- %sName: %s; Type: %s; Schema: %s; Owner: %s", pfx, te->tag, te->desc, te->namespace ? te->namespace : "-", te->owner); if (te->tablespace) ahprintf(AH, "; Tablespace: %s", te->tablespace); ahprintf(AH, "\n"); if (AH->PrintExtraTocPtr !=NULL) (*AH->PrintExtraTocPtr) (AH, te); ahprintf(AH, "--\n\n"); } /* * Actually print the definition. * * Really crude hack for suppressing AUTHORIZATION clause that old pg_dump * versions put into CREATE SCHEMA. We have to do this when --no-owner * mode is selected. This is ugly, but I see no other good way ... */ if (ropt->noOwner && strcmp(te->desc, "SCHEMA") == 0) { ahprintf(AH, "CREATE SCHEMA %s;\n\n\n", fmtId(te->tag)); } else { if (strlen(te->defn) > 0) ahprintf(AH, "%s\n\n", te->defn); } /* * If we aren't using SET SESSION AUTH to determine ownership, we must * instead issue an ALTER OWNER command. We assume that anything without * a DROP command is not a separately ownable object. All the categories * with DROP commands must appear in one list or the other. */ if (!ropt->noOwner && !ropt->use_setsessauth && strlen(te->owner) > 0 && strlen(te->dropStmt) > 0) { if (strcmp(te->desc, "AGGREGATE") == 0 || strcmp(te->desc, "CONVERSION") == 0 || strcmp(te->desc, "DATABASE") == 0 || strcmp(te->desc, "DOMAIN") == 0 || strcmp(te->desc, "FUNCTION") == 0 || strcmp(te->desc, "OPERATOR") == 0 || strcmp(te->desc, "OPERATOR CLASS") == 0 || strcmp(te->desc, "SCHEMA") == 0 || strcmp(te->desc, "TABLE") == 0 || strcmp(te->desc, "TYPE") == 0 || strcmp(te->desc, "VIEW") == 0 || strcmp(te->desc, "SEQUENCE") == 0) { PQExpBuffer temp = createPQExpBuffer(); appendPQExpBuffer(temp, "ALTER "); _getObjectDescription(temp, te, AH); appendPQExpBuffer(temp, " OWNER TO %s;", fmtId(te->owner)); ahprintf(AH, "%s\n\n", temp->data); destroyPQExpBuffer(temp); } else if (strcmp(te->desc, "CAST") == 0 || strcmp(te->desc, "CHECK CONSTRAINT") == 0 || strcmp(te->desc, "CONSTRAINT") == 0 || strcmp(te->desc, "DEFAULT") == 0 || strcmp(te->desc, "FK CONSTRAINT") == 0 || strcmp(te->desc, "INDEX") == 0 || strcmp(te->desc, "PROCEDURAL LANGUAGE") == 0 || strcmp(te->desc, "RULE") == 0 || strcmp(te->desc, "TRIGGER") == 0) { /* these object types don't have separate owners */ } else { write_msg(modulename, "WARNING: don't know how to set owner for object type %s\n", te->desc); } } /* * If it's an ACL entry, it might contain SET SESSION AUTHORIZATION * commands, so we can no longer assume we know the current auth setting. */ if (strncmp(te->desc, "ACL", 3) == 0) { if (AH->currUser) free(AH->currUser); AH->currUser = NULL; }}voidWriteHead(ArchiveHandle *AH){ struct tm crtm; (*AH->WriteBufPtr) (AH, "PGDMP", 5); /* Magic code */ (*AH->WriteBytePtr) (AH, AH->vmaj); (*AH->WriteBytePtr) (AH, AH->vmin); (*AH->WriteBytePtr) (AH, AH->vrev); (*AH->WriteBytePtr) (AH, AH->intSize); (*AH->WriteBytePtr) (AH, AH->offSize); (*AH->WriteBytePtr) (AH, AH->format);#ifndef HAVE_LIBZ if (AH->compression != 0) write_msg(modulename, "WARNING: requested compression not available in this " "installation -- archive will be uncompressed\n"); AH->compression = 0;#endif WriteInt(AH, AH->compression); crtm = *localtime(&AH->createDate); WriteInt(AH, crtm.tm_sec); WriteInt(AH, crtm.tm_min); WriteInt(AH, crtm.tm_hour); WriteInt(AH, crtm.tm_mday); WriteInt(AH, crtm.tm_mon); WriteInt(AH, crtm.tm_year); WriteInt(AH, crtm.tm_isdst); WriteStr(AH, PQdb(AH->connection)); WriteStr(AH, AH->public.remoteVersionStr); WriteStr(AH, PG_VERSION);}voidReadHead(ArchiveHandle *AH){ char tmpMag[7]; int fmt; struct tm crtm; /* If we haven't already read the header... */ if (!AH->readHeader) { (*AH->ReadBufPtr) (AH, tmpMag, 5); if (strncmp(tmpMag, "PGDMP", 5) != 0) die_horribly(AH, modulename, "did not find magic string in file header\n"); AH->vmaj = (*AH->ReadBytePtr) (AH); AH->vmin = (*AH->ReadBytePtr) (AH); if (AH->vmaj > 1 || ((AH->vmaj == 1) && (AH->vmin > 0))) /* Version > 1.0 */ AH->vrev = (*AH->ReadBytePtr) (AH); else AH->vrev = 0; AH->version = ((AH->vmaj * 256 + AH->vmin) * 256 + AH->vrev) * 256 + 0; if (AH->version < K_VERS_1_0 || AH->version > K_VERS_MAX) die_horribly(AH, modulename, "unsupported version (%d.%d) in file header\n", AH->vmaj, AH->vmin); AH->intSize = (*AH->ReadBytePtr) (AH); if (AH->intSize > 32) die_horribly(AH, modulename, "sanity check on integer size (%lu) failed\n", (unsigned long) AH->intSize); if (AH->intSize > sizeof(int)) write_msg(modulename, "WARNING: archive was made on a machine with larger integers, some operations may fail\n"); if (AH->version >= K_VERS_1_7) AH->offSize = (*AH->ReadBytePtr) (AH); else AH->offSize = AH->intSize; fmt = (*AH->ReadBytePtr) (AH); if (AH->format != fmt) die_horribly(AH, modulename, "expected format (%d) differs from format found in file (%d)\n", AH->format, fmt); } if (AH->version >= K_VERS_1_2) { if (AH->version < K_VERS_1_4) AH->compression = (*AH->ReadBytePtr) (AH); else AH->compression = ReadInt(AH); } else AH->compression = Z_DEFAULT_COMPRESSION;#ifndef HAVE_LIBZ if (AH->compression != 0) write_msg(modulename, "WARNING: archive is compressed, but this installation does not support compression -- no data will be available\n");#endif if (AH->version >= K_VERS_1_4) { crtm.tm_sec = ReadInt(AH); crtm.tm_min = ReadInt(AH); crtm.tm_hour = ReadInt(AH); crtm.tm_mday = ReadInt(AH); crtm.tm_mon = ReadInt(AH); crtm.tm_year = ReadInt(AH); crtm.tm_isdst = ReadInt(AH); AH->archdbname = ReadStr(AH); AH->createDate = mktime(&crtm); if (AH->createDate == (time_t) -1) write_msg(modulename, "WARNING: invalid creation date in header\n"); } if (AH->version >= K_VERS_1_10) { AH->archiveRemoteVersion = ReadStr(AH); AH->archiveDumpVersion = ReadStr(AH); }}/* * checkSeek * check to see if fseek can be performed. */boolcheckSeek(FILE *fp){ if (fseeko(fp, 0, SEEK_CUR) != 0) return false; else if (sizeof(off_t) > sizeof(long)) /* * At this point, off_t is too large for long, so we return based on * whether an off_t version of fseek is available. */#ifdef HAVE_FSEEKO return true;#else return false;#endif else return true;}/* * dumpTimestamp */static voiddumpTimestamp(ArchiveHandle *AH, const char *msg, time_t tim){ char buf[256]; if (strftime(buf, 256, "%Y-%m-%d %H:%M:%S %Z", localtime(&tim)) != 0) ahprintf(AH, "-- %s %s\n\n", msg, buf);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -