PostgreSQL Source Code  git master
pg_backup_archiver.c File Reference
#include "postgres_fe.h"
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include "dumputils.h"
#include "fe_utils/string_utils.h"
#include "libpq/libpq-fs.h"
#include "parallel.h"
#include "pg_backup_archiver.h"
#include "pg_backup_db.h"
#include "pg_backup_utils.h"
Include dependency graph for pg_backup_archiver.c:

Go to the source code of this file.

Data Structures

struct  _outputContext
 
struct  _parallelReadyList
 

Macros

#define TEXT_DUMP_HEADER   "--\n-- PostgreSQL database dump\n--\n\n"
 
#define TEXT_DUMPALL_HEADER   "--\n-- PostgreSQL database cluster dump\n--\n\n"
 

Typedefs

typedef struct _outputContext OutputContext
 
typedef struct _parallelReadyList ParallelReadyList
 

Functions

static ArchiveHandle_allocAH (const char *FileSpec, const ArchiveFormat fmt, const int compression, bool dosync, ArchiveMode mode, SetupWorkerPtrType setupWorkerPtr)
 
static void _getObjectDescription (PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH)
 
static void _printTocEntry (ArchiveHandle *AH, TocEntry *te, bool isData)
 
static char * sanitize_line (const char *str, bool want_hyphen)
 
static void _doSetFixedOutputState (ArchiveHandle *AH)
 
static void _doSetSessionAuth (ArchiveHandle *AH, const char *user)
 
static void _reconnectToDB (ArchiveHandle *AH, const char *dbname)
 
static void _becomeUser (ArchiveHandle *AH, const char *user)
 
static void _becomeOwner (ArchiveHandle *AH, TocEntry *te)
 
static void _selectOutputSchema (ArchiveHandle *AH, const char *schemaName)
 
static void _selectTablespace (ArchiveHandle *AH, const char *tablespace)
 
static void _selectTableAccessMethod (ArchiveHandle *AH, const char *tableam)
 
static void processEncodingEntry (ArchiveHandle *AH, TocEntry *te)
 
static void processStdStringsEntry (ArchiveHandle *AH, TocEntry *te)
 
static void processSearchPathEntry (ArchiveHandle *AH, TocEntry *te)
 
static teReqs _tocEntryRequired (TocEntry *te, teSection curSection, ArchiveHandle *AH)
 
static RestorePass _tocEntryRestorePass (TocEntry *te)
 
static bool _tocEntryIsACL (TocEntry *te)
 
static void _disableTriggersIfNecessary (ArchiveHandle *AH, TocEntry *te)
 
static void _enableTriggersIfNecessary (ArchiveHandle *AH, TocEntry *te)
 
static void buildTocEntryArrays (ArchiveHandle *AH)
 
static void _moveBefore (ArchiveHandle *AH, TocEntry *pos, TocEntry *te)
 
static int _discoverArchiveFormat (ArchiveHandle *AH)
 
static int RestoringToDB (ArchiveHandle *AH)
 
static void dump_lo_buf (ArchiveHandle *AH)
 
static void dumpTimestamp (ArchiveHandle *AH, const char *msg, time_t tim)
 
static void SetOutput (ArchiveHandle *AH, const char *filename, int compression)
 
static OutputContext SaveOutput (ArchiveHandle *AH)
 
static void RestoreOutput (ArchiveHandle *AH, OutputContext savedContext)
 
static int restore_toc_entry (ArchiveHandle *AH, TocEntry *te, bool is_parallel)
 
static void restore_toc_entries_prefork (ArchiveHandle *AH, TocEntry *pending_list)
 
static void restore_toc_entries_parallel (ArchiveHandle *AH, ParallelState *pstate, TocEntry *pending_list)
 
static void restore_toc_entries_postfork (ArchiveHandle *AH, TocEntry *pending_list)
 
static void pending_list_header_init (TocEntry *l)
 
static void pending_list_append (TocEntry *l, TocEntry *te)
 
static void pending_list_remove (TocEntry *te)
 
static void ready_list_init (ParallelReadyList *ready_list, int tocCount)
 
static void ready_list_free (ParallelReadyList *ready_list)
 
static void ready_list_insert (ParallelReadyList *ready_list, TocEntry *te)
 
static void ready_list_remove (ParallelReadyList *ready_list, int i)
 
static void ready_list_sort (ParallelReadyList *ready_list)
 
static int TocEntrySizeCompare (const void *p1, const void *p2)
 
static void move_to_ready_list (TocEntry *pending_list, ParallelReadyList *ready_list, RestorePass pass)
 
static TocEntrypop_next_work_item (ArchiveHandle *AH, ParallelReadyList *ready_list, ParallelState *pstate)
 
static void mark_dump_job_done (ArchiveHandle *AH, TocEntry *te, int status, void *callback_data)
 
static void mark_restore_job_done (ArchiveHandle *AH, TocEntry *te, int status, void *callback_data)
 
static void fix_dependencies (ArchiveHandle *AH)
 
static bool has_lock_conflicts (TocEntry *te1, TocEntry *te2)
 
static void repoint_table_dependencies (ArchiveHandle *AH)
 
static void identify_locking_dependencies (ArchiveHandle *AH, TocEntry *te)
 
static void reduce_dependencies (ArchiveHandle *AH, TocEntry *te, ParallelReadyList *ready_list)
 
static void mark_create_done (ArchiveHandle *AH, TocEntry *te)
 
static void inhibit_data_for_failed_table (ArchiveHandle *AH, TocEntry *te)
 
static void StrictNamesCheck (RestoreOptions *ropt)
 
DumpOptionsNewDumpOptions (void)
 
void InitDumpOptions (DumpOptions *opts)
 
DumpOptionsdumpOptionsFromRestoreOptions (RestoreOptions *ropt)
 
static void setupRestoreWorker (Archive *AHX)
 
ArchiveCreateArchive (const char *FileSpec, const ArchiveFormat fmt, const int compression, bool dosync, ArchiveMode mode, SetupWorkerPtrType setupDumpWorker)
 
ArchiveOpenArchive (const char *FileSpec, const ArchiveFormat fmt)
 
void CloseArchive (Archive *AHX)
 
void SetArchiveOptions (Archive *AH, DumpOptions *dopt, RestoreOptions *ropt)
 
void ProcessArchiveRestoreOptions (Archive *AHX)
 
void RestoreArchive (Archive *AHX)
 
RestoreOptionsNewRestoreOptions (void)
 
void WriteData (Archive *AHX, const void *data, size_t dLen)
 
TocEntryArchiveEntry (Archive *AHX, CatalogId catalogId, DumpId dumpId, ArchiveOpts *opts)
 
void PrintTOCSummary (Archive *AHX)
 
int StartBlob (Archive *AHX, Oid oid)
 
int EndBlob (Archive *AHX, Oid oid)
 
void StartRestoreBlobs (ArchiveHandle *AH)
 
void EndRestoreBlobs (ArchiveHandle *AH)
 
void StartRestoreBlob (ArchiveHandle *AH, Oid oid, bool drop)
 
void EndRestoreBlob (ArchiveHandle *AH, Oid oid)
 
void SortTocFromFile (Archive *AHX)
 
void archputs (const char *s, Archive *AH)
 
int archprintf (Archive *AH, const char *fmt,...)
 
int ahprintf (ArchiveHandle *AH, const char *fmt,...)
 
void ahwrite (const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
 
void warn_or_exit_horribly (ArchiveHandle *AH, const char *fmt,...)
 
TocEntrygetTocEntryByDumpId (ArchiveHandle *AH, DumpId id)
 
teReqs TocIDRequired (ArchiveHandle *AH, DumpId id)
 
size_t WriteOffset (ArchiveHandle *AH, pgoff_t o, int wasSet)
 
int ReadOffset (ArchiveHandle *AH, pgoff_t *o)
 
size_t WriteInt (ArchiveHandle *AH, int i)
 
int ReadInt (ArchiveHandle *AH)
 
size_t WriteStr (ArchiveHandle *AH, const char *c)
 
char * ReadStr (ArchiveHandle *AH)
 
void WriteDataChunks (ArchiveHandle *AH, ParallelState *pstate)
 
void WriteDataChunksForTocEntry (ArchiveHandle *AH, TocEntry *te)
 
void WriteToc (ArchiveHandle *AH)
 
void ReadToc (ArchiveHandle *AH)
 
void WriteHead (ArchiveHandle *AH)
 
void ReadHead (ArchiveHandle *AH)
 
bool checkSeek (FILE *fp)
 
int parallel_restore (ArchiveHandle *AH, TocEntry *te)
 
ArchiveHandleCloneArchive (ArchiveHandle *AH)
 
void DeCloneArchive (ArchiveHandle *AH)
 

Macro Definition Documentation

◆ TEXT_DUMP_HEADER

#define TEXT_DUMP_HEADER   "--\n-- PostgreSQL database dump\n--\n\n"

Definition at line 41 of file pg_backup_archiver.c.

Referenced by _discoverArchiveFormat().

◆ TEXT_DUMPALL_HEADER

#define TEXT_DUMPALL_HEADER   "--\n-- PostgreSQL database cluster dump\n--\n\n"

Definition at line 42 of file pg_backup_archiver.c.

Referenced by _discoverArchiveFormat().

Typedef Documentation

◆ OutputContext

typedef struct _outputContext OutputContext

◆ ParallelReadyList

Function Documentation

◆ _allocAH()

static ArchiveHandle * _allocAH ( const char *  FileSpec,
const ArchiveFormat  fmt,
const int  compression,
bool  dosync,
ArchiveMode  mode,
SetupWorkerPtrType  setupWorkerPtr 
)
static

Definition at line 2275 of file pg_backup_archiver.c.

References _discoverArchiveFormat(), archCustom, archDirectory, _archiveHandle::archiveDumpVersion, archModeWrite, archNull, archTar, archUnknown, _archiveHandle::compression, _archiveHandle::createDate, _archiveHandle::currSchema, _archiveHandle::currTableAm, _archiveHandle::currTablespace, _archiveHandle::currUser, dosync, _archiveHandle::dosync, Archive::encoding, Archive::exit_on_error, fatal, _archiveHandle::format, _archiveHandle::fSpec, _archiveHandle::gzOut, InitArchiveFmt_Custom(), InitArchiveFmt_Directory(), InitArchiveFmt_Null(), InitArchiveFmt_Tar(), _archiveHandle::intSize, K_VERS_SELF, mode, _archiveHandle::mode, Archive::n_errors, _tocEntry::next, _archiveHandle::OF, _archiveHandle::offSize, pg_log_debug, pg_malloc0(), pg_strdup(), pgoff_t, _tocEntry::prev, _archiveHandle::promptPassword, _archiveHandle::public, _archiveHandle::SetupWorkerPtr, _archiveHandle::sqlparse, Archive::std_strings, generate_unaccent_rules::stdout, _archiveHandle::toc, TRI_DEFAULT, and _archiveHandle::version.

Referenced by CreateArchive(), and OpenArchive().

2278 {
2279  ArchiveHandle *AH;
2280 
2281  pg_log_debug("allocating AH for %s, format %d", FileSpec, fmt);
2282 
2283  AH = (ArchiveHandle *) pg_malloc0(sizeof(ArchiveHandle));
2284 
2285  AH->version = K_VERS_SELF;
2286 
2287  /* initialize for backwards compatible string processing */
2288  AH->public.encoding = 0; /* PG_SQL_ASCII */
2289  AH->public.std_strings = false;
2290 
2291  /* sql error handling */
2292  AH->public.exit_on_error = true;
2293  AH->public.n_errors = 0;
2294 
2295  AH->archiveDumpVersion = PG_VERSION;
2296 
2297  AH->createDate = time(NULL);
2298 
2299  AH->intSize = sizeof(int);
2300  AH->offSize = sizeof(pgoff_t);
2301  if (FileSpec)
2302  {
2303  AH->fSpec = pg_strdup(FileSpec);
2304 
2305  /*
2306  * Not used; maybe later....
2307  *
2308  * AH->workDir = pg_strdup(FileSpec); for(i=strlen(FileSpec) ; i > 0 ;
2309  * i--) if (AH->workDir[i-1] == '/')
2310  */
2311  }
2312  else
2313  AH->fSpec = NULL;
2314 
2315  AH->currUser = NULL; /* unknown */
2316  AH->currSchema = NULL; /* ditto */
2317  AH->currTablespace = NULL; /* ditto */
2318  AH->currTableAm = NULL; /* ditto */
2319 
2320  AH->toc = (TocEntry *) pg_malloc0(sizeof(TocEntry));
2321 
2322  AH->toc->next = AH->toc;
2323  AH->toc->prev = AH->toc;
2324 
2325  AH->mode = mode;
2326  AH->compression = compression;
2327  AH->dosync = dosync;
2328 
2329  memset(&(AH->sqlparse), 0, sizeof(AH->sqlparse));
2330 
2331  /* Open stdout with no compression for AH output handle */
2332  AH->gzOut = 0;
2333  AH->OF = stdout;
2334 
2335  /*
2336  * On Windows, we need to use binary mode to read/write non-text files,
2337  * which include all archive formats as well as compressed plain text.
2338  * Force stdin/stdout into binary mode if that is what we are using.
2339  */
2340 #ifdef WIN32
2341  if ((fmt != archNull || compression != 0) &&
2342  (AH->fSpec == NULL || strcmp(AH->fSpec, "") == 0))
2343  {
2344  if (mode == archModeWrite)
2345  _setmode(fileno(stdout), O_BINARY);
2346  else
2347  _setmode(fileno(stdin), O_BINARY);
2348  }
2349 #endif
2350 
2351  AH->SetupWorkerPtr = setupWorkerPtr;
2352 
2353  if (fmt == archUnknown)
2354  AH->format = _discoverArchiveFormat(AH);
2355  else
2356  AH->format = fmt;
2357 
2359 
2360  switch (AH->format)
2361  {
2362  case archCustom:
2364  break;
2365 
2366  case archNull:
2367  InitArchiveFmt_Null(AH);
2368  break;
2369 
2370  case archDirectory:
2372  break;
2373 
2374  case archTar:
2375  InitArchiveFmt_Tar(AH);
2376  break;
2377 
2378  default:
2379  fatal("unrecognized file format \"%d\"", fmt);
2380  }
2381 
2382  return AH;
2383 }
struct _tocEntry * next
static PgChecksumMode mode
Definition: pg_checksums.c:61
#define K_VERS_SELF
static bool dosync
Definition: pg_dump.c:92
void InitArchiveFmt_Tar(ArchiveHandle *AH)
int n_errors
Definition: pg_backup.h:206
int encoding
Definition: pg_backup.h:197
SetupWorkerPtrType SetupWorkerPtr
#define pgoff_t
Definition: win32_port.h:195
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
#define pg_log_debug(...)
Definition: logging.h:91
struct _tocEntry * toc
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
sqlparseInfo sqlparse
struct _tocEntry * prev
ArchiveFormat format
static int _discoverArchiveFormat(ArchiveHandle *AH)
void InitArchiveFmt_Directory(ArchiveHandle *AH)
void InitArchiveFmt_Null(ArchiveHandle *AH)
void InitArchiveFmt_Custom(ArchiveHandle *AH)
#define fatal(...)
bool exit_on_error
Definition: pg_backup.h:205
bool std_strings
Definition: pg_backup.h:198

◆ _becomeOwner()

static void _becomeOwner ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 3280 of file pg_backup_archiver.c.

References _becomeUser(), _restoreOptions::noOwner, _tocEntry::owner, _archiveHandle::public, Archive::ropt, and _restoreOptions::use_setsessauth.

Referenced by _printTocEntry(), restore_toc_entry(), and RestoreArchive().

3281 {
3282  RestoreOptions *ropt = AH->public.ropt;
3283 
3284  if (ropt && (ropt->noOwner || !ropt->use_setsessauth))
3285  return;
3286 
3287  _becomeUser(AH, te->owner);
3288 }
RestoreOptions * ropt
Definition: pg_backup.h:183
static void _becomeUser(ArchiveHandle *AH, const char *user)
int use_setsessauth
Definition: pg_backup.h:68

◆ _becomeUser()

static void _becomeUser ( ArchiveHandle AH,
const char *  user 
)
static

Definition at line 3256 of file pg_backup_archiver.c.

References _doSetSessionAuth(), _archiveHandle::currUser, free, and pg_strdup().

Referenced by _becomeOwner(), _disableTriggersIfNecessary(), and _enableTriggersIfNecessary().

3257 {
3258  if (!user)
3259  user = ""; /* avoid null pointers */
3260 
3261  if (AH->currUser && strcmp(AH->currUser, user) == 0)
3262  return; /* no need to do anything */
3263 
3264  _doSetSessionAuth(AH, user);
3265 
3266  /*
3267  * NOTE: currUser keeps track of what the imaginary session user in our
3268  * script is
3269  */
3270  if (AH->currUser)
3271  free(AH->currUser);
3272  AH->currUser = pg_strdup(user);
3273 }
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static void _doSetSessionAuth(ArchiveHandle *AH, const char *user)
#define free(a)
Definition: header.h:65
static char * user
Definition: pg_regress.c:93

◆ _disableTriggersIfNecessary()

static void _disableTriggersIfNecessary ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 983 of file pg_backup_archiver.c.

References _becomeUser(), ahprintf(), _restoreOptions::dataOnly, _restoreOptions::disable_triggers, fmtQualifiedId(), pg_log_info, _archiveHandle::public, Archive::ropt, _restoreOptions::superuser, and _tocEntry::tag.

Referenced by restore_toc_entry().

984 {
985  RestoreOptions *ropt = AH->public.ropt;
986 
987  /* This hack is only needed in a data-only restore */
988  if (!ropt->dataOnly || !ropt->disable_triggers)
989  return;
990 
991  pg_log_info("disabling triggers for %s", te->tag);
992 
993  /*
994  * Become superuser if possible, since they are the only ones who can
995  * disable constraint triggers. If -S was not given, assume the initial
996  * user identity is a superuser. (XXX would it be better to become the
997  * table owner?)
998  */
999  _becomeUser(AH, ropt->superuser);
1000 
1001  /*
1002  * Disable them.
1003  */
1004  ahprintf(AH, "ALTER TABLE %s DISABLE TRIGGER ALL;\n\n",
1005  fmtQualifiedId(te->namespace, te->tag));
1006 }
RestoreOptions * ropt
Definition: pg_backup.h:183
static void _becomeUser(ArchiveHandle *AH, const char *user)
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
char * superuser
Definition: pg_backup.h:70
const char * fmtQualifiedId(const char *schema, const char *id)
Definition: string_utils.c:145
#define pg_log_info(...)
Definition: logging.h:87
int disable_triggers
Definition: pg_backup.h:66

◆ _discoverArchiveFormat()

static int _discoverArchiveFormat ( ArchiveHandle AH)
static

Definition at line 2075 of file pg_backup_archiver.c.

References archDirectory, archTar, buf, fatal, _archiveHandle::format, free, fseeko, _archiveHandle::fSpec, _archiveHandle::intSize, isValidTarHeader(), K_VERS_1_7, _archiveHandle::lookahead, _archiveHandle::lookaheadLen, _archiveHandle::lookaheadPos, _archiveHandle::lookaheadSize, MAKE_ARCHIVE_VERSION, MAXPGPATH, _archiveHandle::offSize, PG_BINARY_R, pg_log_debug, pg_malloc0(), READ_ERROR_EXIT, _archiveHandle::readHeader, S_ISDIR, S_ISREG, sig, snprintf, stat, TEXT_DUMP_HEADER, TEXT_DUMPALL_HEADER, and _archiveHandle::version.

Referenced by _allocAH().

2076 {
2077  FILE *fh;
2078  char sig[6]; /* More than enough */
2079  size_t cnt;
2080  int wantClose = 0;
2081 
2082  pg_log_debug("attempting to ascertain archive format");
2083 
2084  if (AH->lookahead)
2085  free(AH->lookahead);
2086 
2087  AH->lookaheadSize = 512;
2088  AH->lookahead = pg_malloc0(512);
2089  AH->lookaheadLen = 0;
2090  AH->lookaheadPos = 0;
2091 
2092  if (AH->fSpec)
2093  {
2094  struct stat st;
2095 
2096  wantClose = 1;
2097 
2098  /*
2099  * Check if the specified archive is a directory. If so, check if
2100  * there's a "toc.dat" (or "toc.dat.gz") file in it.
2101  */
2102  if (stat(AH->fSpec, &st) == 0 && S_ISDIR(st.st_mode))
2103  {
2104  char buf[MAXPGPATH];
2105 
2106  if (snprintf(buf, MAXPGPATH, "%s/toc.dat", AH->fSpec) >= MAXPGPATH)
2107  fatal("directory name too long: \"%s\"",
2108  AH->fSpec);
2109  if (stat(buf, &st) == 0 && S_ISREG(st.st_mode))
2110  {
2111  AH->format = archDirectory;
2112  return AH->format;
2113  }
2114 
2115 #ifdef HAVE_LIBZ
2116  if (snprintf(buf, MAXPGPATH, "%s/toc.dat.gz", AH->fSpec) >= MAXPGPATH)
2117  fatal("directory name too long: \"%s\"",
2118  AH->fSpec);
2119  if (stat(buf, &st) == 0 && S_ISREG(st.st_mode))
2120  {
2121  AH->format = archDirectory;
2122  return AH->format;
2123  }
2124 #endif
2125  fatal("directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)",
2126  AH->fSpec);
2127  fh = NULL; /* keep compiler quiet */
2128  }
2129  else
2130  {
2131  fh = fopen(AH->fSpec, PG_BINARY_R);
2132  if (!fh)
2133  fatal("could not open input file \"%s\": %m", AH->fSpec);
2134  }
2135  }
2136  else
2137  {
2138  fh = stdin;
2139  if (!fh)
2140  fatal("could not open input file: %m");
2141  }
2142 
2143  if ((cnt = fread(sig, 1, 5, fh)) != 5)
2144  {
2145  if (ferror(fh))
2146  fatal("could not read input file: %m");
2147  else
2148  fatal("input file is too short (read %lu, expected 5)",
2149  (unsigned long) cnt);
2150  }
2151 
2152  /* Save it, just in case we need it later */
2153  memcpy(&AH->lookahead[0], sig, 5);
2154  AH->lookaheadLen = 5;
2155 
2156  if (strncmp(sig, "PGDMP", 5) == 0)
2157  {
2158  int byteread;
2159  char vmaj,
2160  vmin,
2161  vrev;
2162 
2163  /*
2164  * Finish reading (most of) a custom-format header.
2165  *
2166  * NB: this code must agree with ReadHead().
2167  */
2168  if ((byteread = fgetc(fh)) == EOF)
2169  READ_ERROR_EXIT(fh);
2170 
2171  vmaj = byteread;
2172 
2173  if ((byteread = fgetc(fh)) == EOF)
2174  READ_ERROR_EXIT(fh);
2175 
2176  vmin = byteread;
2177 
2178  /* Save these too... */
2179  AH->lookahead[AH->lookaheadLen++] = vmaj;
2180  AH->lookahead[AH->lookaheadLen++] = vmin;
2181 
2182  /* Check header version; varies from V1.0 */
2183  if (vmaj > 1 || (vmaj == 1 && vmin > 0)) /* Version > 1.0 */
2184  {
2185  if ((byteread = fgetc(fh)) == EOF)
2186  READ_ERROR_EXIT(fh);
2187 
2188  vrev = byteread;
2189  AH->lookahead[AH->lookaheadLen++] = vrev;
2190  }
2191  else
2192  vrev = 0;
2193 
2194  AH->version = MAKE_ARCHIVE_VERSION(vmaj, vmin, vrev);
2195 
2196  if ((AH->intSize = fgetc(fh)) == EOF)
2197  READ_ERROR_EXIT(fh);
2198  AH->lookahead[AH->lookaheadLen++] = AH->intSize;
2199 
2200  if (AH->version >= K_VERS_1_7)
2201  {
2202  if ((AH->offSize = fgetc(fh)) == EOF)
2203  READ_ERROR_EXIT(fh);
2204  AH->lookahead[AH->lookaheadLen++] = AH->offSize;
2205  }
2206  else
2207  AH->offSize = AH->intSize;
2208 
2209  if ((byteread = fgetc(fh)) == EOF)
2210  READ_ERROR_EXIT(fh);
2211 
2212  AH->format = byteread;
2213  AH->lookahead[AH->lookaheadLen++] = AH->format;
2214  }
2215  else
2216  {
2217  /*
2218  * *Maybe* we have a tar archive format file or a text dump ... So,
2219  * read first 512 byte header...
2220  */
2221  cnt = fread(&AH->lookahead[AH->lookaheadLen], 1, 512 - AH->lookaheadLen, fh);
2222  /* read failure is checked below */
2223  AH->lookaheadLen += cnt;
2224 
2225  if (AH->lookaheadLen >= strlen(TEXT_DUMPALL_HEADER) &&
2226  (strncmp(AH->lookahead, TEXT_DUMP_HEADER, strlen(TEXT_DUMP_HEADER)) == 0 ||
2227  strncmp(AH->lookahead, TEXT_DUMPALL_HEADER, strlen(TEXT_DUMPALL_HEADER)) == 0))
2228  {
2229  /*
2230  * looks like it's probably a text format dump. so suggest they
2231  * try psql
2232  */
2233  fatal("input file appears to be a text format dump. Please use psql.");
2234  }
2235 
2236  if (AH->lookaheadLen != 512)
2237  {
2238  if (feof(fh))
2239  fatal("input file does not appear to be a valid archive (too short?)");
2240  else
2241  READ_ERROR_EXIT(fh);
2242  }
2243 
2244  if (!isValidTarHeader(AH->lookahead))
2245  fatal("input file does not appear to be a valid archive");
2246 
2247  AH->format = archTar;
2248  }
2249 
2250  /* If we can't seek, then mark the header as read */
2251  if (fseeko(fh, 0, SEEK_SET) != 0)
2252  {
2253  /*
2254  * NOTE: Formats that use the lookahead buffer can unset this in their
2255  * Init routine.
2256  */
2257  AH->readHeader = 1;
2258  }
2259  else
2260  AH->lookaheadLen = 0; /* Don't bother since we've reset the file */
2261 
2262  /* Close the file */
2263  if (wantClose)
2264  if (fclose(fh) != 0)
2265  fatal("could not close input file: %m");
2266 
2267  return AH->format;
2268 }
#define TEXT_DUMP_HEADER
bool isValidTarHeader(char *header)
#define PG_BINARY_R
Definition: c.h:1222
#define K_VERS_1_7
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
#define pg_log_debug(...)
Definition: logging.h:91
#define MAXPGPATH
#define MAKE_ARCHIVE_VERSION(major, minor, rev)
static char * buf
Definition: pg_test_fsync.c:67
#define S_ISREG(m)
Definition: win32_port.h:299
#define stat(a, b)
Definition: win32_port.h:255
ArchiveFormat format
#define TEXT_DUMPALL_HEADER
static int sig
Definition: pg_ctl.c:84
#define fseeko(stream, offset, origin)
Definition: win32_port.h:201
#define free(a)
Definition: header.h:65
#define fatal(...)
#define S_ISDIR(m)
Definition: win32_port.h:296
#define READ_ERROR_EXIT(fd)
#define snprintf
Definition: port.h:192

◆ _doSetFixedOutputState()

static void _doSetFixedOutputState ( ArchiveHandle AH)
static

Definition at line 3113 of file pg_backup_archiver.c.

References ahprintf(), _restoreOptions::enable_row_security, Archive::encoding, fmtId(), pg_encoding_to_char(), _archiveHandle::public, Archive::ropt, Archive::searchpath, Archive::std_strings, and _restoreOptions::use_role.

Referenced by _reconnectToDB(), CloneArchive(), restore_toc_entries_postfork(), and RestoreArchive().

3114 {
3115  RestoreOptions *ropt = AH->public.ropt;
3116 
3117  /*
3118  * Disable timeouts to allow for slow commands, idle parallel workers, etc
3119  */
3120  ahprintf(AH, "SET statement_timeout = 0;\n");
3121  ahprintf(AH, "SET lock_timeout = 0;\n");
3122  ahprintf(AH, "SET idle_in_transaction_session_timeout = 0;\n");
3123 
3124  /* Select the correct character set encoding */
3125  ahprintf(AH, "SET client_encoding = '%s';\n",
3127 
3128  /* Select the correct string literal syntax */
3129  ahprintf(AH, "SET standard_conforming_strings = %s;\n",
3130  AH->public.std_strings ? "on" : "off");
3131 
3132  /* Select the role to be used during restore */
3133  if (ropt && ropt->use_role)
3134  ahprintf(AH, "SET ROLE %s;\n", fmtId(ropt->use_role));
3135 
3136  /* Select the dump-time search_path */
3137  if (AH->public.searchpath)
3138  ahprintf(AH, "%s", AH->public.searchpath);
3139 
3140  /* Make sure function checking is disabled */
3141  ahprintf(AH, "SET check_function_bodies = false;\n");
3142 
3143  /* Ensure that all valid XML data will be accepted */
3144  ahprintf(AH, "SET xmloption = content;\n");
3145 
3146  /* Avoid annoying notices etc */
3147  ahprintf(AH, "SET client_min_messages = warning;\n");
3148  if (!AH->public.std_strings)
3149  ahprintf(AH, "SET escape_string_warning = off;\n");
3150 
3151  /* Adjust row-security state */
3152  if (ropt && ropt->enable_row_security)
3153  ahprintf(AH, "SET row_security = on;\n");
3154  else
3155  ahprintf(AH, "SET row_security = off;\n");
3156 
3157  ahprintf(AH, "\n");
3158 }
RestoreOptions * ropt
Definition: pg_backup.h:183
const char * fmtId(const char *rawid)
Definition: string_utils.c:64
char * use_role
Definition: pg_backup.h:71
int encoding
Definition: pg_backup.h:197
int enable_row_security
Definition: pg_backup.h:123
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
char * searchpath
Definition: pg_backup.h:201
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:588
bool std_strings
Definition: pg_backup.h:198

◆ _doSetSessionAuth()

static void _doSetSessionAuth ( ArchiveHandle AH,
const char *  user 
)
static

Definition at line 3166 of file pg_backup_archiver.c.

References ahprintf(), appendPQExpBufferChar(), appendPQExpBufferStr(), appendStringLiteralAHX, _archiveHandle::connection, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), fatal, PGRES_COMMAND_OK, PQclear(), PQerrorMessage(), PQexec(), PQresultStatus(), and RestoringToDB().

Referenced by _becomeUser().

3167 {
3169 
3170  appendPQExpBufferStr(cmd, "SET SESSION AUTHORIZATION ");
3171 
3172  /*
3173  * SQL requires a string literal here. Might as well be correct.
3174  */
3175  if (user && *user)
3176  appendStringLiteralAHX(cmd, user, AH);
3177  else
3178  appendPQExpBufferStr(cmd, "DEFAULT");
3179  appendPQExpBufferChar(cmd, ';');
3180 
3181  if (RestoringToDB(AH))
3182  {
3183  PGresult *res;
3184 
3185  res = PQexec(AH->connection, cmd->data);
3186 
3187  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3188  /* NOT warn_or_exit_horribly... use -O instead to skip this. */
3189  fatal("could not set session user to \"%s\": %s",
3191 
3192  PQclear(res);
3193  }
3194  else
3195  ahprintf(AH, "%s\n\n", cmd->data);
3196 
3197  destroyPQExpBuffer(cmd);
3198 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6684
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:116
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:74
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:380
void PQclear(PGresult *res)
Definition: fe-exec.c:694
#define fatal(...)
#define appendStringLiteralAHX(buf, str, AH)
static char * user
Definition: pg_regress.c:93
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939

◆ _enableTriggersIfNecessary()

static void _enableTriggersIfNecessary ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 1009 of file pg_backup_archiver.c.

References _becomeUser(), ahprintf(), _restoreOptions::dataOnly, _restoreOptions::disable_triggers, fmtQualifiedId(), pg_log_info, _archiveHandle::public, Archive::ropt, _restoreOptions::superuser, and _tocEntry::tag.

Referenced by restore_toc_entry().

1010 {
1011  RestoreOptions *ropt = AH->public.ropt;
1012 
1013  /* This hack is only needed in a data-only restore */
1014  if (!ropt->dataOnly || !ropt->disable_triggers)
1015  return;
1016 
1017  pg_log_info("enabling triggers for %s", te->tag);
1018 
1019  /*
1020  * Become superuser if possible, since they are the only ones who can
1021  * disable constraint triggers. If -S was not given, assume the initial
1022  * user identity is a superuser. (XXX would it be better to become the
1023  * table owner?)
1024  */
1025  _becomeUser(AH, ropt->superuser);
1026 
1027  /*
1028  * Enable them.
1029  */
1030  ahprintf(AH, "ALTER TABLE %s ENABLE TRIGGER ALL;\n\n",
1031  fmtQualifiedId(te->namespace, te->tag));
1032 }
RestoreOptions * ropt
Definition: pg_backup.h:183
static void _becomeUser(ArchiveHandle *AH, const char *user)
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
char * superuser
Definition: pg_backup.h:70
const char * fmtQualifiedId(const char *schema, const char *id)
Definition: string_utils.c:145
#define pg_log_info(...)
Definition: logging.h:87
int disable_triggers
Definition: pg_backup.h:66

◆ _getObjectDescription()

static void _getObjectDescription ( PQExpBuffer  buf,
TocEntry te,
ArchiveHandle AH 
)
static

Definition at line 3454 of file pg_backup_archiver.c.

References appendPQExpBuffer(), appendPQExpBufferStr(), _tocEntry::desc, _tocEntry::dropStmt, fmtId(), free, pg_log_warning, pg_strdup(), _tocEntry::tag, and generate_unaccent_rules::type.

Referenced by _printTocEntry().

3455 {
3456  const char *type = te->desc;
3457 
3458  /* Use ALTER TABLE for views and sequences */
3459  if (strcmp(type, "VIEW") == 0 || strcmp(type, "SEQUENCE") == 0 ||
3460  strcmp(type, "MATERIALIZED VIEW") == 0)
3461  type = "TABLE";
3462 
3463  /* objects that don't require special decoration */
3464  if (strcmp(type, "COLLATION") == 0 ||
3465  strcmp(type, "CONVERSION") == 0 ||
3466  strcmp(type, "DOMAIN") == 0 ||
3467  strcmp(type, "TABLE") == 0 ||
3468  strcmp(type, "TYPE") == 0 ||
3469  strcmp(type, "FOREIGN TABLE") == 0 ||
3470  strcmp(type, "TEXT SEARCH DICTIONARY") == 0 ||
3471  strcmp(type, "TEXT SEARCH CONFIGURATION") == 0 ||
3472  strcmp(type, "STATISTICS") == 0 ||
3473  /* non-schema-specified objects */
3474  strcmp(type, "DATABASE") == 0 ||
3475  strcmp(type, "PROCEDURAL LANGUAGE") == 0 ||
3476  strcmp(type, "SCHEMA") == 0 ||
3477  strcmp(type, "EVENT TRIGGER") == 0 ||
3478  strcmp(type, "FOREIGN DATA WRAPPER") == 0 ||
3479  strcmp(type, "SERVER") == 0 ||
3480  strcmp(type, "PUBLICATION") == 0 ||
3481  strcmp(type, "SUBSCRIPTION") == 0 ||
3482  strcmp(type, "USER MAPPING") == 0)
3483  {
3484  appendPQExpBuffer(buf, "%s ", type);
3485  if (te->namespace && *te->namespace)
3486  appendPQExpBuffer(buf, "%s.", fmtId(te->namespace));
3487  appendPQExpBufferStr(buf, fmtId(te->tag));
3488  return;
3489  }
3490 
3491  /* BLOBs just have a name, but it's numeric so must not use fmtId */
3492  if (strcmp(type, "BLOB") == 0)
3493  {
3494  appendPQExpBuffer(buf, "LARGE OBJECT %s", te->tag);
3495  return;
3496  }
3497 
3498  /*
3499  * These object types require additional decoration. Fortunately, the
3500  * information needed is exactly what's in the DROP command.
3501  */
3502  if (strcmp(type, "AGGREGATE") == 0 ||
3503  strcmp(type, "FUNCTION") == 0 ||
3504  strcmp(type, "OPERATOR") == 0 ||
3505  strcmp(type, "OPERATOR CLASS") == 0 ||
3506  strcmp(type, "OPERATOR FAMILY") == 0 ||
3507  strcmp(type, "PROCEDURE") == 0)
3508  {
3509  /* Chop "DROP " off the front and make a modifiable copy */
3510  char *first = pg_strdup(te->dropStmt + 5);
3511  char *last;
3512 
3513  /* point to last character in string */
3514  last = first + strlen(first) - 1;
3515 
3516  /* Strip off any ';' or '\n' at the end */
3517  while (last >= first && (*last == '\n' || *last == ';'))
3518  last--;
3519  *(last + 1) = '\0';
3520 
3521  appendPQExpBufferStr(buf, first);
3522 
3523  free(first);
3524  return;
3525  }
3526 
3527  pg_log_warning("don't know how to set owner for object type \"%s\"",
3528  type);
3529 }
const char * fmtId(const char *rawid)
Definition: string_utils.c:64
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
#define free(a)
Definition: header.h:65
#define pg_log_warning(...)
Definition: pgfnames.c:24

◆ _moveBefore()

static void _moveBefore ( ArchiveHandle AH,
TocEntry pos,
TocEntry te 
)
static

Definition at line 1807 of file pg_backup_archiver.c.

References _tocEntry::next, and _tocEntry::prev.

Referenced by SortTocFromFile().

1808 {
1809  /* Unlink te from list */
1810  te->prev->next = te->next;
1811  te->next->prev = te->prev;
1812 
1813  /* and insert it before "pos" */
1814  te->prev = pos->prev;
1815  te->next = pos;
1816  pos->prev->next = te;
1817  pos->prev = te;
1818 }
struct _tocEntry * next
struct _tocEntry * prev

◆ _printTocEntry()

static void _printTocEntry ( ArchiveHandle AH,
TocEntry te,
bool  isData 
)
static

Definition at line 3539 of file pg_backup_archiver.c.

References _becomeOwner(), _getObjectDescription(), _selectOutputSchema(), _selectTableAccessMethod(), _selectTablespace(), _tocEntryIsACL(), ahprintf(), appendPQExpBuffer(), appendPQExpBufferStr(), _tocEntry::catalogId, createPQExpBuffer(), _archiveHandle::currUser, PQExpBufferData::data, _tocEntry::defn, _tocEntry::dependencies, _tocEntry::desc, destroyPQExpBuffer(), _tocEntry::dropStmt, _tocEntry::dumpId, fmtId(), free, i, _tocEntry::nDeps, _restoreOptions::noOwner, _restoreOptions::noTablespace, _archiveHandle::noTocComments, CatalogId::oid, _tocEntry::owner, pg_log_warning, _archiveHandle::PrintExtraTocPtr, _archiveHandle::public, Archive::ropt, sanitize_line(), _tocEntry::tableam, CatalogId::tableoid, _tocEntry::tablespace, _tocEntry::tag, _restoreOptions::use_setsessauth, and Archive::verbose.

Referenced by restore_toc_entry().

3540 {
3541  RestoreOptions *ropt = AH->public.ropt;
3542 
3543  /* Select owner, schema, tablespace and default AM as necessary */
3544  _becomeOwner(AH, te);
3545  _selectOutputSchema(AH, te->namespace);
3546  _selectTablespace(AH, te->tablespace);
3548 
3549  /* Emit header comment for item */
3550  if (!AH->noTocComments)
3551  {
3552  const char *pfx;
3553  char *sanitized_name;
3554  char *sanitized_schema;
3555  char *sanitized_owner;
3556 
3557  if (isData)
3558  pfx = "Data for ";
3559  else
3560  pfx = "";
3561 
3562  ahprintf(AH, "--\n");
3563  if (AH->public.verbose)
3564  {
3565  ahprintf(AH, "-- TOC entry %d (class %u OID %u)\n",
3566  te->dumpId, te->catalogId.tableoid, te->catalogId.oid);
3567  if (te->nDeps > 0)
3568  {
3569  int i;
3570 
3571  ahprintf(AH, "-- Dependencies:");
3572  for (i = 0; i < te->nDeps; i++)
3573  ahprintf(AH, " %d", te->dependencies[i]);
3574  ahprintf(AH, "\n");
3575  }
3576  }
3577 
3578  sanitized_name = sanitize_line(te->tag, false);
3579  sanitized_schema = sanitize_line(te->namespace, true);
3580  sanitized_owner = sanitize_line(ropt->noOwner ? NULL : te->owner, true);
3581 
3582  ahprintf(AH, "-- %sName: %s; Type: %s; Schema: %s; Owner: %s",
3583  pfx, sanitized_name, te->desc, sanitized_schema,
3584  sanitized_owner);
3585 
3586  free(sanitized_name);
3587  free(sanitized_schema);
3588  free(sanitized_owner);
3589 
3590  if (te->tablespace && strlen(te->tablespace) > 0 && !ropt->noTablespace)
3591  {
3592  char *sanitized_tablespace;
3593 
3594  sanitized_tablespace = sanitize_line(te->tablespace, false);
3595  ahprintf(AH, "; Tablespace: %s", sanitized_tablespace);
3596  free(sanitized_tablespace);
3597  }
3598  ahprintf(AH, "\n");
3599 
3600  if (AH->PrintExtraTocPtr != NULL)
3601  AH->PrintExtraTocPtr(AH, te);
3602  ahprintf(AH, "--\n\n");
3603  }
3604 
3605  /*
3606  * Actually print the definition.
3607  *
3608  * Really crude hack for suppressing AUTHORIZATION clause that old pg_dump
3609  * versions put into CREATE SCHEMA. We have to do this when --no-owner
3610  * mode is selected. This is ugly, but I see no other good way ...
3611  */
3612  if (ropt->noOwner && strcmp(te->desc, "SCHEMA") == 0)
3613  {
3614  ahprintf(AH, "CREATE SCHEMA %s;\n\n\n", fmtId(te->tag));
3615  }
3616  else
3617  {
3618  if (te->defn && strlen(te->defn) > 0)
3619  ahprintf(AH, "%s\n\n", te->defn);
3620  }
3621 
3622  /*
3623  * If we aren't using SET SESSION AUTH to determine ownership, we must
3624  * instead issue an ALTER OWNER command. We assume that anything without
3625  * a DROP command is not a separately ownable object. All the categories
3626  * with DROP commands must appear in one list or the other.
3627  */
3628  if (!ropt->noOwner && !ropt->use_setsessauth &&
3629  te->owner && strlen(te->owner) > 0 &&
3630  te->dropStmt && strlen(te->dropStmt) > 0)
3631  {
3632  if (strcmp(te->desc, "AGGREGATE") == 0 ||
3633  strcmp(te->desc, "BLOB") == 0 ||
3634  strcmp(te->desc, "COLLATION") == 0 ||
3635  strcmp(te->desc, "CONVERSION") == 0 ||
3636  strcmp(te->desc, "DATABASE") == 0 ||
3637  strcmp(te->desc, "DOMAIN") == 0 ||
3638  strcmp(te->desc, "FUNCTION") == 0 ||
3639  strcmp(te->desc, "OPERATOR") == 0 ||
3640  strcmp(te->desc, "OPERATOR CLASS") == 0 ||
3641  strcmp(te->desc, "OPERATOR FAMILY") == 0 ||
3642  strcmp(te->desc, "PROCEDURE") == 0 ||
3643  strcmp(te->desc, "PROCEDURAL LANGUAGE") == 0 ||
3644  strcmp(te->desc, "SCHEMA") == 0 ||
3645  strcmp(te->desc, "EVENT TRIGGER") == 0 ||
3646  strcmp(te->desc, "TABLE") == 0 ||
3647  strcmp(te->desc, "TYPE") == 0 ||
3648  strcmp(te->desc, "VIEW") == 0 ||
3649  strcmp(te->desc, "MATERIALIZED VIEW") == 0 ||
3650  strcmp(te->desc, "SEQUENCE") == 0 ||
3651  strcmp(te->desc, "FOREIGN TABLE") == 0 ||
3652  strcmp(te->desc, "TEXT SEARCH DICTIONARY") == 0 ||
3653  strcmp(te->desc, "TEXT SEARCH CONFIGURATION") == 0 ||
3654  strcmp(te->desc, "FOREIGN DATA WRAPPER") == 0 ||
3655  strcmp(te->desc, "SERVER") == 0 ||
3656  strcmp(te->desc, "STATISTICS") == 0 ||
3657  strcmp(te->desc, "PUBLICATION") == 0 ||
3658  strcmp(te->desc, "SUBSCRIPTION") == 0)
3659  {
3660  PQExpBuffer temp = createPQExpBuffer();
3661 
3662  appendPQExpBufferStr(temp, "ALTER ");
3663  _getObjectDescription(temp, te, AH);
3664  appendPQExpBuffer(temp, " OWNER TO %s;", fmtId(te->owner));
3665  ahprintf(AH, "%s\n\n", temp->data);
3666  destroyPQExpBuffer(temp);
3667  }
3668  else if (strcmp(te->desc, "CAST") == 0 ||
3669  strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||
3670  strcmp(te->desc, "CONSTRAINT") == 0 ||
3671  strcmp(te->desc, "DATABASE PROPERTIES") == 0 ||
3672  strcmp(te->desc, "DEFAULT") == 0 ||
3673  strcmp(te->desc, "FK CONSTRAINT") == 0 ||
3674  strcmp(te->desc, "INDEX") == 0 ||
3675  strcmp(te->desc, "RULE") == 0 ||
3676  strcmp(te->desc, "TRIGGER") == 0 ||
3677  strcmp(te->desc, "ROW SECURITY") == 0 ||
3678  strcmp(te->desc, "POLICY") == 0 ||
3679  strcmp(te->desc, "USER MAPPING") == 0)
3680  {
3681  /* these object types don't have separate owners */
3682  }
3683  else
3684  {
3685  pg_log_warning("don't know how to set owner for object type \"%s\"",
3686  te->desc);
3687  }
3688  }
3689 
3690  /*
3691  * If it's an ACL entry, it might contain SET SESSION AUTHORIZATION
3692  * commands, so we can no longer assume we know the current auth setting.
3693  */
3694  if (_tocEntryIsACL(te))
3695  {
3696  if (AH->currUser)
3697  free(AH->currUser);
3698  AH->currUser = NULL;
3699  }
3700 }
Oid tableoid
Definition: pg_backup.h:230
RestoreOptions * ropt
Definition: pg_backup.h:183
const char * fmtId(const char *rawid)
Definition: string_utils.c:64
CatalogId catalogId
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
static bool _tocEntryIsACL(TocEntry *te)
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:116
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
DumpId * dependencies
static void _selectTableAccessMethod(ArchiveHandle *AH, const char *tableam)
static void _becomeOwner(ArchiveHandle *AH, TocEntry *te)
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:74
int use_setsessauth
Definition: pg_backup.h:68
int verbose
Definition: pg_backup.h:185
#define free(a)
Definition: header.h:65
static void _selectOutputSchema(ArchiveHandle *AH, const char *schemaName)
int i
static char * sanitize_line(const char *str, bool want_hyphen)
PrintExtraTocPtrType PrintExtraTocPtr
static void _getObjectDescription(PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH)
#define pg_log_warning(...)
Definition: pgfnames.c:24
static void _selectTablespace(ArchiveHandle *AH, const char *tablespace)

◆ _reconnectToDB()

static void _reconnectToDB ( ArchiveHandle AH,
const char *  dbname 
)
static

Definition at line 3211 of file pg_backup_archiver.c.

References _doSetFixedOutputState(), ahprintf(), appendPsqlMetaConnect(), _archiveHandle::currSchema, _archiveHandle::currTablespace, _archiveHandle::currUser, PQExpBufferData::data, free, initPQExpBuffer(), ReconnectToServer(), RestoringToDB(), and termPQExpBuffer().

Referenced by restore_toc_entry().

3212 {
3213  if (RestoringToDB(AH))
3214  ReconnectToServer(AH, dbname, NULL);
3215  else
3216  {
3217  if (dbname)
3218  {
3219  PQExpBufferData connectbuf;
3220 
3221  initPQExpBuffer(&connectbuf);
3222  appendPsqlMetaConnect(&connectbuf, dbname);
3223  ahprintf(AH, "%s\n", connectbuf.data);
3224  termPQExpBuffer(&connectbuf);
3225  }
3226  else
3227  ahprintf(AH, "%s\n", "\\connect -\n");
3228  }
3229 
3230  /*
3231  * NOTE: currUser keeps track of what the imaginary session user in our
3232  * script is. It's now effectively reset to the original userID.
3233  */
3234  if (AH->currUser)
3235  free(AH->currUser);
3236  AH->currUser = NULL;
3237 
3238  /* don't assume we still know the output schema, tablespace, etc either */
3239  if (AH->currSchema)
3240  free(AH->currSchema);
3241  AH->currSchema = NULL;
3242  if (AH->currTablespace)
3243  free(AH->currTablespace);
3244  AH->currTablespace = NULL;
3245 
3246  /* re-establish fixed state */
3248 }
static int RestoringToDB(ArchiveHandle *AH)
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
void ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *newUser)
Definition: pg_backup_db.c:79
void appendPsqlMetaConnect(PQExpBuffer buf, const char *dbname)
Definition: string_utils.c:590
static void _doSetFixedOutputState(ArchiveHandle *AH)
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
#define free(a)
Definition: header.h:65
char * dbname
Definition: streamutil.c:50
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92

◆ _selectOutputSchema()

static void _selectOutputSchema ( ArchiveHandle AH,
const char *  schemaName 
)
static

Definition at line 3296 of file pg_backup_archiver.c.

References ahprintf(), appendPQExpBuffer(), appendPQExpBufferStr(), _archiveHandle::connection, createPQExpBuffer(), _archiveHandle::currSchema, PQExpBufferData::data, destroyPQExpBuffer(), fmtId(), free, pg_strdup(), PGRES_COMMAND_OK, PQclear(), PQerrorMessage(), PQexec(), PQresultStatus(), _archiveHandle::public, RestoringToDB(), Archive::searchpath, and warn_or_exit_horribly().

Referenced by _printTocEntry(), restore_toc_entry(), and RestoreArchive().

3297 {
3298  PQExpBuffer qry;
3299 
3300  /*
3301  * If there was a SEARCHPATH TOC entry, we're supposed to just stay with
3302  * that search_path rather than switching to entry-specific paths.
3303  * Otherwise, it's an old archive that will not restore correctly unless
3304  * we set the search_path as it's expecting.
3305  */
3306  if (AH->public.searchpath)
3307  return;
3308 
3309  if (!schemaName || *schemaName == '\0' ||
3310  (AH->currSchema && strcmp(AH->currSchema, schemaName) == 0))
3311  return; /* no need to do anything */
3312 
3313  qry = createPQExpBuffer();
3314 
3315  appendPQExpBuffer(qry, "SET search_path = %s",
3316  fmtId(schemaName));
3317  if (strcmp(schemaName, "pg_catalog") != 0)
3318  appendPQExpBufferStr(qry, ", pg_catalog");
3319 
3320  if (RestoringToDB(AH))
3321  {
3322  PGresult *res;
3323 
3324  res = PQexec(AH->connection, qry->data);
3325 
3326  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3328  "could not set search_path to \"%s\": %s",
3329  schemaName, PQerrorMessage(AH->connection));
3330 
3331  PQclear(res);
3332  }
3333  else
3334  ahprintf(AH, "%s;\n\n", qry->data);
3335 
3336  if (AH->currSchema)
3337  free(AH->currSchema);
3338  AH->currSchema = pg_strdup(schemaName);
3339 
3340  destroyPQExpBuffer(qry);
3341 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6684
const char * fmtId(const char *rawid)
Definition: string_utils.c:64
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
void warn_or_exit_horribly(ArchiveHandle *AH, const char *fmt,...)
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:116
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:74
char * searchpath
Definition: pg_backup.h:201
void PQclear(PGresult *res)
Definition: fe-exec.c:694
#define free(a)
Definition: header.h:65
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939

◆ _selectTableAccessMethod()

static void _selectTableAccessMethod ( ArchiveHandle AH,
const char *  tableam 
)
static

Definition at line 3409 of file pg_backup_archiver.c.

References ahprintf(), appendPQExpBuffer(), _archiveHandle::connection, createPQExpBuffer(), _archiveHandle::currTableAm, PQExpBufferData::data, destroyPQExpBuffer(), fmtId(), pg_strdup(), PGRES_COMMAND_OK, PQclear(), PQerrorMessage(), PQexec(), PQresultStatus(), RestoringToDB(), and warn_or_exit_horribly().

Referenced by _printTocEntry().

3410 {
3411  PQExpBuffer cmd;
3412  const char *want,
3413  *have;
3414 
3415  have = AH->currTableAm;
3416  want = tableam;
3417 
3418  if (!want)
3419  return;
3420 
3421  if (have && strcmp(want, have) == 0)
3422  return;
3423 
3424  cmd = createPQExpBuffer();
3425  appendPQExpBuffer(cmd, "SET default_table_access_method = %s;", fmtId(want));
3426 
3427  if (RestoringToDB(AH))
3428  {
3429  PGresult *res;
3430 
3431  res = PQexec(AH->connection, cmd->data);
3432 
3433  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3435  "could not set default_table_access_method: %s",
3436  PQerrorMessage(AH->connection));
3437 
3438  PQclear(res);
3439  }
3440  else
3441  ahprintf(AH, "%s\n\n", cmd->data);
3442 
3443  destroyPQExpBuffer(cmd);
3444 
3445  AH->currTableAm = pg_strdup(want);
3446 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6684
const char * fmtId(const char *rawid)
Definition: string_utils.c:64
void warn_or_exit_horribly(ArchiveHandle *AH, const char *fmt,...)
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:116
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:74
void PQclear(PGresult *res)
Definition: fe-exec.c:694
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939

◆ _selectTablespace()

static void _selectTablespace ( ArchiveHandle AH,
const char *  tablespace 
)
static

Definition at line 3348 of file pg_backup_archiver.c.

References ahprintf(), appendPQExpBuffer(), appendPQExpBufferStr(), _archiveHandle::connection, createPQExpBuffer(), _archiveHandle::currTablespace, PQExpBufferData::data, destroyPQExpBuffer(), fmtId(), free, _restoreOptions::noTablespace, pg_strdup(), PGRES_COMMAND_OK, PQclear(), PQerrorMessage(), PQexec(), PQresultStatus(), _archiveHandle::public, RestoringToDB(), Archive::ropt, tablespace, and warn_or_exit_horribly().

Referenced by _printTocEntry().

3349 {
3350  RestoreOptions *ropt = AH->public.ropt;
3351  PQExpBuffer qry;
3352  const char *want,
3353  *have;
3354 
3355  /* do nothing in --no-tablespaces mode */
3356  if (ropt->noTablespace)
3357  return;
3358 
3359  have = AH->currTablespace;
3360  want = tablespace;
3361 
3362  /* no need to do anything for non-tablespace object */
3363  if (!want)
3364  return;
3365 
3366  if (have && strcmp(want, have) == 0)
3367  return; /* no need to do anything */
3368 
3369  qry = createPQExpBuffer();
3370 
3371  if (strcmp(want, "") == 0)
3372  {
3373  /* We want the tablespace to be the database's default */
3374  appendPQExpBufferStr(qry, "SET default_tablespace = ''");
3375  }
3376  else
3377  {
3378  /* We want an explicit tablespace */
3379  appendPQExpBuffer(qry, "SET default_tablespace = %s", fmtId(want));
3380  }
3381 
3382  if (RestoringToDB(AH))
3383  {
3384  PGresult *res;
3385 
3386  res = PQexec(AH->connection, qry->data);
3387 
3388  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3390  "could not set default_tablespace to %s: %s",
3391  fmtId(want), PQerrorMessage(AH->connection));
3392 
3393  PQclear(res);
3394  }
3395  else
3396  ahprintf(AH, "%s;\n\n", qry->data);
3397 
3398  if (AH->currTablespace)
3399  free(AH->currTablespace);
3400  AH->currTablespace = pg_strdup(want);
3401 
3402  destroyPQExpBuffer(qry);
3403 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6684
RestoreOptions * ropt
Definition: pg_backup.h:183
const char * fmtId(const char *rawid)
Definition: string_utils.c:64
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
void warn_or_exit_horribly(ArchiveHandle *AH, const char *fmt,...)
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:116
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
char * tablespace
Definition: pgbench.c:188
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:74
void PQclear(PGresult *res)
Definition: fe-exec.c:694
#define free(a)
Definition: header.h:65
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939

◆ _tocEntryIsACL()

static bool _tocEntryIsACL ( TocEntry te)
static

Definition at line 3098 of file pg_backup_archiver.c.

References _tocEntry::desc.

Referenced by _printTocEntry(), and _tocEntryRequired().

3099 {
3100  /* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
3101  if (strcmp(te->desc, "ACL") == 0 ||
3102  strcmp(te->desc, "ACL LANGUAGE") == 0 ||
3103  strcmp(te->desc, "DEFAULT ACL") == 0)
3104  return true;
3105  return false;
3106 }

◆ _tocEntryRequired()

static teReqs _tocEntryRequired ( TocEntry te,
teSection  curSection,
ArchiveHandle AH 
)
static

Definition at line 2822 of file pg_backup_archiver.c.

References _tocEntryIsACL(), _restoreOptions::aclsSkip, _restoreOptions::binary_upgrade, _restoreOptions::createDB, _restoreOptions::dataOnly, _tocEntry::defn, _tocEntry::dependencies, _tocEntry::desc, DUMP_DATA, DUMP_POST_DATA, DUMP_PRE_DATA, _tocEntry::dumpId, _restoreOptions::dumpSections, _restoreOptions::functionNames, _tocEntry::hadDumper, SimpleStringList::head, _restoreOptions::idWanted, _restoreOptions::indexNames, _tocEntry::nDeps, _restoreOptions::no_comments, _restoreOptions::no_publications, _restoreOptions::no_security_labels, _restoreOptions::no_subscriptions, _archiveHandle::public, REQ_DATA, REQ_SCHEMA, REQ_SPECIAL, Archive::ropt, _restoreOptions::schemaExcludeNames, _restoreOptions::schemaNames, _restoreOptions::schemaOnly, SECTION_DATA, SECTION_POST_DATA, SECTION_PRE_DATA, _restoreOptions::selFunction, _restoreOptions::selIndex, _restoreOptions::selTable, _restoreOptions::selTrigger, _restoreOptions::selTypes, _restoreOptions::sequence_data, simple_string_list_member(), _restoreOptions::tableNames, _tocEntry::tag, TocIDRequired(), and _restoreOptions::triggerNames.

Referenced by PrintTOCSummary(), and ProcessArchiveRestoreOptions().

2823 {
2824  teReqs res = REQ_SCHEMA | REQ_DATA;
2825  RestoreOptions *ropt = AH->public.ropt;
2826 
2827  /* These items are treated specially */
2828  if (strcmp(te->desc, "ENCODING") == 0 ||
2829  strcmp(te->desc, "STDSTRINGS") == 0 ||
2830  strcmp(te->desc, "SEARCHPATH") == 0)
2831  return REQ_SPECIAL;
2832 
2833  /*
2834  * DATABASE and DATABASE PROPERTIES also have a special rule: they are
2835  * restored in createDB mode, and not restored otherwise, independently of
2836  * all else.
2837  */
2838  if (strcmp(te->desc, "DATABASE") == 0 ||
2839  strcmp(te->desc, "DATABASE PROPERTIES") == 0)
2840  {
2841  if (ropt->createDB)
2842  return REQ_SCHEMA;
2843  else
2844  return 0;
2845  }
2846 
2847  /*
2848  * Process exclusions that affect certain classes of TOC entries.
2849  */
2850 
2851  /* If it's an ACL, maybe ignore it */
2852  if (ropt->aclsSkip && _tocEntryIsACL(te))
2853  return 0;
2854 
2855  /* If it's a comment, maybe ignore it */
2856  if (ropt->no_comments && strcmp(te->desc, "COMMENT") == 0)
2857  return 0;
2858 
2859  /*
2860  * If it's a publication or a table part of a publication, maybe ignore
2861  * it.
2862  */
2863  if (ropt->no_publications &&
2864  (strcmp(te->desc, "PUBLICATION") == 0 ||
2865  strcmp(te->desc, "PUBLICATION TABLE") == 0))
2866  return 0;
2867 
2868  /* If it's a security label, maybe ignore it */
2869  if (ropt->no_security_labels && strcmp(te->desc, "SECURITY LABEL") == 0)
2870  return 0;
2871 
2872  /* If it's a subscription, maybe ignore it */
2873  if (ropt->no_subscriptions && strcmp(te->desc, "SUBSCRIPTION") == 0)
2874  return 0;
2875 
2876  /* Ignore it if section is not to be dumped/restored */
2877  switch (curSection)
2878  {
2879  case SECTION_PRE_DATA:
2880  if (!(ropt->dumpSections & DUMP_PRE_DATA))
2881  return 0;
2882  break;
2883  case SECTION_DATA:
2884  if (!(ropt->dumpSections & DUMP_DATA))
2885  return 0;
2886  break;
2887  case SECTION_POST_DATA:
2888  if (!(ropt->dumpSections & DUMP_POST_DATA))
2889  return 0;
2890  break;
2891  default:
2892  /* shouldn't get here, really, but ignore it */
2893  return 0;
2894  }
2895 
2896  /* Ignore it if rejected by idWanted[] (cf. SortTocFromFile) */
2897  if (ropt->idWanted && !ropt->idWanted[te->dumpId - 1])
2898  return 0;
2899 
2900  /*
2901  * Check options for selective dump/restore.
2902  */
2903  if (strcmp(te->desc, "ACL") == 0 ||
2904  strcmp(te->desc, "COMMENT") == 0 ||
2905  strcmp(te->desc, "SECURITY LABEL") == 0)
2906  {
2907  /* Database properties react to createDB, not selectivity options. */
2908  if (strncmp(te->tag, "DATABASE ", 9) == 0)
2909  {
2910  if (!ropt->createDB)
2911  return 0;
2912  }
2913  else if (ropt->schemaNames.head != NULL ||
2914  ropt->schemaExcludeNames.head != NULL ||
2915  ropt->selTypes)
2916  {
2917  /*
2918  * In a selective dump/restore, we want to restore these dependent
2919  * TOC entry types only if their parent object is being restored.
2920  * Without selectivity options, we let through everything in the
2921  * archive. Note there may be such entries with no parent, eg
2922  * non-default ACLs for built-in objects.
2923  *
2924  * This code depends on the parent having been marked already,
2925  * which should be the case; if it isn't, perhaps due to
2926  * SortTocFromFile rearrangement, skipping the dependent entry
2927  * seems prudent anyway.
2928  *
2929  * Ideally we'd handle, eg, table CHECK constraints this way too.
2930  * But it's hard to tell which of their dependencies is the one to
2931  * consult.
2932  */
2933  if (te->nDeps != 1 ||
2934  TocIDRequired(AH, te->dependencies[0]) == 0)
2935  return 0;
2936  }
2937  }
2938  else
2939  {
2940  /* Apply selective-restore rules for standalone TOC entries. */
2941  if (ropt->schemaNames.head != NULL)
2942  {
2943  /* If no namespace is specified, it means all. */
2944  if (!te->namespace)
2945  return 0;
2946  if (!simple_string_list_member(&ropt->schemaNames, te->namespace))
2947  return 0;
2948  }
2949 
2950  if (ropt->schemaExcludeNames.head != NULL &&
2951  te->namespace &&
2952  simple_string_list_member(&ropt->schemaExcludeNames, te->namespace))
2953  return 0;
2954 
2955  if (ropt->selTypes)
2956  {
2957  if (strcmp(te->desc, "TABLE") == 0 ||
2958  strcmp(te->desc, "TABLE DATA") == 0 ||
2959  strcmp(te->desc, "VIEW") == 0 ||
2960  strcmp(te->desc, "FOREIGN TABLE") == 0 ||
2961  strcmp(te->desc, "MATERIALIZED VIEW") == 0 ||
2962  strcmp(te->desc, "MATERIALIZED VIEW DATA") == 0 ||
2963  strcmp(te->desc, "SEQUENCE") == 0 ||
2964  strcmp(te->desc, "SEQUENCE SET") == 0)
2965  {
2966  if (!ropt->selTable)
2967  return 0;
2968  if (ropt->tableNames.head != NULL &&
2970  return 0;
2971  }
2972  else if (strcmp(te->desc, "INDEX") == 0)
2973  {
2974  if (!ropt->selIndex)
2975  return 0;
2976  if (ropt->indexNames.head != NULL &&
2978  return 0;
2979  }
2980  else if (strcmp(te->desc, "FUNCTION") == 0 ||
2981  strcmp(te->desc, "AGGREGATE") == 0 ||
2982  strcmp(te->desc, "PROCEDURE") == 0)
2983  {
2984  if (!ropt->selFunction)
2985  return 0;
2986  if (ropt->functionNames.head != NULL &&
2988  return 0;
2989  }
2990  else if (strcmp(te->desc, "TRIGGER") == 0)
2991  {
2992  if (!ropt->selTrigger)
2993  return 0;
2994  if (ropt->triggerNames.head != NULL &&
2996  return 0;
2997  }
2998  else
2999  return 0;
3000  }
3001  }
3002 
3003  /*
3004  * Determine whether the TOC entry contains schema and/or data components,
3005  * and mask off inapplicable REQ bits. If it had a dataDumper, assume
3006  * it's both schema and data. Otherwise it's probably schema-only, but
3007  * there are exceptions.
3008  */
3009  if (!te->hadDumper)
3010  {
3011  /*
3012  * Special Case: If 'SEQUENCE SET' or anything to do with BLOBs, then
3013  * it is considered a data entry. We don't need to check for the
3014  * BLOBS entry or old-style BLOB COMMENTS, because they will have
3015  * hadDumper = true ... but we do need to check new-style BLOB ACLs,
3016  * comments, etc.
3017  */
3018  if (strcmp(te->desc, "SEQUENCE SET") == 0 ||
3019  strcmp(te->desc, "BLOB") == 0 ||
3020  (strcmp(te->desc, "ACL") == 0 &&
3021  strncmp(te->tag, "LARGE OBJECT ", 13) == 0) ||
3022  (strcmp(te->desc, "COMMENT") == 0 &&
3023  strncmp(te->tag, "LARGE OBJECT ", 13) == 0) ||
3024  (strcmp(te->desc, "SECURITY LABEL") == 0 &&
3025  strncmp(te->tag, "LARGE OBJECT ", 13) == 0))
3026  res = res & REQ_DATA;
3027  else
3028  res = res & ~REQ_DATA;
3029  }
3030 
3031  /* If there's no definition command, there's no schema component */
3032  if (!te->defn || !te->defn[0])
3033  res = res & ~REQ_SCHEMA;
3034 
3035  /*
3036  * Special case: <Init> type with <Max OID> tag; this is obsolete and we
3037  * always ignore it.
3038  */
3039  if ((strcmp(te->desc, "<Init>") == 0) && (strcmp(te->tag, "Max OID") == 0))
3040  return 0;
3041 
3042  /* Mask it if we only want schema */
3043  if (ropt->schemaOnly)
3044  {
3045  /*
3046  * The sequence_data option overrides schemaOnly for SEQUENCE SET.
3047  *
3048  * In binary-upgrade mode, even with schemaOnly set, we do not mask
3049  * out large objects. (Only large object definitions, comments and
3050  * other metadata should be generated in binary-upgrade mode, not the
3051  * actual data, but that need not concern us here.)
3052  */
3053  if (!(ropt->sequence_data && strcmp(te->desc, "SEQUENCE SET") == 0) &&
3054  !(ropt->binary_upgrade &&
3055  (strcmp(te->desc, "BLOB") == 0 ||
3056  (strcmp(te->desc, "ACL") == 0 &&
3057  strncmp(te->tag, "LARGE OBJECT ", 13) == 0) ||
3058  (strcmp(te->desc, "COMMENT") == 0 &&
3059  strncmp(te->tag, "LARGE OBJECT ", 13) == 0) ||
3060  (strcmp(te->desc, "SECURITY LABEL") == 0 &&
3061  strncmp(te->tag, "LARGE OBJECT ", 13) == 0))))
3062  res = res & REQ_SCHEMA;
3063  }
3064 
3065  /* Mask it if we only want data */
3066  if (ropt->dataOnly)
3067  res = res & REQ_DATA;
3068 
3069  return res;
3070 }
bool simple_string_list_member(SimpleStringList *list, const char *val)
Definition: simple_list.c:87
SimpleStringList triggerNames
Definition: pg_backup.h:106
RestoreOptions * ropt
Definition: pg_backup.h:183
SimpleStringList schemaNames
Definition: pg_backup.h:104
static bool _tocEntryIsACL(TocEntry *te)
bool * idWanted
Definition: pg_backup.h:122
SimpleStringList tableNames
Definition: pg_backup.h:107
DumpId * dependencies
SimpleStringList functionNames
Definition: pg_backup.h:103
int no_security_labels
Definition: pg_backup.h:79
int no_subscriptions
Definition: pg_backup.h:80
teReqs TocIDRequired(ArchiveHandle *AH, DumpId id)
SimpleStringListCell * head
Definition: simple_list.h:42
SimpleStringList indexNames
Definition: pg_backup.h:102
int no_publications
Definition: pg_backup.h:78
SimpleStringList schemaExcludeNames
Definition: pg_backup.h:105

◆ _tocEntryRestorePass()

static RestorePass _tocEntryRestorePass ( TocEntry te)
static

Definition at line 3078 of file pg_backup_archiver.c.

References _tocEntry::desc, RESTORE_PASS_ACL, and RESTORE_PASS_MAIN.

Referenced by move_to_ready_list(), reduce_dependencies(), restore_toc_entries_prefork(), and RestoreArchive().

3079 {
3080  /* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
3081  if (strcmp(te->desc, "ACL") == 0 ||
3082  strcmp(te->desc, "ACL LANGUAGE") == 0 ||
3083  strcmp(te->desc, "DEFAULT ACL") == 0)
3084  return RESTORE_PASS_ACL;
3085  if (strcmp(te->desc, "MATERIALIZED VIEW DATA") == 0)
3086  return RESTORE_PASS_REFRESH;
3087  return RESTORE_PASS_MAIN;
3088 }

◆ ahprintf()

int ahprintf ( ArchiveHandle AH,
const char *  fmt,
  ... 
)

Definition at line 1603 of file pg_backup_archiver.c.

References ahwrite(), generate_unaccent_rules::args, free, pg_malloc(), and pvsnprintf().

Referenced by _disableTriggersIfNecessary(), _doSetFixedOutputState(), _doSetSessionAuth(), _enableTriggersIfNecessary(), _EndBlob(), _EndBlobs(), _EndData(), _PrintExtraToc(), _PrintTocData(), _printTocEntry(), _reconnectToDB(), _selectOutputSchema(), _selectTableAccessMethod(), _selectTablespace(), _StartBlob(), _StartBlobs(), _WriteBlobData(), DropBlobIfExists(), dump_lo_buf(), dumpTimestamp(), EndRestoreBlob(), EndRestoreBlobs(), PrintTOCSummary(), restore_toc_entry(), RestoreArchive(), StartRestoreBlob(), and StartRestoreBlobs().

1604 {
1605  int save_errno = errno;
1606  char *p;
1607  size_t len = 128; /* initial assumption about buffer size */
1608  size_t cnt;
1609 
1610  for (;;)
1611  {
1612  va_list args;
1613 
1614  /* Allocate work buffer. */
1615  p = (char *) pg_malloc(len);
1616 
1617  /* Try to format the data. */
1618  errno = save_errno;
1619  va_start(args, fmt);
1620  cnt = pvsnprintf(p, len, fmt, args);
1621  va_end(args);
1622 
1623  if (cnt < len)
1624  break; /* success */
1625 
1626  /* Release buffer and loop around to try again with larger len. */
1627  free(p);
1628  len = cnt;
1629  }
1630 
1631  ahwrite(p, 1, cnt, AH);
1632  free(p);
1633  return (int) cnt;
1634 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args)
Definition: psprintf.c:106
#define free(a)
Definition: header.h:65
void ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)

◆ ahwrite()

void ahwrite ( const void *  ptr,
size_t  size,
size_t  nmemb,
ArchiveHandle AH 
)

Definition at line 1693 of file pg_backup_archiver.c.

References _archiveHandle::CustomOutPtr, dump_lo_buf(), ExecuteSqlCommandBuf(), _archiveHandle::gzOut, GZWRITE, _archiveHandle::lo_buf, _archiveHandle::lo_buf_size, _archiveHandle::lo_buf_used, _archiveHandle::OF, _archiveHandle::public, remaining, RestoringToDB(), WRITE_ERROR_EXIT, and _archiveHandle::writingBlob.

Referenced by _LoadBlobs(), _PrintFileData(), _PrintTocData(), _WriteData(), ahprintf(), EndCompressor(), and ReadDataFromArchiveNone().

1694 {
1695  int bytes_written = 0;
1696 
1697  if (AH->writingBlob)
1698  {
1699  size_t remaining = size * nmemb;
1700 
1701  while (AH->lo_buf_used + remaining > AH->lo_buf_size)
1702  {
1703  size_t avail = AH->lo_buf_size - AH->lo_buf_used;
1704 
1705  memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, avail);
1706  ptr = (const void *) ((const char *) ptr + avail);
1707  remaining -= avail;
1708  AH->lo_buf_used += avail;
1709  dump_lo_buf(AH);
1710  }
1711 
1712  memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, remaining);
1713  AH->lo_buf_used += remaining;
1714 
1715  bytes_written = size * nmemb;
1716  }
1717  else if (AH->gzOut)
1718  bytes_written = GZWRITE(ptr, size, nmemb, AH->OF);
1719  else if (AH->CustomOutPtr)
1720  bytes_written = AH->CustomOutPtr(AH, ptr, size * nmemb);
1721 
1722  else
1723  {
1724  /*
1725  * If we're doing a restore, and it's direct to DB, and we're
1726  * connected then send it to the DB.
1727  */
1728  if (RestoringToDB(AH))
1729  bytes_written = ExecuteSqlCommandBuf(&AH->public, (const char *) ptr, size * nmemb);
1730  else
1731  bytes_written = fwrite(ptr, size, nmemb, AH->OF) * size;
1732  }
1733 
1734  if (bytes_written != size * nmemb)
1736 }
int remaining
Definition: informix.c:667
static int RestoringToDB(ArchiveHandle *AH)
int ExecuteSqlCommandBuf(Archive *AHX, const char *buf, size_t bufLen)
Definition: pg_backup_db.c:556
static void dump_lo_buf(ArchiveHandle *AH)
#define GZWRITE(p, s, n, fh)
CustomOutPtrType CustomOutPtr
#define WRITE_ERROR_EXIT

◆ ArchiveEntry()

TocEntry* ArchiveEntry ( Archive AHX,
CatalogId  catalogId,
DumpId  dumpId,
ArchiveOpts opts 
)

Definition at line 1061 of file pg_backup_archiver.c.

References _archiveHandle::ArchiveEntryPtr, _tocEntry::catalogId, _tocEntry::copyStmt, _tocEntry::dataDumper, _tocEntry::dataDumperArg, _tocEntry::dataLength, _tocEntry::defn, _tocEntry::dependencies, _tocEntry::desc, _tocEntry::dropStmt, _tocEntry::dumpId, _tocEntry::formatData, _tocEntry::hadDumper, _archiveHandle::maxDumpId, _tocEntry::nDeps, _tocEntry::next, _tocEntry::owner, pg_malloc(), pg_malloc0(), pg_strdup(), _tocEntry::prev, _tocEntry::section, _tocEntry::tableam, _tocEntry::tablespace, _tocEntry::tag, _archiveHandle::toc, _archiveHandle::tocCount, and true.

Referenced by dumpAccessMethod(), dumpACL(), dumpAgg(), dumpAttrDef(), dumpBaseType(), dumpBlob(), dumpCast(), dumpCollation(), dumpComment(), dumpCompositeType(), dumpCompositeTypeColComments(), dumpConstraint(), dumpConversion(), dumpDatabase(), dumpDefaultACL(), dumpDomain(), dumpDumpableObject(), dumpEncoding(), dumpEnumType(), dumpEventTrigger(), dumpExtension(), dumpForeignDataWrapper(), dumpForeignServer(), dumpFunc(), dumpIndex(), dumpIndexAttach(), dumpNamespace(), dumpOpclass(), dumpOpfamily(), dumpOpr(), dumpPolicy(), dumpProcLang(), dumpPublication(), dumpPublicationTable(), dumpRangeType(), dumpRule(), dumpSearchPath(), dumpSecLabel(), dumpSequence(), dumpSequenceData(), dumpShellType(), dumpStatisticsExt(), dumpStdStrings(), dumpSubscription(), dumpTableComment(), dumpTableData(), dumpTableSchema(), dumpTableSecLabel(), dumpTransform(), dumpTrigger(), dumpTSConfig(), dumpTSDictionary(), dumpTSParser(), dumpTSTemplate(), dumpUndefinedType(), dumpUserMappings(), and refreshMatViewData().

1063 {
1064  ArchiveHandle *AH = (ArchiveHandle *) AHX;
1065  TocEntry *newToc;
1066 
1067  newToc = (TocEntry *) pg_malloc0(sizeof(TocEntry));
1068 
1069  AH->tocCount++;
1070  if (dumpId > AH->maxDumpId)
1071  AH->maxDumpId = dumpId;
1072 
1073  newToc->prev = AH->toc->prev;
1074  newToc->next = AH->toc;
1075  AH->toc->prev->next = newToc;
1076  AH->toc->prev = newToc;
1077 
1078  newToc->catalogId = catalogId;
1079  newToc->dumpId = dumpId;
1080  newToc->section = opts->section;
1081 
1082  newToc->tag = pg_strdup(opts->tag);
1083  newToc->namespace = opts->namespace ? pg_strdup(opts->namespace) : NULL;
1084  newToc->tablespace = opts->tablespace ? pg_strdup(opts->tablespace) : NULL;
1085  newToc->tableam = opts->tableam ? pg_strdup(opts->tableam) : NULL;
1086  newToc->owner = opts->owner ? pg_strdup(opts->owner) : NULL;
1087  newToc->desc = pg_strdup(opts->description);
1088  newToc->defn = opts->createStmt ? pg_strdup(opts->createStmt) : NULL;
1089  newToc->dropStmt = opts->dropStmt ? pg_strdup(opts->dropStmt) : NULL;
1090  newToc->copyStmt = opts->copyStmt ? pg_strdup(opts->copyStmt) : NULL;
1091 
1092  if (opts->nDeps > 0)
1093  {
1094  newToc->dependencies = (DumpId *) pg_malloc(opts->nDeps * sizeof(DumpId));
1095  memcpy(newToc->dependencies, opts->deps, opts->nDeps * sizeof(DumpId));
1096  newToc->nDeps = opts->nDeps;
1097  }
1098  else
1099  {
1100  newToc->dependencies = NULL;
1101  newToc->nDeps = 0;
1102  }
1103 
1104  newToc->dataDumper = opts->dumpFn;
1105  newToc->dataDumperArg = opts->dumpArg;
1106  newToc->hadDumper = opts->dumpFn ? true : false;
1107 
1108  newToc->formatData = NULL;
1109  newToc->dataLength = 0;
1110 
1111  if (AH->ArchiveEntryPtr != NULL)
1112  AH->ArchiveEntryPtr(AH, newToc);
1113 
1114  return newToc;
1115 }
struct _tocEntry * next
int DumpId
Definition: pg_backup.h:234
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
CatalogId catalogId
void * dataDumperArg
DataDumperPtr dataDumper
teSection section
#define true
Definition: c.h:311
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
struct _tocEntry * toc
DumpId * dependencies
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
pgoff_t dataLength
struct _tocEntry * prev
ArchiveEntryPtrType ArchiveEntryPtr

◆ archprintf()

int archprintf ( Archive AH,
const char *  fmt,
  ... 
)

Definition at line 1466 of file pg_backup_archiver.c.

References generate_unaccent_rules::args, free, pg_malloc(), pvsnprintf(), and WriteData().

1467 {
1468  int save_errno = errno;
1469  char *p;
1470  size_t len = 128; /* initial assumption about buffer size */
1471  size_t cnt;
1472 
1473  for (;;)
1474  {
1475  va_list args;
1476 
1477  /* Allocate work buffer. */
1478  p = (char *) pg_malloc(len);
1479 
1480  /* Try to format the data. */
1481  errno = save_errno;
1482  va_start(args, fmt);
1483  cnt = pvsnprintf(p, len, fmt, args);
1484  va_end(args);
1485 
1486  if (cnt < len)
1487  break; /* success */
1488 
1489  /* Release buffer and loop around to try again with larger len. */
1490  free(p);
1491  len = cnt;
1492  }
1493 
1494  WriteData(AH, p, cnt);
1495  free(p);
1496  return (int) cnt;
1497 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args)
Definition: psprintf.c:106
void WriteData(Archive *AHX, const void *data, size_t dLen)
#define free(a)
Definition: header.h:65

◆ archputs()

void archputs ( const char *  s,
Archive AH 
)

Definition at line 1459 of file pg_backup_archiver.c.

References WriteData().

Referenced by dumpTableData_insert().

1460 {
1461  WriteData(AH, s, strlen(s));
1462 }
void WriteData(Archive *AHX, const void *data, size_t dLen)

◆ buildTocEntryArrays()

static void buildTocEntryArrays ( ArchiveHandle AH)
static

Definition at line 1832 of file pg_backup_archiver.c.

References _tocEntry::dependencies, _tocEntry::desc, _tocEntry::dumpId, fatal, _archiveHandle::maxDumpId, _tocEntry::nDeps, _tocEntry::next, pg_malloc0(), _archiveHandle::tableDataId, _archiveHandle::toc, and _archiveHandle::tocsByDumpId.

Referenced by getTocEntryByDumpId(), and RestoreArchive().

1833 {
1834  DumpId maxDumpId = AH->maxDumpId;
1835  TocEntry *te;
1836 
1837  AH->tocsByDumpId = (TocEntry **) pg_malloc0((maxDumpId + 1) * sizeof(TocEntry *));
1838  AH->tableDataId = (DumpId *) pg_malloc0((maxDumpId + 1) * sizeof(DumpId));
1839 
1840  for (te = AH->toc->next; te != AH->toc; te = te->next)
1841  {
1842  /* this check is purely paranoia, maxDumpId should be correct */
1843  if (te->dumpId <= 0 || te->dumpId > maxDumpId)
1844  fatal("bad dumpId");
1845 
1846  /* tocsByDumpId indexes all TOCs by their dump ID */
1847  AH->tocsByDumpId[te->dumpId] = te;
1848 
1849  /*
1850  * tableDataId provides the TABLE DATA item's dump ID for each TABLE
1851  * TOC entry that has a DATA item. We compute this by reversing the
1852  * TABLE DATA item's dependency, knowing that a TABLE DATA item has
1853  * just one dependency and it is the TABLE item.
1854  */
1855  if (strcmp(te->desc, "TABLE DATA") == 0 && te->nDeps > 0)
1856  {
1857  DumpId tableId = te->dependencies[0];
1858 
1859  /*
1860  * The TABLE item might not have been in the archive, if this was
1861  * a data-only dump; but its dump ID should be less than its data
1862  * item's dump ID, so there should be a place for it in the array.
1863  */
1864  if (tableId <= 0 || tableId > maxDumpId)
1865  fatal("bad table dumpId for TABLE DATA item");
1866 
1867  AH->tableDataId[tableId] = te->dumpId;
1868  }
1869  }
1870 }
struct _tocEntry * next
int DumpId
Definition: pg_backup.h:234
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
struct _tocEntry * toc
DumpId * dependencies
#define fatal(...)
struct _tocEntry ** tocsByDumpId

◆ checkSeek()

bool checkSeek ( FILE *  fp)

Definition at line 3871 of file pg_backup_archiver.c.

References fseeko, ftello, and pgoff_t.

Referenced by InitArchiveFmt_Custom(), and InitArchiveFmt_Tar().

3872 {
3873  pgoff_t tpos;
3874 
3875  /*
3876  * If pgoff_t is wider than long, we must have "real" fseeko and not an
3877  * emulation using fseek. Otherwise report no seek capability.
3878  */
3879 #ifndef HAVE_FSEEKO
3880  if (sizeof(pgoff_t) > sizeof(long))
3881  return false;
3882 #endif
3883 
3884  /* Check that ftello works on this file */
3885  tpos = ftello(fp);
3886  if (tpos < 0)
3887  return false;
3888 
3889  /*
3890  * Check that fseeko(SEEK_SET) works, too. NB: we used to try to test
3891  * this with fseeko(fp, 0, SEEK_CUR). But some platforms treat that as a
3892  * successful no-op even on files that are otherwise unseekable.
3893  */
3894  if (fseeko(fp, tpos, SEEK_SET) != 0)
3895  return false;
3896 
3897  return true;
3898 }
#define pgoff_t
Definition: win32_port.h:195
#define ftello(stream)
Definition: win32_port.h:204
#define fseeko(stream, offset, origin)
Definition: win32_port.h:201

◆ CloneArchive()

ArchiveHandle* CloneArchive ( ArchiveHandle AH)

Definition at line 4806 of file pg_backup_archiver.c.

References _doSetFixedOutputState(), appendConnStrVal(), appendPQExpBufferStr(), archModeRead, Assert, _archiveHandle::ClonePtr, _archiveHandle::connCancel, ConnectDatabase(), _archiveHandle::connection, connstr, _archiveHandle::currSchema, _archiveHandle::currTablespace, _archiveHandle::currUser, PQExpBufferData::data, _restoreOptions::dbname, initPQExpBuffer(), _archiveHandle::mode, Archive::n_errors, pg_malloc(), pg_strdup(), _restoreOptions::pghost, pghost, _restoreOptions::pgport, pgport, PQdb(), PQhost(), PQport(), PQuser(), _restoreOptions::promptPassword, _archiveHandle::public, Archive::ropt, _archiveHandle::savedPassword, _archiveHandle::sqlparse, termPQExpBuffer(), TRI_NO, _restoreOptions::username, and username.

Referenced by RunWorker().

4807 {
4808  ArchiveHandle *clone;
4809 
4810  /* Make a "flat" copy */
4811  clone = (ArchiveHandle *) pg_malloc(sizeof(ArchiveHandle));
4812  memcpy(clone, AH, sizeof(ArchiveHandle));
4813 
4814  /* Handle format-independent fields */
4815  memset(&(clone->sqlparse), 0, sizeof(clone->sqlparse));
4816 
4817  /* The clone will have its own connection, so disregard connection state */
4818  clone->connection = NULL;
4819  clone->connCancel = NULL;
4820  clone->currUser = NULL;
4821  clone->currSchema = NULL;
4822  clone->currTablespace = NULL;
4823 
4824  /* savedPassword must be local in case we change it while connecting */
4825  if (clone->savedPassword)
4826  clone->savedPassword = pg_strdup(clone->savedPassword);
4827 
4828  /* clone has its own error count, too */
4829  clone->public.n_errors = 0;
4830 
4831  /*
4832  * Connect our new clone object to the database: In parallel restore the
4833  * parent is already disconnected, because we can connect the worker
4834  * processes independently to the database (no snapshot sync required). In
4835  * parallel backup we clone the parent's existing connection.
4836  */
4837  if (AH->mode == archModeRead)
4838  {
4839  RestoreOptions *ropt = AH->public.ropt;
4840 
4841  Assert(AH->connection == NULL);
4842 
4843  /* this also sets clone->connection */
4844  ConnectDatabase((Archive *) clone, ropt->dbname,
4845  ropt->pghost, ropt->pgport, ropt->username,
4846  ropt->promptPassword);
4847 
4848  /* re-establish fixed state */
4849  _doSetFixedOutputState(clone);
4850  }
4851  else
4852  {
4854  char *pghost;
4855  char *pgport;
4856  char *username;
4857 
4858  Assert(AH->connection != NULL);
4859 
4860  /*
4861  * Even though we are technically accessing the parent's database
4862  * object here, these functions are fine to be called like that
4863  * because all just return a pointer and do not actually send/receive
4864  * any data to/from the database.
4865  */
4866  initPQExpBuffer(&connstr);
4867  appendPQExpBufferStr(&connstr, "dbname=");
4868  appendConnStrVal(&connstr, PQdb(AH->connection));
4869  pghost = PQhost(AH->connection);
4870  pgport = PQport(AH->connection);
4871  username = PQuser(AH->connection);
4872 
4873  /* this also sets clone->connection */
4874  ConnectDatabase((Archive *) clone, connstr.data,
4875  pghost, pgport, username, TRI_NO);
4876 
4877  termPQExpBuffer(&connstr);
4878  /* setupDumpWorker will fix up connection state */
4879  }
4880 
4881  /* Let the format-specific code have a chance too */
4882  clone->ClonePtr(clone);
4883 
4884  Assert(clone->connection != NULL);
4885  return clone;
4886 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
RestoreOptions * ropt
Definition: pg_backup.h:183
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
char * username
Definition: pg_backup.h:113
void appendConnStrVal(PQExpBuffer buf, const char *str)
Definition: string_utils.c:545
char * PQport(const PGconn *conn)
Definition: fe-connect.c:6603
int n_errors
Definition: pg_backup.h:206
PGcancel *volatile connCancel
char * PQuser(const PGconn *conn)
Definition: fe-connect.c:6542
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static void _doSetFixedOutputState(ArchiveHandle *AH)
sqlparseInfo sqlparse
char * pghost
Definition: pgbench.c:242
static char * username
Definition: initdb.c:133
char * PQhost(const PGconn *conn)
Definition: fe-connect.c:6567
char * PQdb(const PGconn *conn)
Definition: fe-connect.c:6534
#define Assert(condition)
Definition: c.h:728
ClonePtrType ClonePtr
char * pgport
Definition: pgbench.c:243
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92
void ConnectDatabase(Archive *AH, const char *dbname, const char *pghost, const char *pgport, const char *username, trivalue prompt_password)
Definition: pg_backup_db.c:236
static char * connstr
Definition: pg_dumpall.c:61
trivalue promptPassword
Definition: pg_backup.h:115

◆ CloseArchive()

void CloseArchive ( Archive AHX)

Definition at line 257 of file pg_backup_archiver.c.

References _archiveHandle::ClosePtr, fatal, GZCLOSE, _archiveHandle::gzOut, _archiveHandle::OF, and generate_unaccent_rules::stdout.

Referenced by main().

258 {
259  int res = 0;
260  ArchiveHandle *AH = (ArchiveHandle *) AHX;
261 
262  AH->ClosePtr(AH);
263 
264  /* Close the output */
265  if (AH->gzOut)
266  res = GZCLOSE(AH->OF);
267  else if (AH->OF != stdout)
268  res = fclose(AH->OF);
269 
270  if (res != 0)
271  fatal("could not close output file: %m");
272 }
#define fatal(...)
#define GZCLOSE(fh)
ClosePtrType ClosePtr

◆ CreateArchive()

Archive* CreateArchive ( const char *  FileSpec,
const ArchiveFormat  fmt,
const int  compression,
bool  dosync,
ArchiveMode  mode,
SetupWorkerPtrType  setupDumpWorker 
)

Definition at line 234 of file pg_backup_archiver.c.

References _allocAH().

Referenced by main().

238 {
239  ArchiveHandle *AH = _allocAH(FileSpec, fmt, compression, dosync,
241 
242  return (Archive *) AH;
243 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
static ArchiveHandle * _allocAH(const char *FileSpec, const ArchiveFormat fmt, const int compression, bool dosync, ArchiveMode mode, SetupWorkerPtrType setupWorkerPtr)
static bool dosync
Definition: pg_dump.c:92
static void setupDumpWorker(Archive *AHX)
Definition: pg_dump.c:1226

◆ DeCloneArchive()

void DeCloneArchive ( ArchiveHandle AH)

Definition at line 4894 of file pg_backup_archiver.c.

References Assert, _archiveHandle::connection, sqlparseInfo::curCmd, _archiveHandle::currSchema, _archiveHandle::currTableAm, _archiveHandle::currTablespace, _archiveHandle::currUser, _archiveHandle::DeClonePtr, destroyPQExpBuffer(), free, _archiveHandle::savedPassword, and _archiveHandle::sqlparse.

Referenced by RunWorker().

4895 {
4896  /* Should not have an open database connection */
4897  Assert(AH->connection == NULL);
4898 
4899  /* Clear format-specific state */
4900  AH->DeClonePtr(AH);
4901 
4902  /* Clear state allocated by CloneArchive */
4903  if (AH->sqlparse.curCmd)
4905 
4906  /* Clear any connection-local state */
4907  if (AH->currUser)
4908  free(AH->currUser);
4909  if (AH->currSchema)
4910  free(AH->currSchema);
4911  if (AH->currTablespace)
4912  free(AH->currTablespace);
4913  if (AH->currTableAm)
4914  free(AH->currTableAm);
4915  if (AH->savedPassword)
4916  free(AH->savedPassword);
4917 
4918  free(AH);
4919 }
PQExpBuffer curCmd
DeClonePtrType DeClonePtr
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:116
sqlparseInfo sqlparse
#define free(a)
Definition: header.h:65
#define Assert(condition)
Definition: c.h:728

◆ dump_lo_buf()

static void dump_lo_buf ( ArchiveHandle AH)
static

Definition at line 1651 of file pg_backup_archiver.c.

References ahprintf(), appendByteaLiteralAHX, buf, _archiveHandle::connection, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), fatal, _archiveHandle::lo_buf, _archiveHandle::lo_buf_used, lo_write(), _archiveHandle::loFd, ngettext, pg_log_debug, and _archiveHandle::writingBlob.

Referenced by ahwrite(), and EndRestoreBlob().

1652 {
1653  if (AH->connection)
1654  {
1655  size_t res;
1656 
1657  res = lo_write(AH->connection, AH->loFd, AH->lo_buf, AH->lo_buf_used);
1658  pg_log_debug(ngettext("wrote %lu byte of large object data (result = %lu)",
1659  "wrote %lu bytes of large object data (result = %lu)",
1660  AH->lo_buf_used),
1661  (unsigned long) AH->lo_buf_used, (unsigned long) res);
1662  if (res != AH->lo_buf_used)
1663  fatal("could not write to large object (result: %lu, expected: %lu)",
1664  (unsigned long) res, (unsigned long) AH->lo_buf_used);
1665  }
1666  else
1667  {
1669 
1671  (const unsigned char *) AH->lo_buf,
1672  AH->lo_buf_used,
1673  AH);
1674 
1675  /* Hack: turn off writingBlob so ahwrite doesn't recurse to here */
1676  AH->writingBlob = 0;
1677  ahprintf(AH, "SELECT pg_catalog.lowrite(0, %s);\n", buf->data);
1678  AH->writingBlob = 1;
1679 
1680  destroyPQExpBuffer(buf);
1681  }
1682  AH->lo_buf_used = 0;
1683 }
#define appendByteaLiteralAHX(buf, str, len, AH)
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:116
#define pg_log_debug(...)
Definition: logging.h:91
static char * buf
Definition: pg_test_fsync.c:67
int lo_write(int fd, const char *buf, int len)
Definition: be-fsstubs.c:170
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
#define ngettext(s, p, n)
Definition: c.h:1132
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:74
#define fatal(...)

◆ dumpOptionsFromRestoreOptions()

DumpOptions* dumpOptionsFromRestoreOptions ( RestoreOptions ropt)

Definition at line 176 of file pg_backup_archiver.c.

References _restoreOptions::aclsSkip, _dumpOptions::aclsSkip, _restoreOptions::column_inserts, _dumpOptions::column_inserts, _restoreOptions::createDB, _restoreOptions::dataOnly, _dumpOptions::dataOnly, _restoreOptions::disable_dollar_quoting, _dumpOptions::disable_dollar_quoting, _restoreOptions::disable_triggers, _dumpOptions::disable_triggers, _restoreOptions::dropSchema, _restoreOptions::dump_inserts, _dumpOptions::dump_inserts, _restoreOptions::dumpSections, _dumpOptions::dumpSections, _restoreOptions::enable_row_security, _dumpOptions::enable_row_security, _restoreOptions::if_exists, _dumpOptions::if_exists, _restoreOptions::include_everything, _dumpOptions::include_everything, _restoreOptions::lockWaitTimeout, _dumpOptions::lockWaitTimeout, NewDumpOptions(), _restoreOptions::no_comments, _dumpOptions::no_comments, _restoreOptions::no_publications, _dumpOptions::no_publications, _restoreOptions::no_security_labels, _dumpOptions::no_security_labels, _restoreOptions::no_subscriptions, _dumpOptions::no_subscriptions, _restoreOptions::noOwner, _restoreOptions::noTablespace, _dumpOptions::outputClean, _dumpOptions::outputCreateDB, _dumpOptions::outputNoOwner, _dumpOptions::outputNoTablespaces, _dumpOptions::outputSuperuser, _restoreOptions::schemaOnly, _dumpOptions::schemaOnly, _restoreOptions::sequence_data, _dumpOptions::sequence_data, _restoreOptions::superuser, _restoreOptions::use_setsessauth, and _dumpOptions::use_setsessauth.

Referenced by SetArchiveOptions().

177 {
178  DumpOptions *dopt = NewDumpOptions();
179 
180  /* this is the inverse of what's at the end of pg_dump.c's main() */
181  dopt->outputClean = ropt->dropSchema;
182  dopt->dataOnly = ropt->dataOnly;
183  dopt->schemaOnly = ropt->schemaOnly;
184  dopt->if_exists = ropt->if_exists;
185  dopt->column_inserts = ropt->column_inserts;
186  dopt->dumpSections = ropt->dumpSections;
187  dopt->aclsSkip = ropt->aclsSkip;
188  dopt->outputSuperuser = ropt->superuser;
189  dopt->outputCreateDB = ropt->createDB;
190  dopt->outputNoOwner = ropt->noOwner;
191  dopt->outputNoTablespaces = ropt->noTablespace;
192  dopt->disable_triggers = ropt->disable_triggers;
193  dopt->use_setsessauth = ropt->use_setsessauth;
195  dopt->dump_inserts = ropt->dump_inserts;
196  dopt->no_comments = ropt->no_comments;
197  dopt->no_publications = ropt->no_publications;
199  dopt->no_subscriptions = ropt->no_subscriptions;
200  dopt->lockWaitTimeout = ropt->lockWaitTimeout;
203  dopt->sequence_data = ropt->sequence_data;
204 
205  return dopt;
206 }
int column_inserts
Definition: pg_backup.h:147
int disable_triggers
Definition: pg_backup.h:156
int disable_dollar_quoting
Definition: pg_backup.h:73
bool schemaOnly
Definition: pg_backup.h:138
int no_subscriptions
Definition: pg_backup.h:152
int no_publications
Definition: pg_backup.h:151
DumpOptions * NewDumpOptions(void)
int sequence_data
Definition: pg_backup.h:172
const char * lockWaitTimeout
Definition: pg_backup.h:89
int use_setsessauth
Definition: pg_backup.h:158
int disable_dollar_quoting
Definition: pg_backup.h:146
int column_inserts
Definition: pg_backup.h:75
const char * lockWaitTimeout
Definition: pg_backup.h:142
bool dataOnly
Definition: pg_backup.h:139
bool include_everything
Definition: pg_backup.h:163
char * outputSuperuser
Definition: pg_backup.h:170
int include_everything
Definition: pg_backup.h:90
int no_security_labels
Definition: pg_backup.h:79
int dumpSections
Definition: pg_backup.h:140
int enable_row_security
Definition: pg_backup.h:123
int dump_inserts
Definition: pg_backup.h:143
int outputNoOwner
Definition: pg_backup.h:169
int no_security_labels
Definition: pg_backup.h:150
int no_subscriptions
Definition: pg_backup.h:80
char * superuser
Definition: pg_backup.h:70
bool aclsSkip
Definition: pg_backup.h:141
int use_setsessauth
Definition: pg_backup.h:68
int enable_row_security
Definition: pg_backup.h:159
int outputCreateDB
Definition: pg_backup.h:166
int outputClean
Definition: pg_backup.h:165
int no_comments
Definition: pg_backup.h:149
int outputNoTablespaces
Definition: pg_backup.h:157
int no_publications
Definition: pg_backup.h:78
int disable_triggers
Definition: pg_backup.h:66

◆ dumpTimestamp()

static void dumpTimestamp ( ArchiveHandle AH,
const char *  msg,
time_t  tim 
)
static

Definition at line 3905 of file pg_backup_archiver.c.

References ahprintf(), buf, and PGDUMP_STRFTIME_FMT.

Referenced by RestoreArchive().

3906 {
3907  char buf[64];
3908 
3909  if (strftime(buf, sizeof(buf), PGDUMP_STRFTIME_FMT, localtime(&tim)) != 0)
3910  ahprintf(AH, "-- %s %s\n\n", msg, buf);
3911 }
static char * buf
Definition: pg_test_fsync.c:67
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
#define PGDUMP_STRFTIME_FMT
Definition: dumputils.h:33

◆ EndBlob()

int EndBlob ( Archive AHX,
Oid  oid 
)

Definition at line 1237 of file pg_backup_archiver.c.

References _archiveHandle::currToc, and _archiveHandle::EndBlobPtr.

Referenced by dumpBlobs().

1238 {
1239  ArchiveHandle *AH = (ArchiveHandle *) AHX;
1240 
1241  if (AH->EndBlobPtr)
1242  AH->EndBlobPtr(AH, AH->currToc, oid);
1243 
1244  return 1;
1245 }
struct _tocEntry * currToc
EndBlobPtrType EndBlobPtr

◆ EndRestoreBlob()

void EndRestoreBlob ( ArchiveHandle AH,
Oid  oid 
)

Definition at line 1341 of file pg_backup_archiver.c.

References ahprintf(), _archiveHandle::connection, dump_lo_buf(), _archiveHandle::lo_buf_used, lo_close(), _archiveHandle::loFd, and _archiveHandle::writingBlob.

Referenced by _LoadBlobs().

1342 {
1343  if (AH->lo_buf_used > 0)
1344  {
1345  /* Write remaining bytes from the LO buffer */
1346  dump_lo_buf(AH);
1347  }
1348 
1349  AH->writingBlob = 0;
1350 
1351  if (AH->connection)
1352  {
1353  lo_close(AH->connection, AH->loFd);
1354  AH->loFd = -1;
1355  }
1356  else
1357  {
1358  ahprintf(AH, "SELECT pg_catalog.lo_close(0);\n\n");
1359  }
1360 }
int lo_close(PGconn *conn, int fd)
Definition: fe-lobj.c:99
static void dump_lo_buf(ArchiveHandle *AH)
int ahprintf(ArchiveHandle *AH, const char *fmt,...)

◆ EndRestoreBlobs()

void EndRestoreBlobs ( ArchiveHandle AH)

Definition at line 1274 of file pg_backup_archiver.c.

References ahprintf(), _archiveHandle::blobCount, CommitTransaction(), _archiveHandle::connection, ngettext, pg_log_info, _archiveHandle::public, Archive::ropt, and _restoreOptions::single_txn.

Referenced by _LoadBlobs().

1275 {
1276  RestoreOptions *ropt = AH->public.ropt;
1277 
1278  if (!ropt->single_txn)
1279  {
1280  if (AH->connection)
1281  CommitTransaction(&AH->public);
1282  else
1283  ahprintf(AH, "COMMIT;\n\n");
1284  }
1285 
1286  pg_log_info(ngettext("restored %d large object",
1287  "restored %d large objects",
1288  AH->blobCount),
1289  AH->blobCount);
1290 }
RestoreOptions * ropt
Definition: pg_backup.h:183
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
#define ngettext(s, p, n)
Definition: c.h:1132
static void CommitTransaction(void)
Definition: xact.c:2045
#define pg_log_info(...)
Definition: logging.h:87

◆ fix_dependencies()

static void fix_dependencies ( ArchiveHandle AH)
static

Definition at line 4503 of file pg_backup_archiver.c.

References _tocEntry::depCount, _tocEntry::dependencies, _tocEntry::desc, _tocEntry::dumpId, i, identify_locking_dependencies(), K_VERS_1_11, _tocEntry::lockDeps, _tocEntry::nDeps, _tocEntry::next, _tocEntry::nLockDeps, _tocEntry::nRevDeps, _tocEntry::pending_next, _tocEntry::pending_prev, pg_malloc(), repoint_table_dependencies(), _tocEntry::revDeps, _archiveHandle::toc, _archiveHandle::tocsByDumpId, and _archiveHandle::version.

Referenced by IndexSetParentIndex(), and restore_toc_entries_prefork().

4504 {
4505  TocEntry *te;
4506  int i;
4507 
4508  /*
4509  * Initialize the depCount/revDeps/nRevDeps fields, and make sure the TOC
4510  * items are marked as not being in any parallel-processing list.
4511  */
4512  for (te = AH->toc->next; te != AH->toc; te = te->next)
4513  {
4514  te->depCount = te->nDeps;
4515  te->revDeps = NULL;
4516  te->nRevDeps = 0;
4517  te->pending_prev = NULL;
4518  te->pending_next = NULL;
4519  }
4520 
4521  /*
4522  * POST_DATA items that are shown as depending on a table need to be
4523  * re-pointed to depend on that table's data, instead. This ensures they
4524  * won't get scheduled until the data has been loaded.
4525  */
4527 
4528  /*
4529  * Pre-8.4 versions of pg_dump neglected to set up a dependency from BLOB
4530  * COMMENTS to BLOBS. Cope. (We assume there's only one BLOBS and only
4531  * one BLOB COMMENTS in such files.)
4532  */
4533  if (AH->version < K_VERS_1_11)
4534  {
4535  for (te = AH->toc->next; te != AH->toc; te = te->next)
4536  {
4537  if (strcmp(te->desc, "BLOB COMMENTS") == 0 && te->nDeps == 0)
4538  {
4539  TocEntry *te2;
4540 
4541  for (te2 = AH->toc->next; te2 != AH->toc; te2 = te2->next)
4542  {
4543  if (strcmp(te2->desc, "BLOBS") == 0)
4544  {
4545  te->dependencies = (DumpId *) pg_malloc(sizeof(DumpId));
4546  te->dependencies[0] = te2->dumpId;
4547  te->nDeps++;
4548  te->depCount++;
4549  break;
4550  }
4551  }
4552  break;
4553  }
4554  }
4555  }
4556 
4557  /*
4558  * At this point we start to build the revDeps reverse-dependency arrays,
4559  * so all changes of dependencies must be complete.
4560  */
4561 
4562  /*
4563  * Count the incoming dependencies for each item. Also, it is possible
4564  * that the dependencies list items that are not in the archive at all
4565  * (that should not happen in 9.2 and later, but is highly likely in older
4566  * archives). Subtract such items from the depCounts.
4567  */
4568  for (te = AH->toc->next; te != AH->toc; te = te->next)
4569  {
4570  for (i = 0; i < te->nDeps; i++)
4571  {
4572  DumpId depid = te->dependencies[i];
4573 
4574  if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL)
4575  AH->tocsByDumpId[depid]->nRevDeps++;
4576  else
4577  te->depCount--;
4578  }
4579  }
4580 
4581  /*
4582  * Allocate space for revDeps[] arrays, and reset nRevDeps so we can use
4583  * it as a counter below.
4584  */
4585  for (te = AH->toc->next; te != AH->toc; te = te->next)
4586  {
4587  if (te->nRevDeps > 0)
4588  te->revDeps = (DumpId *) pg_malloc(te->nRevDeps * sizeof(DumpId));
4589  te->nRevDeps = 0;
4590  }
4591 
4592  /*
4593  * Build the revDeps[] arrays of incoming-dependency dumpIds. This had
4594  * better agree with the loops above.
4595  */
4596  for (te = AH->toc->next; te != AH->toc; te = te->next)
4597  {
4598  for (i = 0; i < te->nDeps; i++)
4599  {
4600  DumpId depid = te->dependencies[i];
4601 
4602  if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL)
4603  {
4604  TocEntry *otherte = AH->tocsByDumpId[depid];
4605 
4606  otherte->revDeps[otherte->nRevDeps++] = te->dumpId;
4607  }
4608  }
4609  }
4610 
4611  /*
4612  * Lastly, work out the locking dependencies.
4613  */
4614  for (te = AH->toc->next; te != AH->toc; te = te->next)
4615  {
4616  te->lockDeps = NULL;
4617  te->nLockDeps = 0;
4619  }
4620 }
struct _tocEntry * next
int DumpId
Definition: pg_backup.h:234
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
struct _tocEntry * pending_prev
DumpId * lockDeps
struct _tocEntry * pending_next
struct _tocEntry * toc
DumpId * dependencies
DumpId * revDeps
struct _tocEntry ** tocsByDumpId
static void identify_locking_dependencies(ArchiveHandle *AH, TocEntry *te)
int i
#define K_VERS_1_11
static void repoint_table_dependencies(ArchiveHandle *AH)

◆ getTocEntryByDumpId()

TocEntry* getTocEntryByDumpId ( ArchiveHandle AH,
DumpId  id 
)

Definition at line 1873 of file pg_backup_archiver.c.

References buildTocEntryArrays(), and _archiveHandle::tocsByDumpId.

Referenced by parseWorkerCommand(), SortTocFromFile(), and TocIDRequired().

1874 {
1875  /* build index arrays if we didn't already */
1876  if (AH->tocsByDumpId == NULL)
1877  buildTocEntryArrays(AH);
1878 
1879  if (id > 0 && id <= AH->maxDumpId)
1880  return AH->tocsByDumpId[id];
1881 
1882  return NULL;
1883 }
static void buildTocEntryArrays(ArchiveHandle *AH)
struct _tocEntry ** tocsByDumpId

◆ has_lock_conflicts()

static bool has_lock_conflicts ( TocEntry te1,
TocEntry te2 
)
static

Definition at line 4194 of file pg_backup_archiver.c.

References _tocEntry::dependencies, _tocEntry::lockDeps, _tocEntry::nDeps, and _tocEntry::nLockDeps.

Referenced by pop_next_work_item().

4195 {
4196  int j,
4197  k;
4198 
4199  for (j = 0; j < te1->nLockDeps; j++)
4200  {
4201  for (k = 0; k < te2->nDeps; k++)
4202  {
4203  if (te1->lockDeps[j] == te2->dependencies[k])
4204  return true;
4205  }
4206  }
4207  return false;
4208 }
DumpId * lockDeps
DumpId * dependencies

◆ identify_locking_dependencies()

static void identify_locking_dependencies ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 4667 of file pg_backup_archiver.c.

References _tocEntry::dependencies, _tocEntry::desc, free, i, _tocEntry::lockDeps, _tocEntry::nDeps, _tocEntry::nLockDeps, pg_malloc(), pg_realloc(), _tocEntry::section, SECTION_POST_DATA, and _archiveHandle::tocsByDumpId.

Referenced by fix_dependencies().

4668 {
4669  DumpId *lockids;
4670  int nlockids;
4671  int i;
4672 
4673  /*
4674  * We only care about this for POST_DATA items. PRE_DATA items are not
4675  * run in parallel, and DATA items are all independent by assumption.
4676  */
4677  if (te->section != SECTION_POST_DATA)
4678  return;
4679 
4680  /* Quick exit if no dependencies at all */
4681  if (te->nDeps == 0)
4682  return;
4683 
4684  /*
4685  * Most POST_DATA items are ALTER TABLEs or some moral equivalent of that,
4686  * and hence require exclusive lock. However, we know that CREATE INDEX
4687  * does not. (Maybe someday index-creating CONSTRAINTs will fall in that
4688  * category too ... but today is not that day.)
4689  */
4690  if (strcmp(te->desc, "INDEX") == 0)
4691  return;
4692 
4693  /*
4694  * We assume the entry requires exclusive lock on each TABLE or TABLE DATA
4695  * item listed among its dependencies. Originally all of these would have
4696  * been TABLE items, but repoint_table_dependencies would have repointed
4697  * them to the TABLE DATA items if those are present (which they might not
4698  * be, eg in a schema-only dump). Note that all of the entries we are
4699  * processing here are POST_DATA; otherwise there might be a significant
4700  * difference between a dependency on a table and a dependency on its
4701  * data, so that closer analysis would be needed here.
4702  */
4703  lockids = (DumpId *) pg_malloc(te->nDeps * sizeof(DumpId));
4704  nlockids = 0;
4705  for (i = 0; i < te->nDeps; i++)
4706  {
4707  DumpId depid = te->dependencies[i];
4708 
4709  if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL &&
4710  ((strcmp(AH->tocsByDumpId[depid]->desc, "TABLE DATA") == 0) ||
4711  strcmp(AH->tocsByDumpId[depid]->desc, "TABLE") == 0))
4712  lockids[nlockids++] = depid;
4713  }
4714 
4715  if (nlockids == 0)
4716  {
4717  free(lockids);
4718  return;
4719  }
4720 
4721  te->lockDeps = pg_realloc(lockids, nlockids * sizeof(DumpId));
4722  te->nLockDeps = nlockids;
4723 }
int DumpId
Definition: pg_backup.h:234
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
DumpId * lockDeps
teSection section
DumpId * dependencies
void * pg_realloc(void *ptr, size_t size)
Definition: fe_memutils.c:65
#define free(a)
Definition: header.h:65
struct _tocEntry ** tocsByDumpId
int i

◆ inhibit_data_for_failed_table()

static void inhibit_data_for_failed_table ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 4786 of file pg_backup_archiver.c.

References _tocEntry::dumpId, pg_log_info, _tocEntry::reqs, _archiveHandle::tableDataId, _tocEntry::tag, and _archiveHandle::tocsByDumpId.

Referenced by mark_restore_job_done(), and restore_toc_entry().

4787 {
4788  pg_log_info("table \"%s\" could not be created, will not restore its data",
4789  te->tag);
4790 
4791  if (AH->tableDataId[te->dumpId] != 0)
4792  {
4793  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4794 
4795  ted->reqs = 0;
4796  }
4797 }
struct _tocEntry ** tocsByDumpId
#define pg_log_info(...)
Definition: logging.h:87

◆ InitDumpOptions()

void InitDumpOptions ( DumpOptions opts)

Definition at line 163 of file pg_backup_archiver.c.

References DUMP_UNSECTIONED, _dumpOptions::dumpSections, and _dumpOptions::include_everything.

Referenced by main(), and NewDumpOptions().

164 {
165  memset(opts, 0, sizeof(DumpOptions));
166  /* set any fields that shouldn't default to zeroes */
167  opts->include_everything = true;
169 }
bool include_everything
Definition: pg_backup.h:163
int dumpSections
Definition: pg_backup.h:140

◆ mark_create_done()

static void mark_create_done ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 4771 of file pg_backup_archiver.c.

References _tocEntry::created, _tocEntry::dumpId, _archiveHandle::tableDataId, and _archiveHandle::tocsByDumpId.

Referenced by mark_restore_job_done(), and restore_toc_entry().

4772 {
4773  if (AH->tableDataId[te->dumpId] != 0)
4774  {
4775  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4776 
4777  ted->created = true;
4778  }
4779 }
struct _tocEntry ** tocsByDumpId

◆ mark_dump_job_done()

static void mark_dump_job_done ( ArchiveHandle AH,
TocEntry te,
int  status,
void *  callback_data 
)
static

Definition at line 2456 of file pg_backup_archiver.c.

References _tocEntry::desc, _tocEntry::dumpId, fatal, pg_log_info, and _tocEntry::tag.

Referenced by WriteDataChunks().

2460 {
2461  pg_log_info("finished item %d %s %s",
2462  te->dumpId, te->desc, te->tag);
2463 
2464  if (status != 0)
2465  fatal("worker process failed: exit code %d",
2466  status);
2467 }
#define fatal(...)
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:225
#define pg_log_info(...)
Definition: logging.h:87

◆ mark_restore_job_done()

static void mark_restore_job_done ( ArchiveHandle AH,
TocEntry te,
int  status,
void *  callback_data 
)
static

Definition at line 4462 of file pg_backup_archiver.c.

References _tocEntry::desc, _tocEntry::dumpId, fatal, inhibit_data_for_failed_table(), mark_create_done(), Archive::n_errors, pg_log_info, _archiveHandle::public, reduce_dependencies(), _tocEntry::tag, WORKER_CREATE_DONE, WORKER_IGNORED_ERRORS, and WORKER_INHIBIT_DATA.

Referenced by restore_toc_entries_parallel().

4466 {
4467  ParallelReadyList *ready_list = (ParallelReadyList *) callback_data;
4468 
4469  pg_log_info("finished item %d %s %s",
4470  te->dumpId, te->desc, te->tag);
4471 
4472  if (status == WORKER_CREATE_DONE)
4473  mark_create_done(AH, te);
4474  else if (status == WORKER_INHIBIT_DATA)
4475  {
4477  AH->public.n_errors++;
4478  }
4479  else if (status == WORKER_IGNORED_ERRORS)
4480  AH->public.n_errors++;
4481  else if (status != 0)
4482  fatal("worker process failed: exit code %d",
4483  status);
4484 
4485  reduce_dependencies(AH, te, ready_list);
4486 }
#define WORKER_CREATE_DONE
int n_errors
Definition: pg_backup.h:206
#define WORKER_IGNORED_ERRORS
static void reduce_dependencies(ArchiveHandle *AH, TocEntry *te, ParallelReadyList *ready_list)
static void inhibit_data_for_failed_table(ArchiveHandle *AH, TocEntry *te)
#define WORKER_INHIBIT_DATA
static void mark_create_done(ArchiveHandle *AH, TocEntry *te)
#define fatal(...)
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:225
#define pg_log_info(...)
Definition: logging.h:87

◆ move_to_ready_list()

static void move_to_ready_list ( TocEntry pending_list,
ParallelReadyList ready_list,
RestorePass  pass 
)
static

Definition at line 4347 of file pg_backup_archiver.c.

References _tocEntryRestorePass(), _tocEntry::depCount, pending_list_remove(), _tocEntry::pending_next, and ready_list_insert().

Referenced by restore_toc_entries_parallel().

4350 {
4351  TocEntry *te;
4352  TocEntry *next_te;
4353 
4354  for (te = pending_list->pending_next; te != pending_list; te = next_te)
4355  {
4356  /* must save list link before possibly removing te from list */
4357  next_te = te->pending_next;
4358 
4359  if (te->depCount == 0 &&
4360  _tocEntryRestorePass(te) == pass)
4361  {
4362  /* Remove it from pending_list ... */
4363  pending_list_remove(te);
4364  /* ... and add to ready_list */
4365  ready_list_insert(ready_list, te);
4366  }
4367  }
4368 }
struct _tocEntry * pending_next
static RestorePass _tocEntryRestorePass(TocEntry *te)
static void pending_list_remove(TocEntry *te)
static void ready_list_insert(ParallelReadyList *ready_list, TocEntry *te)

◆ NewDumpOptions()

DumpOptions* NewDumpOptions ( void  )

Definition at line 151 of file pg_backup_archiver.c.

References InitDumpOptions(), and pg_malloc().

Referenced by dumpOptionsFromRestoreOptions().

152 {
153  DumpOptions *opts = (DumpOptions *) pg_malloc(sizeof(DumpOptions));
154 
155  InitDumpOptions(opts);
156  return opts;
157 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
void InitDumpOptions(DumpOptions *opts)

◆ NewRestoreOptions()

RestoreOptions* NewRestoreOptions ( void  )

Definition at line 968 of file pg_backup_archiver.c.

References archUnknown, DUMP_UNSECTIONED, _restoreOptions::dumpSections, _restoreOptions::format, pg_malloc0(), _restoreOptions::promptPassword, and TRI_DEFAULT.

Referenced by _CloseArchive(), and main().

969 {
970  RestoreOptions *opts;
971 
972  opts = (RestoreOptions *) pg_malloc0(sizeof(RestoreOptions));
973 
974  /* set any fields that shouldn't default to zeroes */
975  opts->format = archUnknown;
976  opts->promptPassword = TRI_DEFAULT;
978 
979  return opts;
980 }
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
trivalue promptPassword
Definition: pg_backup.h:115

◆ OpenArchive()

Archive* OpenArchive ( const char *  FileSpec,
const ArchiveFormat  fmt 
)

Definition at line 248 of file pg_backup_archiver.c.

References _allocAH(), archModeRead, and setupRestoreWorker().

Referenced by main().

249 {
250  ArchiveHandle *AH = _allocAH(FileSpec, fmt, 0, true, archModeRead, setupRestoreWorker);
251 
252  return (Archive *) AH;
253 }
static ArchiveHandle * _allocAH(const char *FileSpec, const ArchiveFormat fmt, const int compression, bool dosync, ArchiveMode mode, SetupWorkerPtrType setupWorkerPtr)
static void setupRestoreWorker(Archive *AHX)

◆ parallel_restore()

int parallel_restore ( ArchiveHandle AH,
TocEntry te 
)

Definition at line 4439 of file pg_backup_archiver.c.

References Assert, _archiveHandle::connection, Archive::n_errors, _archiveHandle::public, restore_toc_entry(), and status().

Referenced by _WorkerJobRestoreCustom(), and _WorkerJobRestoreDirectory().

4440 {
4441  int status;
4442 
4443  Assert(AH->connection != NULL);
4444 
4445  /* Count only errors associated with this TOC entry */
4446  AH->public.n_errors = 0;
4447 
4448  /* Restore the TOC item */
4449  status = restore_toc_entry(AH, te, true);
4450 
4451  return status;
4452 }
int n_errors
Definition: pg_backup.h:206
static int restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel)
#define Assert(condition)
Definition: c.h:728
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:225

◆ pending_list_append()

static void pending_list_append ( TocEntry l,
TocEntry te 
)
static

Definition at line 4226 of file pg_backup_archiver.c.

References _tocEntry::pending_next, and _tocEntry::pending_prev.

Referenced by restore_toc_entries_prefork().

4227 {
4228  te->pending_prev = l->pending_prev;
4229  l->pending_prev->pending_next = te;
4230  l->pending_prev = te;
4231  te->pending_next = l;
4232 }
struct _tocEntry * pending_prev
struct _tocEntry * pending_next

◆ pending_list_header_init()

static void pending_list_header_init ( TocEntry l)
static

Definition at line 4219 of file pg_backup_archiver.c.

References _tocEntry::pending_next, and _tocEntry::pending_prev.

Referenced by RestoreArchive().

4220 {
4221  l->pending_prev = l->pending_next = l;
4222 }
struct _tocEntry * pending_prev
struct _tocEntry * pending_next

◆ pending_list_remove()

static void pending_list_remove ( TocEntry te)
static

Definition at line 4236 of file pg_backup_archiver.c.

References _tocEntry::pending_next, and _tocEntry::pending_prev.

Referenced by move_to_ready_list(), and reduce_dependencies().

4237 {
4240  te->pending_prev = NULL;
4241  te->pending_next = NULL;
4242 }
struct _tocEntry * pending_prev
struct _tocEntry * pending_next

◆ pop_next_work_item()

static TocEntry * pop_next_work_item ( ArchiveHandle AH,
ParallelReadyList ready_list,
ParallelState pstate 
)
static

Definition at line 4382 of file pg_backup_archiver.c.

References _parallelReadyList::first_te, has_lock_conflicts(), i, ParallelState::numWorkers, pg_log_debug, ready_list_remove(), ready_list_sort(), ParallelState::te, and _parallelReadyList::tes.

Referenced by restore_toc_entries_parallel().

4384 {
4385  /*
4386  * Sort the ready_list so that we'll tackle larger jobs first.
4387  */
4388  ready_list_sort(ready_list);
4389 
4390  /*
4391  * Search the ready_list until we find a suitable item.
4392  */
4393  for (int i = ready_list->first_te; i <= ready_list->last_te; i++)
4394  {
4395  TocEntry *te = ready_list->tes[i];
4396  bool conflicts = false;
4397 
4398  /*
4399  * Check to see if the item would need exclusive lock on something
4400  * that a currently running item also needs lock on, or vice versa. If
4401  * so, we don't want to schedule them together.
4402  */
4403  for (int k = 0; k < pstate->numWorkers; k++)
4404  {
4405  TocEntry *running_te = pstate->te[k];
4406 
4407  if (running_te == NULL)
4408  continue;
4409  if (has_lock_conflicts(te, running_te) ||
4410  has_lock_conflicts(running_te, te))
4411  {
4412  conflicts = true;
4413  break;
4414  }
4415  }
4416 
4417  if (conflicts)
4418  continue;
4419 
4420  /* passed all tests, so this item can run */
4421  ready_list_remove(ready_list, i);
4422  return te;
4423  }
4424 
4425  pg_log_debug("no item ready");
4426  return NULL;
4427 }
static void ready_list_remove(ParallelReadyList *ready_list, int i)
static void ready_list_sort(ParallelReadyList *ready_list)
#define pg_log_debug(...)
Definition: logging.h:91
TocEntry ** te
Definition: parallel.h:44
int i
static bool has_lock_conflicts(TocEntry *te1, TocEntry *te2)
int numWorkers
Definition: parallel.h:42

◆ PrintTOCSummary()

void PrintTOCSummary ( Archive AHX)

Definition at line 1119 of file pg_backup_archiver.c.

References _tocEntryRequired(), ahprintf(), archCustom, _archiveHandle::archdbname, archDirectory, ARCHIVE_MAJOR, ARCHIVE_MINOR, ARCHIVE_REV, _archiveHandle::archiveDumpVersion, _archiveHandle::archiveRemoteVersion, archTar, _tocEntry::catalogId, _archiveHandle::compression, _archiveHandle::createDate, _tocEntry::dependencies, _tocEntry::desc, _tocEntry::dumpId, _restoreOptions::filename, _archiveHandle::format, free, i, _archiveHandle::intSize, _tocEntry::nDeps, _tocEntry::next, _archiveHandle::offSize, CatalogId::oid, _tocEntry::owner, PGDUMP_STRFTIME_FMT, _archiveHandle::public, REQ_DATA, REQ_SCHEMA, RestoreOutput(), Archive::ropt, sanitize_line(), SaveOutput(), _tocEntry::section, SECTION_NONE, SECTION_PRE_DATA, SetOutput(), _restoreOptions::strict_names, StrictNamesCheck(), CatalogId::tableoid, _tocEntry::tag, _archiveHandle::toc, _archiveHandle::tocCount, _restoreOptions::verbose, and _archiveHandle::version.

Referenced by main().

1120 {
1121  ArchiveHandle *AH = (ArchiveHandle *) AHX;
1122  RestoreOptions *ropt = AH->public.ropt;
1123  TocEntry *te;
1124  teSection curSection;
1125  OutputContext sav;
1126  const char *fmtName;
1127  char stamp_str[64];
1128 
1129  sav = SaveOutput(AH);
1130  if (ropt->filename)
1131  SetOutput(AH, ropt->filename, 0 /* no compression */ );
1132 
1133  if (strftime(stamp_str, sizeof(stamp_str), PGDUMP_STRFTIME_FMT,
1134  localtime(&AH->createDate)) == 0)
1135  strcpy(stamp_str, "[unknown]");
1136 
1137  ahprintf(AH, ";\n; Archive created at %s\n", stamp_str);
1138  ahprintf(AH, "; dbname: %s\n; TOC Entries: %d\n; Compression: %d\n",
1139  sanitize_line(AH->archdbname, false),
1140  AH->tocCount, AH->compression);
1141 
1142  switch (AH->format)
1143  {
1144  case archCustom:
1145  fmtName = "CUSTOM";
1146  break;
1147  case archDirectory:
1148  fmtName = "DIRECTORY";
1149  break;
1150  case archTar:
1151  fmtName = "TAR";
1152  break;
1153  default:
1154  fmtName = "UNKNOWN";
1155  }
1156 
1157  ahprintf(AH, "; Dump Version: %d.%d-%d\n",
1159  ahprintf(AH, "; Format: %s\n", fmtName);
1160  ahprintf(AH, "; Integer: %d bytes\n", (int) AH->intSize);
1161  ahprintf(AH, "; Offset: %d bytes\n", (int) AH->offSize);
1162  if (AH->archiveRemoteVersion)
1163  ahprintf(AH, "; Dumped from database version: %s\n",
1164  AH->archiveRemoteVersion);
1165  if (AH->archiveDumpVersion)
1166  ahprintf(AH, "; Dumped by pg_dump version: %s\n",
1167  AH->archiveDumpVersion);
1168 
1169  ahprintf(AH, ";\n;\n; Selected TOC Entries:\n;\n");
1170 
1171  curSection = SECTION_PRE_DATA;
1172  for (te = AH->toc->next; te != AH->toc; te = te->next)
1173  {
1174  if (te->section != SECTION_NONE)
1175  curSection = te->section;
1176  if (ropt->verbose ||
1177  (_tocEntryRequired(te, curSection, AH) & (REQ_SCHEMA | REQ_DATA)) != 0)
1178  {
1179  char *sanitized_name;
1180  char *sanitized_schema;
1181  char *sanitized_owner;
1182 
1183  /*
1184  */
1185  sanitized_name = sanitize_line(te->tag, false);
1186  sanitized_schema = sanitize_line(te->namespace, true);
1187  sanitized_owner = sanitize_line(te->owner, false);
1188 
1189  ahprintf(AH, "%d; %u %u %s %s %s %s\n", te->dumpId,
1190  te->catalogId.tableoid, te->catalogId.oid,
1191  te->desc, sanitized_schema, sanitized_name,
1192  sanitized_owner);
1193 
1194  free(sanitized_name);
1195  free(sanitized_schema);
1196  free(sanitized_owner);
1197  }
1198  if (ropt->verbose && te->nDeps > 0)
1199  {
1200  int i;
1201 
1202  ahprintf(AH, ";\tdepends on:");
1203  for (i = 0; i < te->nDeps; i++)
1204  ahprintf(AH, " %d", te->dependencies[i]);
1205  ahprintf(AH, "\n");
1206  }
1207  }
1208 
1209  /* Enforce strict names checking */
1210  if (ropt->strict_names)
1211  StrictNamesCheck(ropt);
1212 
1213  if (ropt->filename)
1214  RestoreOutput(AH, sav);
1215 }
struct _tocEntry * next
Oid tableoid
Definition: pg_backup.h:230
RestoreOptions * ropt
Definition: pg_backup.h:183
CatalogId catalogId
static void SetOutput(ArchiveHandle *AH, const char *filename, int compression)
teSection section
const char * filename
Definition: pg_backup.h:83
struct _tocEntry * toc
DumpId * dependencies
#define ARCHIVE_REV(version)
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
#define ARCHIVE_MINOR(version)
ArchiveFormat format
static void StrictNamesCheck(RestoreOptions *ropt)
#define ARCHIVE_MAJOR(version)
static OutputContext SaveOutput(ArchiveHandle *AH)
#define free(a)
Definition: header.h:65
enum _teSection teSection
#define PGDUMP_STRFTIME_FMT
Definition: dumputils.h:33
static void RestoreOutput(ArchiveHandle *AH, OutputContext savedContext)
int i
static char * sanitize_line(const char *str, bool want_hyphen)
static teReqs _tocEntryRequired(TocEntry *te, teSection curSection, ArchiveHandle *AH)

◆ ProcessArchiveRestoreOptions()

void ProcessArchiveRestoreOptions ( Archive AHX)

Definition at line 289 of file pg_backup_archiver.c.

References _tocEntryRequired(), archModeRead, fatal, _archiveHandle::mode, _tocEntry::next, pg_log_warning, _archiveHandle::public, _tocEntry::reqs, Archive::ropt, _tocEntry::section, SECTION_DATA, SECTION_NONE, SECTION_POST_DATA, SECTION_PRE_DATA, _restoreOptions::strict_names, StrictNamesCheck(), and _archiveHandle::toc.

Referenced by main().

290 {
291  ArchiveHandle *AH = (ArchiveHandle *) AHX;
292  RestoreOptions *ropt = AH->public.ropt;
293  TocEntry *te;
294  teSection curSection;
295 
296  /* Decide which TOC entries will be dumped/restored, and mark them */
297  curSection = SECTION_PRE_DATA;
298  for (te = AH->toc->next; te != AH->toc; te = te->next)
299  {
300  /*
301  * When writing an archive, we also take this opportunity to check
302  * that we have generated the entries in a sane order that respects
303  * the section divisions. When reading, don't complain, since buggy
304  * old versions of pg_dump might generate out-of-order archives.
305  */
306  if (AH->mode != archModeRead)
307  {
308  switch (te->section)
309  {
310  case SECTION_NONE:
311  /* ok to be anywhere */
312  break;
313  case SECTION_PRE_DATA:
314  if (curSection != SECTION_PRE_DATA)
315  pg_log_warning("archive items not in correct section order");
316  break;
317  case SECTION_DATA:
318  if (curSection == SECTION_POST_DATA)
319  pg_log_warning("archive items not in correct section order");
320  break;
321  case SECTION_POST_DATA:
322  /* ok no matter which section we were in */
323  break;
324  default:
325  fatal("unexpected section code %d",
326  (int) te->section);
327  break;
328  }
329  }
330 
331  if (te->section != SECTION_NONE)
332  curSection = te->section;
333 
334  te->reqs = _tocEntryRequired(te, curSection, AH);
335  }
336 
337  /* Enforce strict names checking */
338  if (ropt->strict_names)
339  StrictNamesCheck(ropt);
340 }
struct _tocEntry * next
RestoreOptions * ropt
Definition: pg_backup.h:183
teSection section
struct _tocEntry * toc
static void StrictNamesCheck(RestoreOptions *ropt)
enum _teSection teSection
#define fatal(...)
static teReqs _tocEntryRequired(TocEntry *te, teSection curSection, ArchiveHandle *AH)
#define pg_log_warning(...)
Definition: pgfnames.c:24

◆ processEncodingEntry()

static void processEncodingEntry ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 2718 of file pg_backup_archiver.c.

References _tocEntry::defn, encoding, Archive::encoding, fatal, free, pg_char_to_encoding(), pg_strdup(), and _archiveHandle::public.

Referenced by ReadToc().

2719 {
2720  /* te->defn should have the form SET client_encoding = 'foo'; */
2721  char *defn = pg_strdup(te->defn);
2722  char *ptr1;
2723  char *ptr2 = NULL;
2724  int encoding;
2725 
2726  ptr1 = strchr(defn, '\'');
2727  if (ptr1)
2728  ptr2 = strchr(++ptr1, '\'');
2729  if (ptr2)
2730  {
2731  *ptr2 = '\0';
2732  encoding = pg_char_to_encoding(ptr1);
2733  if (encoding < 0)
2734  fatal("unrecognized encoding \"%s\"",
2735  ptr1);
2736  AH->public.encoding = encoding;
2737  }
2738  else
2739  fatal("invalid ENCODING item: %s",
2740  te->defn);
2741 
2742  free(defn);
2743 }
int pg_char_to_encoding(const char *name)
Definition: encnames.c:550
int encoding
Definition: pg_backup.h:197
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
#define free(a)
Definition: header.h:65
#define fatal(...)
int32 encoding
Definition: pg_database.h:41

◆ processSearchPathEntry()

static void processSearchPathEntry ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 2762 of file pg_backup_archiver.c.

References _tocEntry::defn, pg_strdup(), _archiveHandle::public, and Archive::searchpath.

Referenced by ReadToc().

2763 {
2764  /*
2765  * te->defn should contain a command to set search_path. We just copy it
2766  * verbatim for use later.
2767  */
2768  AH->public.searchpath = pg_strdup(te->defn);
2769 }
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
char * searchpath
Definition: pg_backup.h:201

◆ processStdStringsEntry()

static void processStdStringsEntry ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 2746 of file pg_backup_archiver.c.

References _tocEntry::defn, fatal, _archiveHandle::public, and Archive::std_strings.

Referenced by ReadToc().

2747 {
2748  /* te->defn should have the form SET standard_conforming_strings = 'x'; */
2749  char *ptr1;
2750 
2751  ptr1 = strchr(te->defn, '\'');
2752  if (ptr1 && strncmp(ptr1, "'on'", 4) == 0)
2753  AH->public.std_strings = true;
2754  else if (ptr1 && strncmp(ptr1, "'off'", 5) == 0)
2755  AH->public.std_strings = false;
2756  else
2757  fatal("invalid STDSTRINGS item: %s",
2758  te->defn);
2759 }
#define fatal(...)
bool std_strings
Definition: pg_backup.h:198

◆ ReadHead()

void ReadHead ( ArchiveHandle AH)

Definition at line 3768 of file pg_backup_archiver.c.

References _archiveHandle::archdbname, _archiveHandle::archiveDumpVersion, _archiveHandle::archiveRemoteVersion, _archiveHandle::compression, _archiveHandle::createDate, fatal, _archiveHandle::format, _archiveHandle::intSize, K_VERS_1_0, K_VERS_1_10, K_VERS_1_2, K_VERS_1_4, K_VERS_1_7, K_VERS_MAX, MAKE_ARCHIVE_VERSION, _archiveHandle::offSize, pg_log_warning, _archiveHandle::ReadBufPtr, _archiveHandle::ReadBytePtr, _archiveHandle::readHeader, ReadInt(), ReadStr(), tm, _archiveHandle::version, and Z_DEFAULT_COMPRESSION.

Referenced by InitArchiveFmt_Custom(), InitArchiveFmt_Directory(), and InitArchiveFmt_Tar().

3769 {
3770  char tmpMag[7];
3771  int fmt;
3772  struct tm crtm;
3773 
3774  /*
3775  * If we haven't already read the header, do so.
3776  *
3777  * NB: this code must agree with _discoverArchiveFormat(). Maybe find a
3778  * way to unify the cases?
3779  */
3780  if (!AH->readHeader)
3781  {
3782  char vmaj,
3783  vmin,
3784  vrev;
3785 
3786  AH->ReadBufPtr(AH, tmpMag, 5);
3787 
3788  if (strncmp(tmpMag, "PGDMP", 5) != 0)
3789  fatal("did not find magic string in file header");
3790 
3791  vmaj = AH->ReadBytePtr(AH);
3792  vmin = AH->ReadBytePtr(AH);
3793 
3794  if (vmaj > 1 || (vmaj == 1 && vmin > 0)) /* Version > 1.0 */
3795  vrev = AH->ReadBytePtr(AH);
3796  else
3797  vrev = 0;
3798 
3799  AH->version = MAKE_ARCHIVE_VERSION(vmaj, vmin, vrev);
3800 
3801  if (AH->version < K_VERS_1_0 || AH->version > K_VERS_MAX)
3802  fatal("unsupported version (%d.%d) in file header",
3803  vmaj, vmin);
3804 
3805  AH->intSize = AH->ReadBytePtr(AH);
3806  if (AH->intSize > 32)
3807  fatal("sanity check on integer size (%lu) failed",
3808  (unsigned long) AH->intSize);
3809 
3810  if (AH->intSize > sizeof(int))
3811  pg_log_warning("archive was made on a machine with larger integers, some operations might fail");
3812 
3813  if (AH->version >= K_VERS_1_7)
3814  AH->offSize = AH->ReadBytePtr(AH);
3815  else
3816  AH->offSize = AH->intSize;
3817 
3818  fmt = AH->ReadBytePtr(AH);
3819 
3820  if (AH->format != fmt)
3821  fatal("expected format (%d) differs from format found in file (%d)",
3822  AH->format, fmt);
3823  }
3824 
3825  if (AH->version >= K_VERS_1_2)
3826  {
3827  if (AH->version < K_VERS_1_4)
3828  AH->compression = AH->ReadBytePtr(AH);
3829  else
3830  AH->compression = ReadInt(AH);
3831  }
3832  else
3834 
3835 #ifndef HAVE_LIBZ
3836  if (AH->compression != 0)
3837  pg_log_warning("archive is compressed, but this installation does not support compression -- no data will be available");
3838 #endif
3839 
3840  if (AH->version >= K_VERS_1_4)
3841  {
3842  crtm.tm_sec = ReadInt(AH);
3843  crtm.tm_min = ReadInt(AH);
3844  crtm.tm_hour = ReadInt(AH);
3845  crtm.tm_mday = ReadInt(AH);
3846  crtm.tm_mon = ReadInt(AH);
3847  crtm.tm_year = ReadInt(AH);
3848  crtm.tm_isdst = ReadInt(AH);
3849 
3850  AH->archdbname = ReadStr(AH);
3851 
3852  AH->createDate = mktime(&crtm);
3853 
3854  if (AH->createDate == (time_t) -1)
3855  pg_log_warning("invalid creation date in header");
3856  }
3857 
3858  if (AH->version >= K_VERS_1_10)
3859  {
3860  AH->archiveRemoteVersion = ReadStr(AH);
3861  AH->archiveDumpVersion = ReadStr(AH);
3862  }
3863 }
ReadBufPtrType ReadBufPtr
#define Z_DEFAULT_COMPRESSION
#define K_VERS_1_0
int ReadInt(ArchiveHandle *AH)
#define K_VERS_1_4
ReadBytePtrType ReadBytePtr
static struct pg_tm tm
Definition: localtime.c:108
#define K_VERS_1_7
#define MAKE_ARCHIVE_VERSION(major, minor, rev)
#define K_VERS_1_2
#define K_VERS_1_10
ArchiveFormat format
#define K_VERS_MAX
char * ReadStr(ArchiveHandle *AH)
#define fatal(...)
#define pg_log_warning(...)
Definition: pgfnames.c:24

◆ ReadInt()

int ReadInt ( ArchiveHandle AH)

Definition at line 2009 of file pg_backup_archiver.c.

References _archiveHandle::intSize, K_VERS_1_0, _archiveHandle::ReadBytePtr, sign, and _archiveHandle::version.

Referenced by _CustomReadFunc(), _LoadBlobs(), _readBlockHeader(), _ReadExtraToc(), _skipBlobs(), _skipData(), ReadHead(), ReadOffset(), ReadStr(), and ReadToc().

2010 {
2011  int res = 0;
2012  int bv,
2013  b;
2014  int sign = 0; /* Default positive */
2015  int bitShift = 0;
2016 
2017  if (AH->version > K_VERS_1_0)
2018  /* Read a sign byte */
2019  sign = AH->ReadBytePtr(AH);
2020 
2021  for (b = 0; b < AH->intSize; b++)
2022  {
2023  bv = AH->ReadBytePtr(AH) & 0xFF;
2024  if (bv != 0)
2025  res = res + (bv << bitShift);
2026  bitShift += 8;
2027  }
2028 
2029  if (sign)
2030  res = -res;
2031 
2032  return res;
2033 }
#define K_VERS_1_0
ReadBytePtrType ReadBytePtr
char sign
Definition: informix.c:668

◆ ReadOffset()

int ReadOffset ( ArchiveHandle AH,
pgoff_t o 
)

Definition at line 1914 of file pg_backup_archiver.c.

References fatal, i, K_OFFSET_NO_DATA, K_OFFSET_POS_NOT_SET, K_OFFSET_POS_SET, K_VERS_1_7, _archiveHandle::offSize, pgoff_t, _archiveHandle::ReadBytePtr, ReadInt(), and _archiveHandle::version.

Referenced by _ReadExtraToc().

1915 {
1916  int i;
1917  int off;
1918  int offsetFlg;
1919 
1920  /* Initialize to zero */
1921  *o = 0;
1922 
1923  /* Check for old version */
1924  if (AH->version < K_VERS_1_7)
1925  {
1926  /* Prior versions wrote offsets using WriteInt */
1927  i = ReadInt(AH);
1928  /* -1 means not set */
1929  if (i < 0)
1930  return K_OFFSET_POS_NOT_SET;
1931  else if (i == 0)
1932  return K_OFFSET_NO_DATA;
1933 
1934  /* Cast to pgoff_t because it was written as an int. */
1935  *o = (pgoff_t) i;
1936  return K_OFFSET_POS_SET;
1937  }
1938 
1939  /*
1940  * Read the flag indicating the state of the data pointer. Check if valid
1941  * and die if not.
1942  *
1943  * This used to be handled by a negative or zero pointer, now we use an
1944  * extra byte specifically for the state.
1945  */
1946  offsetFlg = AH->ReadBytePtr(AH) & 0xFF;
1947 
1948  switch (offsetFlg)
1949  {
1950  case K_OFFSET_POS_NOT_SET:
1951  case K_OFFSET_NO_DATA:
1952  case K_OFFSET_POS_SET:
1953 
1954  break;
1955 
1956  default:
1957  fatal("unexpected data offset flag %d", offsetFlg);
1958  }
1959 
1960  /*
1961  * Read the bytes
1962  */
1963  for (off = 0; off < AH->offSize; off++)
1964  {
1965  if (off < sizeof(pgoff_t))
1966  *o |= ((pgoff_t) (AH->ReadBytePtr(AH))) << (off * 8);
1967  else
1968  {
1969  if (AH->ReadBytePtr(AH) != 0)
1970  fatal("file offset in dump file is too large");
1971  }
1972  }
1973 
1974  return offsetFlg;
1975 }
int ReadInt(ArchiveHandle *AH)
ReadBytePtrType ReadBytePtr
#define K_VERS_1_7
#define pgoff_t
Definition: win32_port.h:195
#define K_OFFSET_NO_DATA
#define fatal(...)
#define K_OFFSET_POS_SET
int i
#define K_OFFSET_POS_NOT_SET

◆ ReadStr()

char* ReadStr ( ArchiveHandle AH)

Definition at line 2055 of file pg_backup_archiver.c.

References buf, pg_malloc(), _archiveHandle::ReadBufPtr, and ReadInt().

Referenced by _ReadExtraToc(), ReadHead(), and ReadToc().

2056 {
2057  char *buf;
2058  int l;
2059 
2060  l = ReadInt(AH);
2061  if (l < 0)
2062  buf = NULL;
2063  else
2064  {
2065  buf = (char *) pg_malloc(l + 1);
2066  AH->ReadBufPtr(AH, (void *) buf, l);
2067 
2068  buf[l] = '\0';
2069  }
2070 
2071  return buf;
2072 }
ReadBufPtrType ReadBufPtr
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
int ReadInt(ArchiveHandle *AH)
static char * buf
Definition: pg_test_fsync.c:67

◆ ReadToc()

void ReadToc ( ArchiveHandle AH)

Definition at line 2563 of file pg_backup_archiver.c.

References _tocEntry::catalogId, _tocEntry::copyStmt, _tocEntry::dataLength, _tocEntry::defn, _tocEntry::dependencies, _tocEntry::desc, _tocEntry::dropStmt, _tocEntry::dumpId, fatal, free, _tocEntry::hadDumper, i, InvalidOid, K_VERS_1_10, K_VERS_1_11, K_VERS_1_14, K_VERS_1_3, K_VERS_1_5, K_VERS_1_6, K_VERS_1_8, K_VERS_1_9, _archiveHandle::maxDumpId, _tocEntry::nDeps, _tocEntry::next, CatalogId::oid, _tocEntry::owner, pg_log_debug, pg_log_warning, pg_malloc(), pg_malloc0(), pg_realloc(), _tocEntry::prev, processEncodingEntry(), processSearchPathEntry(), processStdStringsEntry(), _archiveHandle::ReadExtraTocPtr, ReadInt(), ReadStr(), _tocEntry::section, SECTION_DATA, SECTION_NONE, SECTION_POST_DATA, SECTION_PRE_DATA, _tocEntry::tableam, CatalogId::tableoid, _tocEntry::tablespace, _tocEntry::tag, _archiveHandle::toc, _archiveHandle::tocCount, and _archiveHandle::version.

Referenced by InitArchiveFmt_Custom(), InitArchiveFmt_Directory(), and InitArchiveFmt_Tar().

2564 {
2565  int i;
2566  char *tmp;
2567  DumpId *deps;
2568  int depIdx;
2569  int depSize;
2570  TocEntry *te;
2571 
2572  AH->tocCount = ReadInt(AH);
2573  AH->maxDumpId = 0;
2574 
2575  for (i = 0; i < AH->tocCount; i++)
2576  {
2577  te = (TocEntry *) pg_malloc0(sizeof(TocEntry));
2578  te->dumpId = ReadInt(AH);
2579 
2580  if (te->dumpId > AH->maxDumpId)
2581  AH->maxDumpId = te->dumpId;
2582 
2583  /* Sanity check */
2584  if (te->dumpId <= 0)
2585  fatal("entry ID %d out of range -- perhaps a corrupt TOC",
2586  te->dumpId);
2587 
2588  te->hadDumper = ReadInt(AH);
2589 
2590  if (AH->version >= K_VERS_1_8)
2591  {
2592  tmp = ReadStr(AH);
2593  sscanf(tmp, "%u", &te->catalogId.tableoid);
2594  free(tmp);
2595  }
2596  else
2598  tmp = ReadStr(AH);
2599  sscanf(tmp, "%u", &te->catalogId.oid);
2600  free(tmp);
2601 
2602  te->tag = ReadStr(AH);
2603  te->desc = ReadStr(AH);
2604 
2605  if (AH->version >= K_VERS_1_11)
2606  {
2607  te->section = ReadInt(AH);
2608  }
2609  else
2610  {
2611  /*
2612  * Rules for pre-8.4 archives wherein pg_dump hasn't classified
2613  * the entries into sections. This list need not cover entry
2614  * types added later than 8.4.
2615  */
2616  if (strcmp(te->desc, "COMMENT") == 0 ||
2617  strcmp(te->desc, "ACL") == 0 ||
2618  strcmp(te->desc, "ACL LANGUAGE") == 0)
2619  te->section = SECTION_NONE;
2620  else if (strcmp(te->desc, "TABLE DATA") == 0 ||
2621  strcmp(te->desc, "BLOBS") == 0 ||
2622  strcmp(te->desc, "BLOB COMMENTS") == 0)
2623  te->section = SECTION_DATA;
2624  else if (strcmp(te->desc, "CONSTRAINT") == 0 ||
2625  strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||
2626  strcmp(te->desc, "FK CONSTRAINT") == 0 ||
2627  strcmp(te->desc, "INDEX") == 0 ||
2628  strcmp(te->desc, "RULE") == 0 ||
2629  strcmp(te->desc, "TRIGGER") == 0)
2630  te->section = SECTION_POST_DATA;
2631  else
2632  te->section = SECTION_PRE_DATA;
2633  }
2634 
2635  te->defn = ReadStr(AH);
2636  te->dropStmt = ReadStr(AH);
2637 
2638  if (AH->version >= K_VERS_1_3)
2639  te->copyStmt = ReadStr(AH);
2640 
2641  if (AH->version >= K_VERS_1_6)
2642  te->namespace = ReadStr(AH);
2643 
2644  if (AH->version >= K_VERS_1_10)
2645  te->tablespace = ReadStr(AH);
2646 
2647  if (AH->version >= K_VERS_1_14)
2648  te->tableam = ReadStr(AH);
2649 
2650  te->owner = ReadStr(AH);
2651  if (AH->version < K_VERS_1_9 || strcmp(ReadStr(AH), "true") == 0)
2652  pg_log_warning("restoring tables WITH OIDS is not supported anymore");
2653 
2654  /* Read TOC entry dependencies */
2655  if (AH->version >= K_VERS_1_5)
2656  {
2657  depSize = 100;
2658  deps = (DumpId *) pg_malloc(sizeof(DumpId) * depSize);
2659  depIdx = 0;
2660  for (;;)
2661  {
2662  tmp = ReadStr(AH);
2663  if (!tmp)
2664  break; /* end of list */
2665  if (depIdx >= depSize)
2666  {
2667  depSize *= 2;
2668  deps = (DumpId *) pg_realloc(deps, sizeof(DumpId) * depSize);
2669  }
2670  sscanf(tmp, "%d", &deps[depIdx]);
2671  free(tmp);
2672  depIdx++;
2673  }
2674 
2675  if (depIdx > 0) /* We have a non-null entry */
2676  {
2677  deps = (DumpId *) pg_realloc(deps, sizeof(DumpId) * depIdx);
2678  te->dependencies = deps;
2679  te->nDeps = depIdx;
2680  }
2681  else
2682  {
2683  free(deps);
2684  te->dependencies = NULL;
2685  te->nDeps = 0;
2686  }
2687  }
2688  else
2689  {
2690  te->dependencies = NULL;
2691  te->nDeps = 0;
2692  }
2693  te->dataLength = 0;
2694 
2695  if (AH->ReadExtraTocPtr)
2696  AH->ReadExtraTocPtr(AH, te);
2697 
2698  pg_log_debug("read TOC entry %d (ID %d) for %s %s",
2699  i, te->dumpId, te->desc, te->tag);
2700 
2701  /* link completed entry into TOC circular list */
2702  te->prev = AH->toc->prev;
2703  AH->toc->prev->next = te;
2704  AH->toc->prev = te;
2705  te->next = AH->toc;
2706 
2707  /* special processing immediately upon read for some items */
2708  if (strcmp(te->desc, "ENCODING") == 0)
2709  processEncodingEntry(AH, te);
2710  else if (strcmp(te->desc, "STDSTRINGS") == 0)
2711  processStdStringsEntry(AH, te);
2712  else if (strcmp(te->desc, "SEARCHPATH") == 0)
2713  processSearchPathEntry(AH, te);
2714  }
2715 }
struct _tocEntry * next
static void processEncodingEntry(ArchiveHandle *AH, TocEntry *te)
int DumpId
Definition: pg_backup.h:234
Oid tableoid
Definition: pg_backup.h:230
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
CatalogId catalogId
#define K_VERS_1_9
int ReadInt(ArchiveHandle *AH)
static void processStdStringsEntry(ArchiveHandle *AH, TocEntry *te)
teSection section
#define K_VERS_1_5
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
#define pg_log_debug(...)
Definition: logging.h:91
struct _tocEntry * toc
DumpId * dependencies
#define K_VERS_1_8
static void processSearchPathEntry(ArchiveHandle *AH, TocEntry *te)
#define K_VERS_1_10
pgoff_t dataLength
void * pg_realloc(void *ptr, size_t size)
Definition: fe_memutils.c:65
#define K_VERS_1_3
struct _tocEntry * prev
#define InvalidOid
Definition: postgres_ext.h:36
#define free(a)
Definition: header.h:65
char * ReadStr(ArchiveHandle *AH)
#define fatal(...)
#define K_VERS_1_14
#define K_VERS_1_6
int i
#define K_VERS_1_11
#define pg_log_warning(...)
Definition: pgfnames.c:24
ReadExtraTocPtrType ReadExtraTocPtr

◆ ready_list_free()

static void ready_list_free ( ParallelReadyList ready_list)
static

Definition at line 4262 of file pg_backup_archiver.c.

References pg_free(), and _parallelReadyList::tes.

Referenced by restore_toc_entries_parallel().

4263 {
4264  pg_free(ready_list->tes);
4265 }
void pg_free(void *ptr)
Definition: fe_memutils.c:105

◆ ready_list_init()

static void ready_list_init ( ParallelReadyList ready_list,
int  tocCount 
)
static

Definition at line 4249 of file pg_backup_archiver.c.

References _parallelReadyList::first_te, _parallelReadyList::last_te, pg_malloc(), _parallelReadyList::sorted, and _parallelReadyList::tes.

Referenced by restore_toc_entries_parallel().

4250 {
4251  ready_list->tes = (TocEntry **)
4252  pg_malloc(tocCount * sizeof(TocEntry *));
4253  ready_list->first_te = 0;
4254  ready_list->last_te = -1;
4255  ready_list->sorted = false;
4256 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47

◆ ready_list_insert()

static void ready_list_insert ( ParallelReadyList ready_list,
TocEntry te 
)
static

Definition at line 4269 of file pg_backup_archiver.c.

References _parallelReadyList::last_te, _parallelReadyList::sorted, and _parallelReadyList::tes.

Referenced by move_to_ready_list(), and reduce_dependencies().

4270 {
4271  ready_list->tes[++ready_list->last_te] = te;
4272  /* List is (probably) not sorted anymore. */
4273  ready_list->sorted = false;
4274 }

◆ ready_list_remove()

static void ready_list_remove ( ParallelReadyList ready_list,
int  i 
)
static

Definition at line 4278 of file pg_backup_archiver.c.

References Assert, _parallelReadyList::first_te, memmove, and _parallelReadyList::tes.

Referenced by pop_next_work_item().

4279 {
4280  int f = ready_list->first_te;
4281 
4282  Assert(i >= f && i <= ready_list->last_te);
4283 
4284  /*
4285  * In the typical case where the item to be removed is the first ready
4286  * entry, we need only increment first_te to remove it. Otherwise, move
4287  * the entries before it to compact the list. (This preserves sortedness,
4288  * if any.) We could alternatively move the entries after i, but there
4289  * are typically many more of those.
4290  */
4291  if (i > f)
4292  {
4293  TocEntry **first_te_ptr = &ready_list->tes[f];
4294 
4295  memmove(first_te_ptr + 1, first_te_ptr, (i - f) * sizeof(TocEntry *));
4296  }
4297  ready_list->first_te++;
4298 }
#define memmove(d, s, c)
Definition: c.h:1265
#define Assert(condition)
Definition: c.h:728
int i

◆ ready_list_sort()

static void ready_list_sort ( ParallelReadyList ready_list)
static

Definition at line 4302 of file pg_backup_archiver.c.

References _parallelReadyList::first_te, _parallelReadyList::last_te, qsort, _parallelReadyList::sorted, _parallelReadyList::tes, and TocEntrySizeCompare().

Referenced by pop_next_work_item().

4303 {
4304  if (!ready_list->sorted)
4305  {
4306  int n = ready_list->last_te - ready_list->first_te + 1;
4307 
4308  if (n > 1)
4309  qsort(ready_list->tes + ready_list->first_te, n,
4310  sizeof(TocEntry *),
4312  ready_list->sorted = true;
4313  }
4314 }
static int TocEntrySizeCompare(const void *p1, const void *p2)
#define qsort(a, b, c, d)
Definition: port.h:491

◆ reduce_dependencies()