#include "postgres_fe.h"
#include "pg_dump.h"
#include "dumputils.h"
#include "libpq-fe.h"
Go to the source code of this file.
Data Structures | |
struct | Archive |
struct | _restoreOptions |
Defines | |
#define | atooid(x) ((Oid) strtoul((x), NULL, 10)) |
#define | oidcmp(x, y) ( ((x) < (y) ? -1 : ((x) > (y)) ? 1 : 0) ) |
#define | oideq(x, y) ( (x) == (y) ) |
#define | oidle(x, y) ( (x) <= (y) ) |
#define | oidge(x, y) ( (x) >= (y) ) |
#define | oidzero(x) ( (x) == 0 ) |
#define | appendStringLiteralAH(buf, str, AH) appendStringLiteral(buf, str, (AH)->encoding, (AH)->std_strings) |
Typedefs | |
typedef enum _archiveFormat | ArchiveFormat |
typedef enum _archiveMode | ArchiveMode |
typedef enum _teSection | teSection |
typedef int(* | DataDumperPtr )(Archive *AH, void *userArg) |
typedef struct _restoreOptions | RestoreOptions |
typedef void(* | SetupWorkerPtr )(Archive *AH, RestoreOptions *ropt) |
Enumerations | |
enum | trivalue { TRI_DEFAULT, TRI_NO, TRI_YES, TRI_DEFAULT, TRI_NO, TRI_YES, TRI_DEFAULT, TRI_NO, TRI_YES, TRI_DEFAULT, TRI_NO, TRI_YES } |
enum | _archiveFormat { archUnknown = 0, archCustom = 1, archTar = 3, archNull = 4, archDirectory = 5 } |
enum | _archiveMode { archModeAppend, archModeWrite, archModeRead } |
enum | _teSection { SECTION_NONE = 1, SECTION_PRE_DATA, SECTION_DATA, SECTION_POST_DATA } |
Functions | |
void | ConnectDatabase (Archive *AH, const char *dbname, const char *pghost, const char *pgport, const char *username, enum trivalue prompt_password) |
void | DisconnectDatabase (Archive *AHX) |
PGconn * | GetConnection (Archive *AHX) |
void | ArchiveEntry (Archive *AHX, CatalogId catalogId, DumpId dumpId, const char *tag, const char *namespace, const char *tablespace, const char *owner, bool withOids, const char *desc, teSection section, const char *defn, const char *dropStmt, const char *copyStmt, const DumpId *deps, int nDeps, DataDumperPtr dumpFn, void *dumpArg) |
size_t | WriteData (Archive *AH, const void *data, size_t dLen) |
int | StartBlob (Archive *AH, Oid oid) |
int | EndBlob (Archive *AH, Oid oid) |
void | CloseArchive (Archive *AH) |
void | SetArchiveRestoreOptions (Archive *AH, RestoreOptions *ropt) |
void | RestoreArchive (Archive *AH) |
Archive * | OpenArchive (const char *FileSpec, const ArchiveFormat fmt) |
Archive * | CreateArchive (const char *FileSpec, const ArchiveFormat fmt, const int compression, ArchiveMode mode, SetupWorkerPtr setupDumpWorker) |
void | PrintTOCSummary (Archive *AH, RestoreOptions *ropt) |
RestoreOptions * | NewRestoreOptions (void) |
void | SortTocFromFile (Archive *AHX, RestoreOptions *ropt) |
int | archputs (const char *s, Archive *AH) |
int | archprintf (Archive *AH, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE |
#define appendStringLiteralAH | ( | buf, | ||
str, | ||||
AH | ||||
) | appendStringLiteral(buf, str, (AH)->encoding, (AH)->std_strings) |
Definition at line 216 of file pg_backup.h.
Referenced by createViewAsClause(), dumpAgg(), dumpBaseType(), dumpCollation(), dumpComment(), dumpCompositeType(), dumpCompositeTypeColComments(), dumpConversion(), dumpDatabase(), dumpDomain(), dumpEncoding(), dumpEnumType(), dumpExtension(), dumpForeignServer(), dumpFunc(), dumpSecLabel(), dumpSequenceData(), dumpTableComment(), dumpTableData_insert(), dumpTableSchema(), dumpTableSecLabel(), dumpTrigger(), and findLastBuiltinOid_V71().
#define atooid | ( | x | ) | ((Oid) strtoul((x), NULL, 10)) |
Definition at line 34 of file pg_backup.h.
#define oidcmp | ( | x, | ||
y | ||||
) | ( ((x) < (y) ? -1 : ((x) > (y)) ? 1 : 0) ) |
Definition at line 35 of file pg_backup.h.
Referenced by DOCatalogIdCompare(), DOTypeNameCompare(), DOTypeOidCompare(), findObjectByCatalogId(), and findObjectByOid().
#define oideq | ( | x, | ||
y | ||||
) | ( (x) == (y) ) |
Definition at line 36 of file pg_backup.h.
#define oidge | ( | x, | ||
y | ||||
) | ( (x) >= (y) ) |
Definition at line 38 of file pg_backup.h.
#define oidle | ( | x, | ||
y | ||||
) | ( (x) <= (y) ) |
Definition at line 37 of file pg_backup.h.
#define oidzero | ( | x | ) | ( (x) == 0 ) |
Definition at line 39 of file pg_backup.h.
typedef enum _archiveFormat ArchiveFormat |
typedef enum _archiveMode ArchiveMode |
typedef int(* DataDumperPtr)(Archive *AH, void *userArg) |
Definition at line 101 of file pg_backup.h.
typedef struct _restoreOptions RestoreOptions |
typedef void(* SetupWorkerPtr)(Archive *AH, RestoreOptions *ropt) |
Definition at line 154 of file pg_backup.h.
typedef enum _teSection teSection |
enum _archiveFormat |
Definition at line 48 of file pg_backup.h.
{ archUnknown = 0, archCustom = 1, archTar = 3, archNull = 4, archDirectory = 5 } ArchiveFormat;
enum _archiveMode |
Definition at line 57 of file pg_backup.h.
{ archModeAppend, archModeWrite, archModeRead } ArchiveMode;
enum _teSection |
Definition at line 64 of file pg_backup.h.
{ SECTION_NONE = 1, /* COMMENTs, ACLs, etc; can be anywhere */ SECTION_PRE_DATA, /* stuff to be processed before data */ SECTION_DATA, /* TABLE DATA, BLOBS, BLOB COMMENTS */ SECTION_POST_DATA /* stuff to be processed after data */ } teSection;
enum trivalue |
TRI_DEFAULT | |
TRI_NO | |
TRI_YES | |
TRI_DEFAULT | |
TRI_NO | |
TRI_YES | |
TRI_DEFAULT | |
TRI_NO | |
TRI_YES | |
TRI_DEFAULT | |
TRI_NO | |
TRI_YES |
Definition at line 41 of file pg_backup.h.
{ TRI_DEFAULT, TRI_NO, TRI_YES };
void ArchiveEntry | ( | Archive * | AHX, | |
CatalogId | catalogId, | |||
DumpId | dumpId, | |||
const char * | tag, | |||
const char * | namespace, | |||
const char * | tablespace, | |||
const char * | owner, | |||
bool | withOids, | |||
const char * | desc, | |||
teSection | section, | |||
const char * | defn, | |||
const char * | dropStmt, | |||
const char * | copyStmt, | |||
const DumpId * | deps, | |||
int | nDeps, | |||
DataDumperPtr | dumpFn, | |||
void * | dumpArg | |||
) |
Definition at line 803 of file pg_backup_archiver.c.
References _archiveHandle::ArchiveEntryPtr, _tocEntry::catalogId, _tocEntry::dataDumper, _tocEntry::dataDumperArg, _tocEntry::dependencies, _tocEntry::dumpId, _tocEntry::formatData, _tocEntry::hadDumper, _archiveHandle::maxDumpId, _tocEntry::nDeps, _tocEntry::next, NULL, pg_malloc(), pg_malloc0(), pg_strdup(), _tocEntry::prev, _tocEntry::section, _tocEntry::tag, _archiveHandle::toc, and _archiveHandle::tocCount.
Referenced by dumpACL(), dumpAgg(), dumpAttrDef(), dumpBaseType(), dumpBlob(), dumpCast(), dumpCollation(), dumpComment(), dumpCompositeType(), dumpCompositeTypeColComments(), dumpConstraint(), dumpConversion(), dumpDatabase(), dumpDefaultACL(), dumpDomain(), dumpDumpableObject(), dumpEncoding(), dumpEnumType(), dumpEventTrigger(), dumpExtension(), dumpForeignDataWrapper(), dumpForeignServer(), dumpFunc(), dumpIndex(), dumpNamespace(), dumpOpclass(), dumpOpfamily(), dumpOpr(), dumpProcLang(), dumpRangeType(), dumpRule(), dumpSecLabel(), dumpSequence(), dumpSequenceData(), dumpShellType(), dumpStdStrings(), dumpTableComment(), dumpTableData(), dumpTableSchema(), dumpTableSecLabel(), dumpTrigger(), dumpTSConfig(), dumpTSDictionary(), dumpTSParser(), dumpTSTemplate(), dumpUserMappings(), and refreshMatViewData().
{ ArchiveHandle *AH = (ArchiveHandle *) AHX; TocEntry *newToc; newToc = (TocEntry *) pg_malloc0(sizeof(TocEntry)); AH->tocCount++; if (dumpId > AH->maxDumpId) AH->maxDumpId = dumpId; newToc->prev = AH->toc->prev; newToc->next = AH->toc; AH->toc->prev->next = newToc; AH->toc->prev = newToc; newToc->catalogId = catalogId; newToc->dumpId = dumpId; newToc->section = section; newToc->tag = pg_strdup(tag); newToc->namespace = namespace ? pg_strdup(namespace) : NULL; newToc->tablespace = tablespace ? pg_strdup(tablespace) : NULL; newToc->owner = pg_strdup(owner); newToc->withOids = withOids; newToc->desc = pg_strdup(desc); newToc->defn = pg_strdup(defn); newToc->dropStmt = pg_strdup(dropStmt); newToc->copyStmt = copyStmt ? pg_strdup(copyStmt) : NULL; if (nDeps > 0) { newToc->dependencies = (DumpId *) pg_malloc(nDeps * sizeof(DumpId)); memcpy(newToc->dependencies, deps, nDeps * sizeof(DumpId)); newToc->nDeps = nDeps; } else { newToc->dependencies = NULL; newToc->nDeps = 0; } newToc->dataDumper = dumpFn; newToc->dataDumperArg = dumpArg; newToc->hadDumper = dumpFn ? true : false; newToc->formatData = NULL; if (AH->ArchiveEntryPtr !=NULL) (*AH->ArchiveEntryPtr) (AH, newToc); }
int archprintf | ( | Archive * | AH, | |
const char * | fmt, | |||
... | ||||
) |
Referenced by dumpTableData_copy(), and dumpTableData_insert().
int archputs | ( | const char * | s, | |
Archive * | AH | |||
) |
Definition at line 1174 of file pg_backup_archiver.c.
References WriteData().
Referenced by dumpTableData_insert().
{ return WriteData(AH, s, strlen(s)); }
void CloseArchive | ( | Archive * | AH | ) |
Definition at line 155 of file pg_backup_archiver.c.
References _archiveHandle::ClosePtr, exit_horribly(), GZCLOSE, _archiveHandle::gzOut, modulename, _archiveHandle::OF, and strerror().
Referenced by main().
{ int res = 0; ArchiveHandle *AH = (ArchiveHandle *) AHX; (*AH->ClosePtr) (AH); /* Close the output */ if (AH->gzOut) res = GZCLOSE(AH->OF); else if (AH->OF != stdout) res = fclose(AH->OF); if (res != 0) exit_horribly(modulename, "could not close output file: %s\n", strerror(errno)); }
void ConnectDatabase | ( | Archive * | AH, | |
const char * | dbname, | |||
const char * | pghost, | |||
const char * | pgport, | |||
const char * | username, | |||
enum trivalue | prompt_password | |||
) |
Definition at line 215 of file pg_backup_db.c.
References _check_database_version(), _archiveHandle::connection, CONNECTION_BAD, exit_horribly(), free, modulename, notice_processor(), NULL, PARAMS_ARRAY_SIZE, pg_malloc(), PQconnectdbParams(), PQconnectionNeedsPassword(), PQdb(), PQerrorMessage(), PQfinish(), PQsetNoticeProcessor(), PQstatus(), progname, _archiveHandle::promptPassword, _archiveHandle::savedPassword, simple_prompt(), TRI_NO, TRI_YES, and values.
Referenced by CloneArchive(), main(), restore_toc_entries_postfork(), and RestoreArchive().
{ ArchiveHandle *AH = (ArchiveHandle *) AHX; char *password = AH->savedPassword; bool new_pass; if (AH->connection) exit_horribly(modulename, "already connected to a database\n"); if (prompt_password == TRI_YES && password == NULL) { password = simple_prompt("Password: ", 100, false); if (password == NULL) exit_horribly(modulename, "out of memory\n"); } AH->promptPassword = prompt_password; /* * Start the connection. Loop until we have a password if requested by * backend. */ do { #define PARAMS_ARRAY_SIZE 7 const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords)); const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values)); keywords[0] = "host"; values[0] = pghost; keywords[1] = "port"; values[1] = pgport; keywords[2] = "user"; values[2] = username; keywords[3] = "password"; values[3] = password; keywords[4] = "dbname"; values[4] = dbname; keywords[5] = "fallback_application_name"; values[5] = progname; keywords[6] = NULL; values[6] = NULL; new_pass = false; AH->connection = PQconnectdbParams(keywords, values, true); free(keywords); free(values); if (!AH->connection) exit_horribly(modulename, "failed to connect to database\n"); if (PQstatus(AH->connection) == CONNECTION_BAD && PQconnectionNeedsPassword(AH->connection) && password == NULL && prompt_password != TRI_NO) { PQfinish(AH->connection); password = simple_prompt("Password: ", 100, false); if (password == NULL) exit_horribly(modulename, "out of memory\n"); new_pass = true; } } while (new_pass); AH->savedPassword = password; /* check to see that the backend connection was successfully made */ if (PQstatus(AH->connection) == CONNECTION_BAD) exit_horribly(modulename, "connection to database \"%s\" failed: %s", PQdb(AH->connection) ? PQdb(AH->connection) : "", PQerrorMessage(AH->connection)); /* check for version mismatch */ _check_database_version(AH); PQsetNoticeProcessor(AH->connection, notice_processor, NULL); }
Archive* CreateArchive | ( | const char * | FileSpec, | |
const ArchiveFormat | fmt, | |||
const int | compression, | |||
ArchiveMode | mode, | |||
SetupWorkerPtr | setupDumpWorker | |||
) |
Definition at line 134 of file pg_backup_archiver.c.
References _allocAH().
Referenced by main().
{ ArchiveHandle *AH = _allocAH(FileSpec, fmt, compression, mode, setupDumpWorker); return (Archive *) AH; }
void DisconnectDatabase | ( | Archive * | AHX | ) |
Definition at line 303 of file pg_backup_db.c.
References _archiveHandle::connection, PQcancel(), PQfinish(), PQfreeCancel(), PQgetCancel(), and PQtransactionStatus().
Referenced by archive_close_connection(), restore_toc_entries_prefork(), and RestoreArchive().
{ ArchiveHandle *AH = (ArchiveHandle *) AHX; PGcancel *cancel; char errbuf[1]; if (!AH->connection) return; if (PQtransactionStatus(AH->connection) == PQTRANS_ACTIVE) { if ((cancel = PQgetCancel(AH->connection))) { PQcancel(cancel, errbuf, sizeof(errbuf)); PQfreeCancel(cancel); } } PQfinish(AH->connection); AH->connection = NULL; }
Definition at line 954 of file pg_backup_archiver.c.
References _archiveHandle::currToc, and _archiveHandle::EndBlobPtr.
Referenced by dumpBlobs().
{ ArchiveHandle *AH = (ArchiveHandle *) AHX; if (AH->EndBlobPtr) (*AH->EndBlobPtr) (AH, AH->currToc, oid); return 1; }
Definition at line 326 of file pg_backup_db.c.
References _archiveHandle::connection.
{ ArchiveHandle *AH = (ArchiveHandle *) AHX; return AH->connection; }
RestoreOptions* NewRestoreOptions | ( | void | ) |
Definition at line 714 of file pg_backup_archiver.c.
References _restoreOptions::dumpSections, _restoreOptions::format, pg_malloc0(), and _restoreOptions::promptPassword.
Referenced by _CloseArchive(), and main().
{ RestoreOptions *opts; opts = (RestoreOptions *) pg_malloc0(sizeof(RestoreOptions)); /* set any fields that shouldn't default to zeroes */ opts->format = archUnknown; opts->promptPassword = TRI_DEFAULT; opts->dumpSections = DUMP_UNSECTIONED; return opts; }
Archive* OpenArchive | ( | const char * | FileSpec, | |
const ArchiveFormat | fmt | |||
) |
Definition at line 146 of file pg_backup_archiver.c.
References _allocAH(), archModeRead, and setupRestoreWorker().
Referenced by main().
{ ArchiveHandle *AH = _allocAH(FileSpec, fmt, 0, archModeRead, setupRestoreWorker); return (Archive *) AH; }
void PrintTOCSummary | ( | Archive * | AH, | |
RestoreOptions * | ropt | |||
) |
Definition at line 867 of file pg_backup_archiver.c.
References _tocEntryRequired(), ahprintf(), archCustom, _archiveHandle::archdbname, _archiveHandle::archiveDumpVersion, _archiveHandle::archiveRemoteVersion, archTar, _tocEntry::catalogId, _archiveHandle::compression, _archiveHandle::createDate, _tocEntry::dependencies, _tocEntry::desc, _tocEntry::dumpId, _restoreOptions::filename, _archiveHandle::format, i, _archiveHandle::intSize, _tocEntry::nDeps, _tocEntry::next, _archiveHandle::offSize, CatalogId::oid, _tocEntry::owner, REQ_DATA, REQ_SCHEMA, RestoreOutput(), SaveOutput(), _tocEntry::section, SECTION_NONE, SetOutput(), CatalogId::tableoid, _tocEntry::tag, _archiveHandle::toc, _archiveHandle::tocCount, _restoreOptions::verbose, _archiveHandle::vmaj, _archiveHandle::vmin, and _archiveHandle::vrev.
Referenced by main().
{ ArchiveHandle *AH = (ArchiveHandle *) AHX; TocEntry *te; teSection curSection; OutputContext sav; const char *fmtName; sav = SaveOutput(AH); if (ropt->filename) SetOutput(AH, ropt->filename, 0 /* no compression */ ); ahprintf(AH, ";\n; Archive created at %s", ctime(&AH->createDate)); ahprintf(AH, "; dbname: %s\n; TOC Entries: %d\n; Compression: %d\n", AH->archdbname, AH->tocCount, AH->compression); switch (AH->format) { case archCustom: fmtName = "CUSTOM"; break; case archTar: fmtName = "TAR"; break; default: fmtName = "UNKNOWN"; } ahprintf(AH, "; Dump Version: %d.%d-%d\n", AH->vmaj, AH->vmin, AH->vrev); ahprintf(AH, "; Format: %s\n", fmtName); ahprintf(AH, "; Integer: %d bytes\n", (int) AH->intSize); ahprintf(AH, "; Offset: %d bytes\n", (int) AH->offSize); if (AH->archiveRemoteVersion) ahprintf(AH, "; Dumped from database version: %s\n", AH->archiveRemoteVersion); if (AH->archiveDumpVersion) ahprintf(AH, "; Dumped by pg_dump version: %s\n", AH->archiveDumpVersion); ahprintf(AH, ";\n;\n; Selected TOC Entries:\n;\n"); curSection = SECTION_PRE_DATA; for (te = AH->toc->next; te != AH->toc; te = te->next) { if (te->section != SECTION_NONE) curSection = te->section; if (ropt->verbose || (_tocEntryRequired(te, curSection, ropt) & (REQ_SCHEMA | REQ_DATA)) != 0) ahprintf(AH, "%d; %u %u %s %s %s %s\n", te->dumpId, te->catalogId.tableoid, te->catalogId.oid, te->desc, te->namespace ? te->namespace : "-", te->tag, te->owner); if (ropt->verbose && te->nDeps > 0) { int i; ahprintf(AH, ";\tdepends on:"); for (i = 0; i < te->nDeps; i++) ahprintf(AH, " %d", te->dependencies[i]); ahprintf(AH, "\n"); } } if (ropt->filename) RestoreOutput(AH, sav); }
void RestoreArchive | ( | Archive * | AH | ) |
Definition at line 230 of file pg_backup_archiver.c.
References _becomeOwner(), _doSetFixedOutputState(), _printTocEntry(), _selectOutputSchema(), ahlog(), ahprintf(), _archiveHandle::archiveDumpVersion, _archiveHandle::archiveRemoteVersion, Assert, buildTocEntryArrays(), _archiveHandle::ClonePtr, CommitTransaction(), _restoreOptions::compression, _archiveHandle::compression, ConnectDatabase(), _archiveHandle::connection, _archiveHandle::createDate, _restoreOptions::createDB, _archiveHandle::currentTE, _archiveHandle::currSchema, _restoreOptions::dataOnly, _restoreOptions::dbname, _tocEntry::desc, DisconnectDatabase(), _restoreOptions::dropSchema, _tocEntry::dropStmt, dumpTimestamp(), exit_horribly(), _restoreOptions::filename, free, _tocEntry::hadDumper, K_VERS_1_3, K_VERS_1_8, Archive::maxRemoteVersion, Archive::minRemoteVersion, modulename, _tocEntry::next, _archiveHandle::noTocComments, NULL, Archive::numWorkers, par_list_header_init(), ParallelBackupEnd(), ParallelBackupStart(), _restoreOptions::pghost, _restoreOptions::pgport, _tocEntry::prev, _archiveHandle::PrintTocDataPtr, _restoreOptions::promptPassword, _archiveHandle::public, _archiveHandle::ReopenPtr, REQ_DATA, REQ_SCHEMA, _tocEntry::reqs, restore_toc_entries_parallel(), restore_toc_entries_postfork(), restore_toc_entries_prefork(), restore_toc_entry(), RestoreOutput(), _archiveHandle::ropt, SaveOutput(), SetOutput(), _restoreOptions::single_txn, _archiveHandle::stage, StartTransaction(), _tocEntry::tag, _archiveHandle::toc, _archiveHandle::tocsByDumpId, _restoreOptions::useDB, _restoreOptions::username, Archive::verbose, and _archiveHandle::version.
Referenced by _CloseArchive(), and main().
{ ArchiveHandle *AH = (ArchiveHandle *) AHX; RestoreOptions *ropt = AH->ropt; bool parallel_mode; TocEntry *te; OutputContext sav; AH->stage = STAGE_INITIALIZING; /* * Check for nonsensical option combinations. * * -C is not compatible with -1, because we can't create a database inside * a transaction block. */ if (ropt->createDB && ropt->single_txn) exit_horribly(modulename, "-C and -1 are incompatible options\n"); /* * If we're going to do parallel restore, there are some restrictions. */ parallel_mode = (AH->public.numWorkers > 1 && ropt->useDB); if (parallel_mode) { /* We haven't got round to making this work for all archive formats */ if (AH->ClonePtr == NULL || AH->ReopenPtr == NULL) exit_horribly(modulename, "parallel restore is not supported with this archive file format\n"); /* Doesn't work if the archive represents dependencies as OIDs */ if (AH->version < K_VERS_1_8) exit_horribly(modulename, "parallel restore is not supported with archives made by pre-8.0 pg_dump\n"); /* * It's also not gonna work if we can't reopen the input file, so * let's try that immediately. */ (AH->ReopenPtr) (AH); } /* * Make sure we won't need (de)compression we haven't got */ #ifndef HAVE_LIBZ if (AH->compression != 0 && AH->PrintTocDataPtr !=NULL) { for (te = AH->toc->next; te != AH->toc; te = te->next) { if (te->hadDumper && (te->reqs & REQ_DATA) != 0) exit_horribly(modulename, "cannot restore from compressed archive (compression not supported in this installation)\n"); } } #endif /* * Prepare index arrays, so we can assume we have them throughout restore. * It's possible we already did this, though. */ if (AH->tocsByDumpId == NULL) buildTocEntryArrays(AH); /* * If we're using a DB connection, then connect it. */ if (ropt->useDB) { ahlog(AH, 1, "connecting to database for restore\n"); if (AH->version < K_VERS_1_3) exit_horribly(modulename, "direct database connections are not supported in pre-1.3 archives\n"); /* XXX Should get this from the archive */ AHX->minRemoteVersion = 070100; AHX->maxRemoteVersion = 999999; ConnectDatabase(AHX, ropt->dbname, ropt->pghost, ropt->pgport, ropt->username, ropt->promptPassword); /* * If we're talking to the DB directly, don't send comments since they * obscure SQL when displaying errors */ AH->noTocComments = 1; } /* * Work out if we have an implied data-only restore. This can happen if * the dump was data only or if the user has used a toc list to exclude * all of the schema data. All we do is look for schema entries - if none * are found then we set the dataOnly flag. * * We could scan for wanted TABLE entries, but that is not the same as * dataOnly. At this stage, it seems unnecessary (6-Mar-2001). */ if (!ropt->dataOnly) { int impliedDataOnly = 1; for (te = AH->toc->next; te != AH->toc; te = te->next) { if ((te->reqs & REQ_SCHEMA) != 0) { /* It's schema, and it's wanted */ impliedDataOnly = 0; break; } } if (impliedDataOnly) { ropt->dataOnly = impliedDataOnly; ahlog(AH, 1, "implied data-only restore\n"); } } /* * Setup the output file if necessary. */ sav = SaveOutput(AH); if (ropt->filename || ropt->compression) SetOutput(AH, ropt->filename, ropt->compression); ahprintf(AH, "--\n-- PostgreSQL database dump\n--\n\n"); if (AH->public.verbose) { if (AH->archiveRemoteVersion) ahprintf(AH, "-- Dumped from database version %s\n", AH->archiveRemoteVersion); if (AH->archiveDumpVersion) ahprintf(AH, "-- Dumped by pg_dump version %s\n", AH->archiveDumpVersion); dumpTimestamp(AH, "Started on", AH->createDate); } if (ropt->single_txn) { if (AH->connection) StartTransaction(AH); else ahprintf(AH, "BEGIN;\n\n"); } /* * Establish important parameter values right away. */ _doSetFixedOutputState(AH); AH->stage = STAGE_PROCESSING; /* * Drop the items at the start, in reverse order */ if (ropt->dropSchema) { for (te = AH->toc->prev; te != AH->toc; te = te->prev) { AH->currentTE = te; /* * In createDB mode, issue a DROP *only* for the database as a * whole. Issuing drops against anything else would be wrong, * because at this point we're connected to the wrong database. * Conversely, if we're not in createDB mode, we'd better not * issue a DROP against the database at all. */ if (ropt->createDB) { if (strcmp(te->desc, "DATABASE") != 0) continue; } else { if (strcmp(te->desc, "DATABASE") == 0) continue; } /* Otherwise, drop anything that's selected and has a dropStmt */ if (((te->reqs & (REQ_SCHEMA | REQ_DATA)) != 0) && te->dropStmt) { ahlog(AH, 1, "dropping %s %s\n", te->desc, te->tag); /* Select owner and schema as necessary */ _becomeOwner(AH, te); _selectOutputSchema(AH, te->namespace); /* Drop it */ ahprintf(AH, "%s", te->dropStmt); } } /* * _selectOutputSchema may have set currSchema to reflect the effect * of a "SET search_path" command it emitted. However, by now we may * have dropped that schema; or it might not have existed in the first * place. In either case the effective value of search_path will not * be what we think. Forcibly reset currSchema so that we will * re-establish the search_path setting when needed (after creating * the schema). * * If we treated users as pg_dump'able objects then we'd need to reset * currUser here too. */ if (AH->currSchema) free(AH->currSchema); AH->currSchema = NULL; } /* * In serial mode, we now process each non-ACL TOC entry. * * In parallel mode, turn control over to the parallel-restore logic. */ if (parallel_mode) { ParallelState *pstate; TocEntry pending_list; par_list_header_init(&pending_list); /* This runs PRE_DATA items and then disconnects from the database */ restore_toc_entries_prefork(AH); Assert(AH->connection == NULL); /* ParallelBackupStart() will actually fork the processes */ pstate = ParallelBackupStart(AH, ropt); restore_toc_entries_parallel(AH, pstate, &pending_list); ParallelBackupEnd(AH, pstate); /* reconnect the master and see if we missed something */ restore_toc_entries_postfork(AH, &pending_list); Assert(AH->connection != NULL); } else { for (te = AH->toc->next; te != AH->toc; te = te->next) (void) restore_toc_entry(AH, te, ropt, false); } /* * Scan TOC again to output ownership commands and ACLs */ for (te = AH->toc->next; te != AH->toc; te = te->next) { AH->currentTE = te; /* Both schema and data objects might now have ownership/ACLs */ if ((te->reqs & (REQ_SCHEMA | REQ_DATA)) != 0) { ahlog(AH, 1, "setting owner and privileges for %s %s\n", te->desc, te->tag); _printTocEntry(AH, te, ropt, false, true); } } if (ropt->single_txn) { if (AH->connection) CommitTransaction(AH); else ahprintf(AH, "COMMIT;\n\n"); } if (AH->public.verbose) dumpTimestamp(AH, "Completed on", time(NULL)); ahprintf(AH, "--\n-- PostgreSQL database dump complete\n--\n\n"); /* * Clean up & we're done. */ AH->stage = STAGE_FINALIZING; if (ropt->filename || ropt->compression) RestoreOutput(AH, sav); if (ropt->useDB) DisconnectDatabase(&AH->public); }
void SetArchiveRestoreOptions | ( | Archive * | AH, | |
RestoreOptions * | ropt | |||
) |
Definition at line 175 of file pg_backup_archiver.c.
References _tocEntryRequired(), archModeRead, exit_horribly(), _archiveHandle::mode, modulename, _tocEntry::next, _tocEntry::reqs, _archiveHandle::ropt, _tocEntry::section, SECTION_DATA, SECTION_NONE, SECTION_POST_DATA, SECTION_PRE_DATA, _archiveHandle::toc, and write_msg().
Referenced by main().
{ ArchiveHandle *AH = (ArchiveHandle *) AHX; TocEntry *te; teSection curSection; /* Save options for later access */ AH->ropt = ropt; /* Decide which TOC entries will be dumped/restored, and mark them */ curSection = SECTION_PRE_DATA; for (te = AH->toc->next; te != AH->toc; te = te->next) { /* * When writing an archive, we also take this opportunity to check * that we have generated the entries in a sane order that respects * the section divisions. When reading, don't complain, since buggy * old versions of pg_dump might generate out-of-order archives. */ if (AH->mode != archModeRead) { switch (te->section) { case SECTION_NONE: /* ok to be anywhere */ break; case SECTION_PRE_DATA: if (curSection != SECTION_PRE_DATA) write_msg(modulename, "WARNING: archive items not in correct section order\n"); break; case SECTION_DATA: if (curSection == SECTION_POST_DATA) write_msg(modulename, "WARNING: archive items not in correct section order\n"); break; case SECTION_POST_DATA: /* ok no matter which section we were in */ break; default: exit_horribly(modulename, "unexpected section code %d\n", (int) te->section); break; } } if (te->section != SECTION_NONE) curSection = te->section; te->reqs = _tocEntryRequired(te, curSection, ropt); } }
void SortTocFromFile | ( | Archive * | AHX, | |
RestoreOptions * | ropt | |||
) |
Definition at line 1080 of file pg_backup_archiver.c.
References _moveBefore(), buf, exit_horribly(), getTocEntryByDumpId(), _restoreOptions::idWanted, _archiveHandle::maxDumpId, modulename, NULL, PG_BINARY_R, pg_malloc(), strerror(), _archiveHandle::toc, _restoreOptions::tocFile, and write_msg().
Referenced by main().
{ ArchiveHandle *AH = (ArchiveHandle *) AHX; FILE *fh; char buf[100]; bool incomplete_line; /* Allocate space for the 'wanted' array, and init it */ ropt->idWanted = (bool *) pg_malloc(sizeof(bool) * AH->maxDumpId); memset(ropt->idWanted, 0, sizeof(bool) * AH->maxDumpId); /* Setup the file */ fh = fopen(ropt->tocFile, PG_BINARY_R); if (!fh) exit_horribly(modulename, "could not open TOC file \"%s\": %s\n", ropt->tocFile, strerror(errno)); incomplete_line = false; while (fgets(buf, sizeof(buf), fh) != NULL) { bool prev_incomplete_line = incomplete_line; int buflen; char *cmnt; char *endptr; DumpId id; TocEntry *te; /* * Some lines in the file might be longer than sizeof(buf). This is * no problem, since we only care about the leading numeric ID which * can be at most a few characters; but we have to skip continuation * bufferloads when processing a long line. */ buflen = strlen(buf); if (buflen > 0 && buf[buflen - 1] == '\n') incomplete_line = false; else incomplete_line = true; if (prev_incomplete_line) continue; /* Truncate line at comment, if any */ cmnt = strchr(buf, ';'); if (cmnt != NULL) cmnt[0] = '\0'; /* Ignore if all blank */ if (strspn(buf, " \t\r\n") == strlen(buf)) continue; /* Get an ID, check it's valid and not already seen */ id = strtol(buf, &endptr, 10); if (endptr == buf || id <= 0 || id > AH->maxDumpId || ropt->idWanted[id - 1]) { write_msg(modulename, "WARNING: line ignored: %s\n", buf); continue; } /* Find TOC entry */ te = getTocEntryByDumpId(AH, id); if (!te) exit_horribly(modulename, "could not find entry for ID %d\n", id); /* Mark it wanted */ ropt->idWanted[id - 1] = true; /* * Move each item to the end of the list as it is selected, so that * they are placed in the desired order. Any unwanted items will end * up at the front of the list, which may seem unintuitive but it's * what we need. In an ordinary serial restore that makes no * difference, but in a parallel restore we need to mark unrestored * items' dependencies as satisfied before we start examining * restorable items. Otherwise they could have surprising * side-effects on the order in which restorable items actually get * restored. */ _moveBefore(AH, AH->toc, te); } if (fclose(fh) != 0) exit_horribly(modulename, "could not close TOC file: %s\n", strerror(errno)); }
Definition at line 940 of file pg_backup_archiver.c.
References _archiveHandle::currToc, exit_horribly(), modulename, and _archiveHandle::StartBlobPtr.
Referenced by dumpBlobs().
{ ArchiveHandle *AH = (ArchiveHandle *) AHX; if (!AH->StartBlobPtr) exit_horribly(modulename, "large-object output not supported in chosen format\n"); (*AH->StartBlobPtr) (AH, AH->currToc, oid); return 1; }
size_t WriteData | ( | Archive * | AH, | |
const void * | data, | |||
size_t | dLen | |||
) |
Definition at line 786 of file pg_backup_archiver.c.
References _archiveHandle::currToc, exit_horribly(), modulename, and _archiveHandle::WriteDataPtr.
Referenced by archprintf(), archputs(), dumpBlobs(), and dumpTableData_copy().
{ ArchiveHandle *AH = (ArchiveHandle *) AHX; if (!AH->currToc) exit_horribly(modulename, "internal error -- WriteData cannot be called outside the context of a DataDumper routine\n"); return (*AH->WriteDataPtr) (AH, data, dLen); }