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 "common/string.h"
#include "dumputils.h"
#include "fe_utils/string_utils.h"
#include "lib/stringinfo.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)
 
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 int _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 (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 (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)
 
int 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 43 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 44 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 2202 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::public, _archiveHandle::SetupWorkerPtr, _archiveHandle::sqlparse, Archive::std_strings, generate_unaccent_rules::stdout, _archiveHandle::toc, and _archiveHandle::version.

Referenced by CreateArchive(), and OpenArchive().

2205 {
2206  ArchiveHandle *AH;
2207 
2208  pg_log_debug("allocating AH for %s, format %d",
2209  FileSpec ? FileSpec : "(stdio)", fmt);
2210 
2211  AH = (ArchiveHandle *) pg_malloc0(sizeof(ArchiveHandle));
2212 
2213  AH->version = K_VERS_SELF;
2214 
2215  /* initialize for backwards compatible string processing */
2216  AH->public.encoding = 0; /* PG_SQL_ASCII */
2217  AH->public.std_strings = false;
2218 
2219  /* sql error handling */
2220  AH->public.exit_on_error = true;
2221  AH->public.n_errors = 0;
2222 
2223  AH->archiveDumpVersion = PG_VERSION;
2224 
2225  AH->createDate = time(NULL);
2226 
2227  AH->intSize = sizeof(int);
2228  AH->offSize = sizeof(pgoff_t);
2229  if (FileSpec)
2230  {
2231  AH->fSpec = pg_strdup(FileSpec);
2232 
2233  /*
2234  * Not used; maybe later....
2235  *
2236  * AH->workDir = pg_strdup(FileSpec); for(i=strlen(FileSpec) ; i > 0 ;
2237  * i--) if (AH->workDir[i-1] == '/')
2238  */
2239  }
2240  else
2241  AH->fSpec = NULL;
2242 
2243  AH->currUser = NULL; /* unknown */
2244  AH->currSchema = NULL; /* ditto */
2245  AH->currTablespace = NULL; /* ditto */
2246  AH->currTableAm = NULL; /* ditto */
2247 
2248  AH->toc = (TocEntry *) pg_malloc0(sizeof(TocEntry));
2249 
2250  AH->toc->next = AH->toc;
2251  AH->toc->prev = AH->toc;
2252 
2253  AH->mode = mode;
2254  AH->compression = compression;
2255  AH->dosync = dosync;
2256 
2257  memset(&(AH->sqlparse), 0, sizeof(AH->sqlparse));
2258 
2259  /* Open stdout with no compression for AH output handle */
2260  AH->gzOut = 0;
2261  AH->OF = stdout;
2262 
2263  /*
2264  * On Windows, we need to use binary mode to read/write non-text files,
2265  * which include all archive formats as well as compressed plain text.
2266  * Force stdin/stdout into binary mode if that is what we are using.
2267  */
2268 #ifdef WIN32
2269  if ((fmt != archNull || compression != 0) &&
2270  (AH->fSpec == NULL || strcmp(AH->fSpec, "") == 0))
2271  {
2272  if (mode == archModeWrite)
2273  _setmode(fileno(stdout), O_BINARY);
2274  else
2275  _setmode(fileno(stdin), O_BINARY);
2276  }
2277 #endif
2278 
2279  AH->SetupWorkerPtr = setupWorkerPtr;
2280 
2281  if (fmt == archUnknown)
2282  AH->format = _discoverArchiveFormat(AH);
2283  else
2284  AH->format = fmt;
2285 
2286  switch (AH->format)
2287  {
2288  case archCustom:
2290  break;
2291 
2292  case archNull:
2293  InitArchiveFmt_Null(AH);
2294  break;
2295 
2296  case archDirectory:
2298  break;
2299 
2300  case archTar:
2301  InitArchiveFmt_Tar(AH);
2302  break;
2303 
2304  default:
2305  fatal("unrecognized file format \"%d\"", fmt);
2306  }
2307 
2308  return AH;
2309 }
struct _tocEntry * next
static PgChecksumMode mode
Definition: pg_checksums.c:65
#define K_VERS_SELF
static bool dosync
Definition: pg_dump.c:94
void InitArchiveFmt_Tar(ArchiveHandle *AH)
int n_errors
Definition: pg_backup.h:215
int encoding
Definition: pg_backup.h:206
SetupWorkerPtrType SetupWorkerPtr
#define pgoff_t
Definition: win32_port.h:208
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
#define pg_log_debug(...)
Definition: logging.h:92
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:214
bool std_strings
Definition: pg_backup.h:207

◆ _becomeOwner()

static void _becomeOwner ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 3212 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().

3213 {
3214  RestoreOptions *ropt = AH->public.ropt;
3215 
3216  if (ropt && (ropt->noOwner || !ropt->use_setsessauth))
3217  return;
3218 
3219  _becomeUser(AH, te->owner);
3220 }
RestoreOptions * ropt
Definition: pg_backup.h:192
static void _becomeUser(ArchiveHandle *AH, const char *user)
int use_setsessauth
Definition: pg_backup.h:82

◆ _becomeUser()

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

Definition at line 3188 of file pg_backup_archiver.c.

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

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

3189 {
3190  if (!user)
3191  user = ""; /* avoid null pointers */
3192 
3193  if (AH->currUser && strcmp(AH->currUser, user) == 0)
3194  return; /* no need to do anything */
3195 
3196  _doSetSessionAuth(AH, user);
3197 
3198  /*
3199  * NOTE: currUser keeps track of what the imaginary session user in our
3200  * script is
3201  */
3202  if (AH->currUser)
3203  free(AH->currUser);
3204  AH->currUser = pg_strdup(user);
3205 }
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:95

◆ _disableTriggersIfNecessary()

static void _disableTriggersIfNecessary ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 979 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().

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

◆ _discoverArchiveFormat()

static int _discoverArchiveFormat ( ArchiveHandle AH)
static

Definition at line 2061 of file pg_backup_archiver.c.

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

Referenced by _allocAH().

2062 {
2063  FILE *fh;
2064  char sig[6]; /* More than enough */
2065  size_t cnt;
2066  int wantClose = 0;
2067 
2068  pg_log_debug("attempting to ascertain archive format");
2069 
2070  if (AH->lookahead)
2071  free(AH->lookahead);
2072 
2073  AH->readHeader = 0;
2074  AH->lookaheadSize = 512;
2075  AH->lookahead = pg_malloc0(512);
2076  AH->lookaheadLen = 0;
2077  AH->lookaheadPos = 0;
2078 
2079  if (AH->fSpec)
2080  {
2081  struct stat st;
2082 
2083  wantClose = 1;
2084 
2085  /*
2086  * Check if the specified archive is a directory. If so, check if
2087  * there's a "toc.dat" (or "toc.dat.gz") file in it.
2088  */
2089  if (stat(AH->fSpec, &st) == 0 && S_ISDIR(st.st_mode))
2090  {
2091  char buf[MAXPGPATH];
2092 
2093  if (snprintf(buf, MAXPGPATH, "%s/toc.dat", AH->fSpec) >= MAXPGPATH)
2094  fatal("directory name too long: \"%s\"",
2095  AH->fSpec);
2096  if (stat(buf, &st) == 0 && S_ISREG(st.st_mode))
2097  {
2098  AH->format = archDirectory;
2099  return AH->format;
2100  }
2101 
2102 #ifdef HAVE_LIBZ
2103  if (snprintf(buf, MAXPGPATH, "%s/toc.dat.gz", AH->fSpec) >= MAXPGPATH)
2104  fatal("directory name too long: \"%s\"",
2105  AH->fSpec);
2106  if (stat(buf, &st) == 0 && S_ISREG(st.st_mode))
2107  {
2108  AH->format = archDirectory;
2109  return AH->format;
2110  }
2111 #endif
2112  fatal("directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)",
2113  AH->fSpec);
2114  fh = NULL; /* keep compiler quiet */
2115  }
2116  else
2117  {
2118  fh = fopen(AH->fSpec, PG_BINARY_R);
2119  if (!fh)
2120  fatal("could not open input file \"%s\": %m", AH->fSpec);
2121  }
2122  }
2123  else
2124  {
2125  fh = stdin;
2126  if (!fh)
2127  fatal("could not open input file: %m");
2128  }
2129 
2130  if ((cnt = fread(sig, 1, 5, fh)) != 5)
2131  {
2132  if (ferror(fh))
2133  fatal("could not read input file: %m");
2134  else
2135  fatal("input file is too short (read %lu, expected 5)",
2136  (unsigned long) cnt);
2137  }
2138 
2139  /* Save it, just in case we need it later */
2140  memcpy(&AH->lookahead[0], sig, 5);
2141  AH->lookaheadLen = 5;
2142 
2143  if (strncmp(sig, "PGDMP", 5) == 0)
2144  {
2145  /* It's custom format, stop here */
2146  AH->format = archCustom;
2147  AH->readHeader = 1;
2148  }
2149  else
2150  {
2151  /*
2152  * *Maybe* we have a tar archive format file or a text dump ... So,
2153  * read first 512 byte header...
2154  */
2155  cnt = fread(&AH->lookahead[AH->lookaheadLen], 1, 512 - AH->lookaheadLen, fh);
2156  /* read failure is checked below */
2157  AH->lookaheadLen += cnt;
2158 
2159  if (AH->lookaheadLen >= strlen(TEXT_DUMPALL_HEADER) &&
2160  (strncmp(AH->lookahead, TEXT_DUMP_HEADER, strlen(TEXT_DUMP_HEADER)) == 0 ||
2161  strncmp(AH->lookahead, TEXT_DUMPALL_HEADER, strlen(TEXT_DUMPALL_HEADER)) == 0))
2162  {
2163  /*
2164  * looks like it's probably a text format dump. so suggest they
2165  * try psql
2166  */
2167  fatal("input file appears to be a text format dump. Please use psql.");
2168  }
2169 
2170  if (AH->lookaheadLen != 512)
2171  {
2172  if (feof(fh))
2173  fatal("input file does not appear to be a valid archive (too short?)");
2174  else
2175  READ_ERROR_EXIT(fh);
2176  }
2177 
2178  if (!isValidTarHeader(AH->lookahead))
2179  fatal("input file does not appear to be a valid archive");
2180 
2181  AH->format = archTar;
2182  }
2183 
2184  /* Close the file if we opened it */
2185  if (wantClose)
2186  {
2187  if (fclose(fh) != 0)
2188  fatal("could not close input file: %m");
2189  /* Forget lookahead, since we'll re-read header after re-opening */
2190  AH->readHeader = 0;
2191  AH->lookaheadLen = 0;
2192  }
2193 
2194  return AH->format;
2195 }
#define TEXT_DUMP_HEADER
bool isValidTarHeader(char *header)
#define PG_BINARY_R
Definition: c.h:1273
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
#define pg_log_debug(...)
Definition: logging.h:92
#define MAXPGPATH
static char * buf
Definition: pg_test_fsync.c:68
#define S_ISREG(m)
Definition: win32_port.h:327
ArchiveFormat format
#define TEXT_DUMPALL_HEADER
static int sig
Definition: pg_ctl.c:84
#define free(a)
Definition: header.h:65
#define fatal(...)
#define S_ISDIR(m)
Definition: win32_port.h:324
#define READ_ERROR_EXIT(fd)
#define snprintf
Definition: port.h:217
#define stat
Definition: win32_port.h:283

◆ _doSetFixedOutputState()

static void _doSetFixedOutputState ( ArchiveHandle AH)
static

Definition at line 3052 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().

3053 {
3054  RestoreOptions *ropt = AH->public.ropt;
3055 
3056  /*
3057  * Disable timeouts to allow for slow commands, idle parallel workers, etc
3058  */
3059  ahprintf(AH, "SET statement_timeout = 0;\n");
3060  ahprintf(AH, "SET lock_timeout = 0;\n");
3061  ahprintf(AH, "SET idle_in_transaction_session_timeout = 0;\n");
3062 
3063  /* Select the correct character set encoding */
3064  ahprintf(AH, "SET client_encoding = '%s';\n",
3066 
3067  /* Select the correct string literal syntax */
3068  ahprintf(AH, "SET standard_conforming_strings = %s;\n",
3069  AH->public.std_strings ? "on" : "off");
3070 
3071  /* Select the role to be used during restore */
3072  if (ropt && ropt->use_role)
3073  ahprintf(AH, "SET ROLE %s;\n", fmtId(ropt->use_role));
3074 
3075  /* Select the dump-time search_path */
3076  if (AH->public.searchpath)
3077  ahprintf(AH, "%s", AH->public.searchpath);
3078 
3079  /* Make sure function checking is disabled */
3080  ahprintf(AH, "SET check_function_bodies = false;\n");
3081 
3082  /* Ensure that all valid XML data will be accepted */
3083  ahprintf(AH, "SET xmloption = content;\n");
3084 
3085  /* Avoid annoying notices etc */
3086  ahprintf(AH, "SET client_min_messages = warning;\n");
3087  if (!AH->public.std_strings)
3088  ahprintf(AH, "SET escape_string_warning = off;\n");
3089 
3090  /* Adjust row-security state */
3091  if (ropt && ropt->enable_row_security)
3092  ahprintf(AH, "SET row_security = on;\n");
3093  else
3094  ahprintf(AH, "SET row_security = off;\n");
3095 
3096  ahprintf(AH, "\n");
3097 }
RestoreOptions * ropt
Definition: pg_backup.h:192
const char * fmtId(const char *rawid)
Definition: string_utils.c:64
char * use_role
Definition: pg_backup.h:85
int encoding
Definition: pg_backup.h:206
int enable_row_security
Definition: pg_backup.h:134
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
char * searchpath
Definition: pg_backup.h:210
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:588
bool std_strings
Definition: pg_backup.h:207

◆ _doSetSessionAuth()

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

Definition at line 3105 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().

3106 {
3108 
3109  appendPQExpBufferStr(cmd, "SET SESSION AUTHORIZATION ");
3110 
3111  /*
3112  * SQL requires a string literal here. Might as well be correct.
3113  */
3114  if (user && *user)
3115  appendStringLiteralAHX(cmd, user, AH);
3116  else
3117  appendPQExpBufferStr(cmd, "DEFAULT");
3118  appendPQExpBufferChar(cmd, ';');
3119 
3120  if (RestoringToDB(AH))
3121  {
3122  PGresult *res;
3123 
3124  res = PQexec(AH->connection, cmd->data);
3125 
3126  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3127  /* NOT warn_or_exit_horribly... use -O instead to skip this. */
3128  fatal("could not set session user to \"%s\": %s",
3130 
3131  PQclear(res);
3132  }
3133  else
3134  ahprintf(AH, "%s\n\n", cmd->data);
3135 
3136  destroyPQExpBuffer(cmd);
3137 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6744
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3178
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:95
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2193

◆ _enableTriggersIfNecessary()

static void _enableTriggersIfNecessary ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 1005 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().

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

◆ _getObjectDescription()

static void _getObjectDescription ( PQExpBuffer  buf,
TocEntry te 
)
static

Definition at line 3386 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().

3387 {
3388  const char *type = te->desc;
3389 
3390  /* Use ALTER TABLE for views and sequences */
3391  if (strcmp(type, "VIEW") == 0 || strcmp(type, "SEQUENCE") == 0 ||
3392  strcmp(type, "MATERIALIZED VIEW") == 0)
3393  type = "TABLE";
3394 
3395  /* objects that don't require special decoration */
3396  if (strcmp(type, "COLLATION") == 0 ||
3397  strcmp(type, "CONVERSION") == 0 ||
3398  strcmp(type, "DOMAIN") == 0 ||
3399  strcmp(type, "TABLE") == 0 ||
3400  strcmp(type, "TYPE") == 0 ||
3401  strcmp(type, "FOREIGN TABLE") == 0 ||
3402  strcmp(type, "TEXT SEARCH DICTIONARY") == 0 ||
3403  strcmp(type, "TEXT SEARCH CONFIGURATION") == 0 ||
3404  strcmp(type, "STATISTICS") == 0 ||
3405  /* non-schema-specified objects */
3406  strcmp(type, "DATABASE") == 0 ||
3407  strcmp(type, "PROCEDURAL LANGUAGE") == 0 ||
3408  strcmp(type, "SCHEMA") == 0 ||
3409  strcmp(type, "EVENT TRIGGER") == 0 ||
3410  strcmp(type, "FOREIGN DATA WRAPPER") == 0 ||
3411  strcmp(type, "SERVER") == 0 ||
3412  strcmp(type, "PUBLICATION") == 0 ||
3413  strcmp(type, "SUBSCRIPTION") == 0 ||
3414  strcmp(type, "USER MAPPING") == 0)
3415  {
3416  appendPQExpBuffer(buf, "%s ", type);
3417  if (te->namespace && *te->namespace)
3418  appendPQExpBuffer(buf, "%s.", fmtId(te->namespace));
3419  appendPQExpBufferStr(buf, fmtId(te->tag));
3420  return;
3421  }
3422 
3423  /* BLOBs just have a name, but it's numeric so must not use fmtId */
3424  if (strcmp(type, "BLOB") == 0)
3425  {
3426  appendPQExpBuffer(buf, "LARGE OBJECT %s", te->tag);
3427  return;
3428  }
3429 
3430  /*
3431  * These object types require additional decoration. Fortunately, the
3432  * information needed is exactly what's in the DROP command.
3433  */
3434  if (strcmp(type, "AGGREGATE") == 0 ||
3435  strcmp(type, "FUNCTION") == 0 ||
3436  strcmp(type, "OPERATOR") == 0 ||
3437  strcmp(type, "OPERATOR CLASS") == 0 ||
3438  strcmp(type, "OPERATOR FAMILY") == 0 ||
3439  strcmp(type, "PROCEDURE") == 0)
3440  {
3441  /* Chop "DROP " off the front and make a modifiable copy */
3442  char *first = pg_strdup(te->dropStmt + 5);
3443  char *last;
3444 
3445  /* point to last character in string */
3446  last = first + strlen(first) - 1;
3447 
3448  /* Strip off any ';' or '\n' at the end */
3449  while (last >= first && (*last == '\n' || *last == ';'))
3450  last--;
3451  *(last + 1) = '\0';
3452 
3453  appendPQExpBufferStr(buf, first);
3454 
3455  free(first);
3456  return;
3457  }
3458 
3459  pg_log_warning("don't know how to set owner for object type \"%s\"",
3460  type);
3461 }
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 ( TocEntry pos,
TocEntry te 
)
static

Definition at line 1793 of file pg_backup_archiver.c.

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

Referenced by SortTocFromFile().

1794 {
1795  /* Unlink te from list */
1796  te->prev->next = te->next;
1797  te->next->prev = te->prev;
1798 
1799  /* and insert it before "pos" */
1800  te->prev = pos->prev;
1801  te->next = pos;
1802  pos->prev->next = te;
1803  pos->prev = te;
1804 }
struct _tocEntry * next
struct _tocEntry * prev

◆ _printTocEntry()

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

Definition at line 3471 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().

3472 {
3473  RestoreOptions *ropt = AH->public.ropt;
3474 
3475  /* Select owner, schema, tablespace and default AM as necessary */
3476  _becomeOwner(AH, te);
3477  _selectOutputSchema(AH, te->namespace);
3478  _selectTablespace(AH, te->tablespace);
3480 
3481  /* Emit header comment for item */
3482  if (!AH->noTocComments)
3483  {
3484  const char *pfx;
3485  char *sanitized_name;
3486  char *sanitized_schema;
3487  char *sanitized_owner;
3488 
3489  if (isData)
3490  pfx = "Data for ";
3491  else
3492  pfx = "";
3493 
3494  ahprintf(AH, "--\n");
3495  if (AH->public.verbose)
3496  {
3497  ahprintf(AH, "-- TOC entry %d (class %u OID %u)\n",
3498  te->dumpId, te->catalogId.tableoid, te->catalogId.oid);
3499  if (te->nDeps > 0)
3500  {
3501  int i;
3502 
3503  ahprintf(AH, "-- Dependencies:");
3504  for (i = 0; i < te->nDeps; i++)
3505  ahprintf(AH, " %d", te->dependencies[i]);
3506  ahprintf(AH, "\n");
3507  }
3508  }
3509 
3510  sanitized_name = sanitize_line(te->tag, false);
3511  sanitized_schema = sanitize_line(te->namespace, true);
3512  sanitized_owner = sanitize_line(ropt->noOwner ? NULL : te->owner, true);
3513 
3514  ahprintf(AH, "-- %sName: %s; Type: %s; Schema: %s; Owner: %s",
3515  pfx, sanitized_name, te->desc, sanitized_schema,
3516  sanitized_owner);
3517 
3518  free(sanitized_name);
3519  free(sanitized_schema);
3520  free(sanitized_owner);
3521 
3522  if (te->tablespace && strlen(te->tablespace) > 0 && !ropt->noTablespace)
3523  {
3524  char *sanitized_tablespace;
3525 
3526  sanitized_tablespace = sanitize_line(te->tablespace, false);
3527  ahprintf(AH, "; Tablespace: %s", sanitized_tablespace);
3528  free(sanitized_tablespace);
3529  }
3530  ahprintf(AH, "\n");
3531 
3532  if (AH->PrintExtraTocPtr != NULL)
3533  AH->PrintExtraTocPtr(AH, te);
3534  ahprintf(AH, "--\n\n");
3535  }
3536 
3537  /*
3538  * Actually print the definition.
3539  *
3540  * Really crude hack for suppressing AUTHORIZATION clause that old pg_dump
3541  * versions put into CREATE SCHEMA. Don't mutate the variant for schema
3542  * "public" that is a comment. We have to do this when --no-owner mode is
3543  * selected. This is ugly, but I see no other good way ...
3544  */
3545  if (ropt->noOwner &&
3546  strcmp(te->desc, "SCHEMA") == 0 && strncmp(te->defn, "--", 2) != 0)
3547  {
3548  ahprintf(AH, "CREATE SCHEMA %s;\n\n\n", fmtId(te->tag));
3549  }
3550  else
3551  {
3552  if (te->defn && strlen(te->defn) > 0)
3553  ahprintf(AH, "%s\n\n", te->defn);
3554  }
3555 
3556  /*
3557  * If we aren't using SET SESSION AUTH to determine ownership, we must
3558  * instead issue an ALTER OWNER command. Schema "public" is special; when
3559  * a dump emits a comment in lieu of creating it, we use ALTER OWNER even
3560  * when using SET SESSION for all other objects. We assume that anything
3561  * without a DROP command is not a separately ownable object. All the
3562  * categories with DROP commands must appear in one list or the other.
3563  */
3564  if (!ropt->noOwner &&
3565  (!ropt->use_setsessauth ||
3566  (strcmp(te->desc, "SCHEMA") == 0 &&
3567  strncmp(te->defn, "--", 2) == 0)) &&
3568  te->owner && strlen(te->owner) > 0 &&
3569  te->dropStmt && strlen(te->dropStmt) > 0)
3570  {
3571  if (strcmp(te->desc, "AGGREGATE") == 0 ||
3572  strcmp(te->desc, "BLOB") == 0 ||
3573  strcmp(te->desc, "COLLATION") == 0 ||
3574  strcmp(te->desc, "CONVERSION") == 0 ||
3575  strcmp(te->desc, "DATABASE") == 0 ||
3576  strcmp(te->desc, "DOMAIN") == 0 ||
3577  strcmp(te->desc, "FUNCTION") == 0 ||
3578  strcmp(te->desc, "OPERATOR") == 0 ||
3579  strcmp(te->desc, "OPERATOR CLASS") == 0 ||
3580  strcmp(te->desc, "OPERATOR FAMILY") == 0 ||
3581  strcmp(te->desc, "PROCEDURE") == 0 ||
3582  strcmp(te->desc, "PROCEDURAL LANGUAGE") == 0 ||
3583  strcmp(te->desc, "SCHEMA") == 0 ||
3584  strcmp(te->desc, "EVENT TRIGGER") == 0 ||
3585  strcmp(te->desc, "TABLE") == 0 ||
3586  strcmp(te->desc, "TYPE") == 0 ||
3587  strcmp(te->desc, "VIEW") == 0 ||
3588  strcmp(te->desc, "MATERIALIZED VIEW") == 0 ||
3589  strcmp(te->desc, "SEQUENCE") == 0 ||
3590  strcmp(te->desc, "FOREIGN TABLE") == 0 ||
3591  strcmp(te->desc, "TEXT SEARCH DICTIONARY") == 0 ||
3592  strcmp(te->desc, "TEXT SEARCH CONFIGURATION") == 0 ||
3593  strcmp(te->desc, "FOREIGN DATA WRAPPER") == 0 ||
3594  strcmp(te->desc, "SERVER") == 0 ||
3595  strcmp(te->desc, "STATISTICS") == 0 ||
3596  strcmp(te->desc, "PUBLICATION") == 0 ||
3597  strcmp(te->desc, "SUBSCRIPTION") == 0)
3598  {
3599  PQExpBuffer temp = createPQExpBuffer();
3600 
3601  appendPQExpBufferStr(temp, "ALTER ");
3602  _getObjectDescription(temp, te);
3603  appendPQExpBuffer(temp, " OWNER TO %s;", fmtId(te->owner));
3604  ahprintf(AH, "%s\n\n", temp->data);
3605  destroyPQExpBuffer(temp);
3606  }
3607  else if (strcmp(te->desc, "CAST") == 0 ||
3608  strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||
3609  strcmp(te->desc, "CONSTRAINT") == 0 ||
3610  strcmp(te->desc, "DATABASE PROPERTIES") == 0 ||
3611  strcmp(te->desc, "DEFAULT") == 0 ||
3612  strcmp(te->desc, "FK CONSTRAINT") == 0 ||
3613  strcmp(te->desc, "INDEX") == 0 ||
3614  strcmp(te->desc, "RULE") == 0 ||
3615  strcmp(te->desc, "TRIGGER") == 0 ||
3616  strcmp(te->desc, "ROW SECURITY") == 0 ||
3617  strcmp(te->desc, "POLICY") == 0 ||
3618  strcmp(te->desc, "USER MAPPING") == 0)
3619  {
3620  /* these object types don't have separate owners */
3621  }
3622  else
3623  {
3624  pg_log_warning("don't know how to set owner for object type \"%s\"",
3625  te->desc);
3626  }
3627  }
3628 
3629  /*
3630  * If it's an ACL entry, it might contain SET SESSION AUTHORIZATION
3631  * commands, so we can no longer assume we know the current auth setting.
3632  */
3633  if (_tocEntryIsACL(te))
3634  {
3635  if (AH->currUser)
3636  free(AH->currUser);
3637  AH->currUser = NULL;
3638  }
3639 }
Oid tableoid
Definition: pg_backup.h:240
static void _getObjectDescription(PQExpBuffer buf, TocEntry *te)
RestoreOptions * ropt
Definition: pg_backup.h:192
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:82
int verbose
Definition: pg_backup.h:194
#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
#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 3148 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().

3149 {
3150  if (RestoringToDB(AH))
3152  else
3153  {
3154  PQExpBufferData connectbuf;
3155 
3156  initPQExpBuffer(&connectbuf);
3157  appendPsqlMetaConnect(&connectbuf, dbname);
3158  ahprintf(AH, "%s\n", connectbuf.data);
3159  termPQExpBuffer(&connectbuf);
3160  }
3161 
3162  /*
3163  * NOTE: currUser keeps track of what the imaginary session user in our
3164  * script is. It's now effectively reset to the original userID.
3165  */
3166  if (AH->currUser)
3167  free(AH->currUser);
3168  AH->currUser = NULL;
3169 
3170  /* don't assume we still know the output schema, tablespace, etc either */
3171  if (AH->currSchema)
3172  free(AH->currSchema);
3173  AH->currSchema = NULL;
3174  if (AH->currTablespace)
3175  free(AH->currTablespace);
3176  AH->currTablespace = NULL;
3177 
3178  /* re-establish fixed state */
3180 }
static int RestoringToDB(ArchiveHandle *AH)
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
void appendPsqlMetaConnect(PQExpBuffer buf, const char *dbname)
Definition: string_utils.c:590
void ReconnectToServer(ArchiveHandle *AH, const char *dbname)
Definition: pg_backup_db.c:78
static void _doSetFixedOutputState(ArchiveHandle *AH)
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
#define free(a)
Definition: header.h:65
char * dbname
Definition: streamutil.c:51
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92

◆ _selectOutputSchema()

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

Definition at line 3228 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().

3229 {
3230  PQExpBuffer qry;
3231 
3232  /*
3233  * If there was a SEARCHPATH TOC entry, we're supposed to just stay with
3234  * that search_path rather than switching to entry-specific paths.
3235  * Otherwise, it's an old archive that will not restore correctly unless
3236  * we set the search_path as it's expecting.
3237  */
3238  if (AH->public.searchpath)
3239  return;
3240 
3241  if (!schemaName || *schemaName == '\0' ||
3242  (AH->currSchema && strcmp(AH->currSchema, schemaName) == 0))
3243  return; /* no need to do anything */
3244 
3245  qry = createPQExpBuffer();
3246 
3247  appendPQExpBuffer(qry, "SET search_path = %s",
3248  fmtId(schemaName));
3249  if (strcmp(schemaName, "pg_catalog") != 0)
3250  appendPQExpBufferStr(qry, ", pg_catalog");
3251 
3252  if (RestoringToDB(AH))
3253  {
3254  PGresult *res;
3255 
3256  res = PQexec(AH->connection, qry->data);
3257 
3258  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3260  "could not set search_path to \"%s\": %s",
3261  schemaName, PQerrorMessage(AH->connection));
3262 
3263  PQclear(res);
3264  }
3265  else
3266  ahprintf(AH, "%s;\n\n", qry->data);
3267 
3268  if (AH->currSchema)
3269  free(AH->currSchema);
3270  AH->currSchema = pg_strdup(schemaName);
3271 
3272  destroyPQExpBuffer(qry);
3273 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6744
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:3178
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:210
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:2193

◆ _selectTableAccessMethod()

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

Definition at line 3341 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().

3342 {
3343  PQExpBuffer cmd;
3344  const char *want,
3345  *have;
3346 
3347  have = AH->currTableAm;
3348  want = tableam;
3349 
3350  if (!want)
3351  return;
3352 
3353  if (have && strcmp(want, have) == 0)
3354  return;
3355 
3356  cmd = createPQExpBuffer();
3357  appendPQExpBuffer(cmd, "SET default_table_access_method = %s;", fmtId(want));
3358 
3359  if (RestoringToDB(AH))
3360  {
3361  PGresult *res;
3362 
3363  res = PQexec(AH->connection, cmd->data);
3364 
3365  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3367  "could not set default_table_access_method: %s",
3368  PQerrorMessage(AH->connection));
3369 
3370  PQclear(res);
3371  }
3372  else
3373  ahprintf(AH, "%s\n\n", cmd->data);
3374 
3375  destroyPQExpBuffer(cmd);
3376 
3377  AH->currTableAm = pg_strdup(want);
3378 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6744
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:3178
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:2193

◆ _selectTablespace()

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

Definition at line 3280 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().

3281 {
3282  RestoreOptions *ropt = AH->public.ropt;
3283  PQExpBuffer qry;
3284  const char *want,
3285  *have;
3286 
3287  /* do nothing in --no-tablespaces mode */
3288  if (ropt->noTablespace)
3289  return;
3290 
3291  have = AH->currTablespace;
3292  want = tablespace;
3293 
3294  /* no need to do anything for non-tablespace object */
3295  if (!want)
3296  return;
3297 
3298  if (have && strcmp(want, have) == 0)
3299  return; /* no need to do anything */
3300 
3301  qry = createPQExpBuffer();
3302 
3303  if (strcmp(want, "") == 0)
3304  {
3305  /* We want the tablespace to be the database's default */
3306  appendPQExpBufferStr(qry, "SET default_tablespace = ''");
3307  }
3308  else
3309  {
3310  /* We want an explicit tablespace */
3311  appendPQExpBuffer(qry, "SET default_tablespace = %s", fmtId(want));
3312  }
3313 
3314  if (RestoringToDB(AH))
3315  {
3316  PGresult *res;
3317 
3318  res = PQexec(AH->connection, qry->data);
3319 
3320  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3322  "could not set default_tablespace to %s: %s",
3323  fmtId(want), PQerrorMessage(AH->connection));
3324 
3325  PQclear(res);
3326  }
3327  else
3328  ahprintf(AH, "%s;\n\n", qry->data);
3329 
3330  if (AH->currTablespace)
3331  free(AH->currTablespace);
3332  AH->currTablespace = pg_strdup(want);
3333 
3334  destroyPQExpBuffer(qry);
3335 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6744
RestoreOptions * ropt
Definition: pg_backup.h:192
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:3178
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:116
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
char * tablespace
Definition: pgbench.c:226
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:2193

◆ _tocEntryIsACL()

static bool _tocEntryIsACL ( TocEntry te)
static

Definition at line 3037 of file pg_backup_archiver.c.

References _tocEntry::desc.

Referenced by _printTocEntry(), and _tocEntryRequired().

3038 {
3039  /* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
3040  if (strcmp(te->desc, "ACL") == 0 ||
3041  strcmp(te->desc, "ACL LANGUAGE") == 0 ||
3042  strcmp(te->desc, "DEFAULT ACL") == 0)
3043  return true;
3044  return false;
3045 }

◆ _tocEntryRequired()

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

Definition at line 2748 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().

2749 {
2750  int res = REQ_SCHEMA | REQ_DATA;
2751  RestoreOptions *ropt = AH->public.ropt;
2752 
2753  /* These items are treated specially */
2754  if (strcmp(te->desc, "ENCODING") == 0 ||
2755  strcmp(te->desc, "STDSTRINGS") == 0 ||
2756  strcmp(te->desc, "SEARCHPATH") == 0)
2757  return REQ_SPECIAL;
2758 
2759  /*
2760  * DATABASE and DATABASE PROPERTIES also have a special rule: they are
2761  * restored in createDB mode, and not restored otherwise, independently of
2762  * all else.
2763  */
2764  if (strcmp(te->desc, "DATABASE") == 0 ||
2765  strcmp(te->desc, "DATABASE PROPERTIES") == 0)
2766  {
2767  if (ropt->createDB)
2768  return REQ_SCHEMA;
2769  else
2770  return 0;
2771  }
2772 
2773  /*
2774  * Process exclusions that affect certain classes of TOC entries.
2775  */
2776 
2777  /* If it's an ACL, maybe ignore it */
2778  if (ropt->aclsSkip && _tocEntryIsACL(te))
2779  return 0;
2780 
2781  /* If it's a comment, maybe ignore it */
2782  if (ropt->no_comments && strcmp(te->desc, "COMMENT") == 0)
2783  return 0;
2784 
2785  /*
2786  * If it's a publication or a table part of a publication, maybe ignore
2787  * it.
2788  */
2789  if (ropt->no_publications &&
2790  (strcmp(te->desc, "PUBLICATION") == 0 ||
2791  strcmp(te->desc, "PUBLICATION TABLE") == 0))
2792  return 0;
2793 
2794  /* If it's a security label, maybe ignore it */
2795  if (ropt->no_security_labels && strcmp(te->desc, "SECURITY LABEL") == 0)
2796  return 0;
2797 
2798  /* If it's a subscription, maybe ignore it */
2799  if (ropt->no_subscriptions && strcmp(te->desc, "SUBSCRIPTION") == 0)
2800  return 0;
2801 
2802  /* Ignore it if section is not to be dumped/restored */
2803  switch (curSection)
2804  {
2805  case SECTION_PRE_DATA:
2806  if (!(ropt->dumpSections & DUMP_PRE_DATA))
2807  return 0;
2808  break;
2809  case SECTION_DATA:
2810  if (!(ropt->dumpSections & DUMP_DATA))
2811  return 0;
2812  break;
2813  case SECTION_POST_DATA:
2814  if (!(ropt->dumpSections & DUMP_POST_DATA))
2815  return 0;
2816  break;
2817  default:
2818  /* shouldn't get here, really, but ignore it */
2819  return 0;
2820  }
2821 
2822  /* Ignore it if rejected by idWanted[] (cf. SortTocFromFile) */
2823  if (ropt->idWanted && !ropt->idWanted[te->dumpId - 1])
2824  return 0;
2825 
2826  /*
2827  * Check options for selective dump/restore.
2828  */
2829  if (strcmp(te->desc, "ACL") == 0 ||
2830  strcmp(te->desc, "COMMENT") == 0 ||
2831  strcmp(te->desc, "SECURITY LABEL") == 0)
2832  {
2833  /* Database properties react to createDB, not selectivity options. */
2834  if (strncmp(te->tag, "DATABASE ", 9) == 0)
2835  {
2836  if (!ropt->createDB)
2837  return 0;
2838  }
2839  else if (ropt->schemaNames.head != NULL ||
2840  ropt->schemaExcludeNames.head != NULL ||
2841  ropt->selTypes)
2842  {
2843  /*
2844  * In a selective dump/restore, we want to restore these dependent
2845  * TOC entry types only if their parent object is being restored.
2846  * Without selectivity options, we let through everything in the
2847  * archive. Note there may be such entries with no parent, eg
2848  * non-default ACLs for built-in objects.
2849  *
2850  * This code depends on the parent having been marked already,
2851  * which should be the case; if it isn't, perhaps due to
2852  * SortTocFromFile rearrangement, skipping the dependent entry
2853  * seems prudent anyway.
2854  *
2855  * Ideally we'd handle, eg, table CHECK constraints this way too.
2856  * But it's hard to tell which of their dependencies is the one to
2857  * consult.
2858  */
2859  if (te->nDeps != 1 ||
2860  TocIDRequired(AH, te->dependencies[0]) == 0)
2861  return 0;
2862  }
2863  }
2864  else
2865  {
2866  /* Apply selective-restore rules for standalone TOC entries. */
2867  if (ropt->schemaNames.head != NULL)
2868  {
2869  /* If no namespace is specified, it means all. */
2870  if (!te->namespace)
2871  return 0;
2872  if (!simple_string_list_member(&ropt->schemaNames, te->namespace))
2873  return 0;
2874  }
2875 
2876  if (ropt->schemaExcludeNames.head != NULL &&
2877  te->namespace &&
2878  simple_string_list_member(&ropt->schemaExcludeNames, te->namespace))
2879  return 0;
2880 
2881  if (ropt->selTypes)
2882  {
2883  if (strcmp(te->desc, "TABLE") == 0 ||
2884  strcmp(te->desc, "TABLE DATA") == 0 ||
2885  strcmp(te->desc, "VIEW") == 0 ||
2886  strcmp(te->desc, "FOREIGN TABLE") == 0 ||
2887  strcmp(te->desc, "MATERIALIZED VIEW") == 0 ||
2888  strcmp(te->desc, "MATERIALIZED VIEW DATA") == 0 ||
2889  strcmp(te->desc, "SEQUENCE") == 0 ||
2890  strcmp(te->desc, "SEQUENCE SET") == 0)
2891  {
2892  if (!ropt->selTable)
2893  return 0;
2894  if (ropt->tableNames.head != NULL &&
2896  return 0;
2897  }
2898  else if (strcmp(te->desc, "INDEX") == 0)
2899  {
2900  if (!ropt->selIndex)
2901  return 0;
2902  if (ropt->indexNames.head != NULL &&
2904  return 0;
2905  }
2906  else if (strcmp(te->desc, "FUNCTION") == 0 ||
2907  strcmp(te->desc, "AGGREGATE") == 0 ||
2908  strcmp(te->desc, "PROCEDURE") == 0)
2909  {
2910  if (!ropt->selFunction)
2911  return 0;
2912  if (ropt->functionNames.head != NULL &&
2914  return 0;
2915  }
2916  else if (strcmp(te->desc, "TRIGGER") == 0)
2917  {
2918  if (!ropt->selTrigger)
2919  return 0;
2920  if (ropt->triggerNames.head != NULL &&
2922  return 0;
2923  }
2924  else
2925  return 0;
2926  }
2927  }
2928 
2929  /*
2930  * Determine whether the TOC entry contains schema and/or data components,
2931  * and mask off inapplicable REQ bits. If it had a dataDumper, assume
2932  * it's both schema and data. Otherwise it's probably schema-only, but
2933  * there are exceptions.
2934  */
2935  if (!te->hadDumper)
2936  {
2937  /*
2938  * Special Case: If 'SEQUENCE SET' or anything to do with BLOBs, then
2939  * it is considered a data entry. We don't need to check for the
2940  * BLOBS entry or old-style BLOB COMMENTS, because they will have
2941  * hadDumper = true ... but we do need to check new-style BLOB ACLs,
2942  * comments, etc.
2943  */
2944  if (strcmp(te->desc, "SEQUENCE SET") == 0 ||
2945  strcmp(te->desc, "BLOB") == 0 ||
2946  (strcmp(te->desc, "ACL") == 0 &&
2947  strncmp(te->tag, "LARGE OBJECT ", 13) == 0) ||
2948  (strcmp(te->desc, "COMMENT") == 0 &&
2949  strncmp(te->tag, "LARGE OBJECT ", 13) == 0) ||
2950  (strcmp(te->desc, "SECURITY LABEL") == 0 &&
2951  strncmp(te->tag, "LARGE OBJECT ", 13) == 0))
2952  res = res & REQ_DATA;
2953  else
2954  res = res & ~REQ_DATA;
2955  }
2956 
2957  /* If there's no definition command, there's no schema component */
2958  if (!te->defn || !te->defn[0])
2959  res = res & ~REQ_SCHEMA;
2960 
2961  /*
2962  * Special case: <Init> type with <Max OID> tag; this is obsolete and we
2963  * always ignore it.
2964  */
2965  if ((strcmp(te->desc, "<Init>") == 0) && (strcmp(te->tag, "Max OID") == 0))
2966  return 0;
2967 
2968  /* Mask it if we only want schema */
2969  if (ropt->schemaOnly)
2970  {
2971  /*
2972  * The sequence_data option overrides schemaOnly for SEQUENCE SET.
2973  *
2974  * In binary-upgrade mode, even with schemaOnly set, we do not mask
2975  * out large objects. (Only large object definitions, comments and
2976  * other metadata should be generated in binary-upgrade mode, not the
2977  * actual data, but that need not concern us here.)
2978  */
2979  if (!(ropt->sequence_data && strcmp(te->desc, "SEQUENCE SET") == 0) &&
2980  !(ropt->binary_upgrade &&
2981  (strcmp(te->desc, "BLOB") == 0 ||
2982  (strcmp(te->desc, "ACL") == 0 &&
2983  strncmp(te->tag, "LARGE OBJECT ", 13) == 0) ||
2984  (strcmp(te->desc, "COMMENT") == 0 &&
2985  strncmp(te->tag, "LARGE OBJECT ", 13) == 0) ||
2986  (strcmp(te->desc, "SECURITY LABEL") == 0 &&
2987  strncmp(te->tag, "LARGE OBJECT ", 13) == 0))))
2988  res = res & REQ_SCHEMA;
2989  }
2990 
2991  /* Mask it if we only want data */
2992  if (ropt->dataOnly)
2993  res = res & REQ_DATA;
2994 
2995  return res;
2996 }
#define REQ_SCHEMA
#define REQ_DATA
bool simple_string_list_member(SimpleStringList *list, const char *val)
Definition: simple_list.c:87
SimpleStringList triggerNames
Definition: pg_backup.h:120
RestoreOptions * ropt
Definition: pg_backup.h:192
SimpleStringList schemaNames
Definition: pg_backup.h:118
static bool _tocEntryIsACL(TocEntry *te)
#define REQ_SPECIAL
bool * idWanted
Definition: pg_backup.h:133
SimpleStringList tableNames
Definition: pg_backup.h:121
DumpId * dependencies
SimpleStringList functionNames
Definition: pg_backup.h:117
#define DUMP_POST_DATA
int no_security_labels
Definition: pg_backup.h:93
int no_subscriptions
Definition: pg_backup.h:94
#define DUMP_DATA
SimpleStringListCell * head
Definition: simple_list.h:42
SimpleStringList indexNames
Definition: pg_backup.h:116
int no_publications
Definition: pg_backup.h:92
SimpleStringList schemaExcludeNames
Definition: pg_backup.h:119
int TocIDRequired(ArchiveHandle *AH, DumpId id)
#define DUMP_PRE_DATA

◆ _tocEntryRestorePass()

static RestorePass _tocEntryRestorePass ( TocEntry te)
static

Definition at line 3004 of file pg_backup_archiver.c.

References _tocEntry::desc, RESTORE_PASS_ACL, RESTORE_PASS_MAIN, and _tocEntry::tag.

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

3005 {
3006  /* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
3007  if (strcmp(te->desc, "ACL") == 0 ||
3008  strcmp(te->desc, "ACL LANGUAGE") == 0 ||
3009  strcmp(te->desc, "DEFAULT ACL") == 0)
3010  return RESTORE_PASS_ACL;
3011  if (strcmp(te->desc, "EVENT TRIGGER") == 0 ||
3012  strcmp(te->desc, "MATERIALIZED VIEW DATA") == 0)
3013  return RESTORE_PASS_POST_ACL;
3014 
3015  /*
3016  * Comments need to be emitted in the same pass as their parent objects.
3017  * ACLs haven't got comments, and neither do matview data objects, but
3018  * event triggers do. (Fortunately, event triggers haven't got ACLs, or
3019  * we'd need yet another weird special case.)
3020  */
3021  if (strcmp(te->desc, "COMMENT") == 0 &&
3022  strncmp(te->tag, "EVENT TRIGGER ", 14) == 0)
3023  return RESTORE_PASS_POST_ACL;
3024 
3025  /* All else can be handled in the main pass. */
3026  return RESTORE_PASS_MAIN;
3027 }

◆ ahprintf()

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

Definition at line 1588 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().

1589 {
1590  int save_errno = errno;
1591  char *p;
1592  size_t len = 128; /* initial assumption about buffer size */
1593  size_t cnt;
1594 
1595  for (;;)
1596  {
1597  va_list args;
1598 
1599  /* Allocate work buffer. */
1600  p = (char *) pg_malloc(len);
1601 
1602  /* Try to format the data. */
1603  errno = save_errno;
1604  va_start(args, fmt);
1605  cnt = pvsnprintf(p, len, fmt, args);
1606  va_end(args);
1607 
1608  if (cnt < len)
1609  break; /* success */
1610 
1611  /* Release buffer and loop around to try again with larger len. */
1612  free(p);
1613  len = cnt;
1614  }
1615 
1616  ahwrite(p, 1, cnt, AH);
1617  free(p);
1618  return (int) cnt;
1619 }
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 1679 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().

1680 {
1681  int bytes_written = 0;
1682 
1683  if (AH->writingBlob)
1684  {
1685  size_t remaining = size * nmemb;
1686 
1687  while (AH->lo_buf_used + remaining > AH->lo_buf_size)
1688  {
1689  size_t avail = AH->lo_buf_size - AH->lo_buf_used;
1690 
1691  memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, avail);
1692  ptr = (const void *) ((const char *) ptr + avail);
1693  remaining -= avail;
1694  AH->lo_buf_used += avail;
1695  dump_lo_buf(AH);
1696  }
1697 
1698  memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, remaining);
1699  AH->lo_buf_used += remaining;
1700 
1701  bytes_written = size * nmemb;
1702  }
1703  else if (AH->gzOut)
1704  bytes_written = GZWRITE(ptr, size, nmemb, AH->OF);
1705  else if (AH->CustomOutPtr)
1706  bytes_written = AH->CustomOutPtr(AH, ptr, size * nmemb);
1707 
1708  else
1709  {
1710  /*
1711  * If we're doing a restore, and it's direct to DB, and we're
1712  * connected then send it to the DB.
1713  */
1714  if (RestoringToDB(AH))
1715  bytes_written = ExecuteSqlCommandBuf(&AH->public, (const char *) ptr, size * nmemb);
1716  else
1717  bytes_written = fwrite(ptr, size, nmemb, AH->OF) * size;
1718  }
1719 
1720  if (bytes_written != size * nmemb)
1722 }
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:449
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 1057 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(), dumpCommentExtended(), 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(), dumpTableAttach(), dumpTableComment(), dumpTableData(), dumpTableSchema(), dumpTableSecLabel(), dumpTransform(), dumpTrigger(), dumpTSConfig(), dumpTSDictionary(), dumpTSParser(), dumpTSTemplate(), dumpUndefinedType(), dumpUserMappings(), and refreshMatViewData().

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

◆ archprintf()

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

Definition at line 1451 of file pg_backup_archiver.c.

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

1452 {
1453  int save_errno = errno;
1454  char *p;
1455  size_t len = 128; /* initial assumption about buffer size */
1456  size_t cnt;
1457 
1458  for (;;)
1459  {
1460  va_list args;
1461 
1462  /* Allocate work buffer. */
1463  p = (char *) pg_malloc(len);
1464 
1465  /* Try to format the data. */
1466  errno = save_errno;
1467  va_start(args, fmt);
1468  cnt = pvsnprintf(p, len, fmt, args);
1469  va_end(args);
1470 
1471  if (cnt < len)
1472  break; /* success */
1473 
1474  /* Release buffer and loop around to try again with larger len. */
1475  free(p);
1476  len = cnt;
1477  }
1478 
1479  WriteData(AH, p, cnt);
1480  free(p);
1481  return (int) cnt;
1482 }
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 1444 of file pg_backup_archiver.c.

References WriteData().

Referenced by dumpTableData_insert().

1445 {
1446  WriteData(AH, s, strlen(s));
1447 }
void WriteData(Archive *AHX, const void *data, size_t dLen)

◆ buildTocEntryArrays()

static void buildTocEntryArrays ( ArchiveHandle AH)
static

Definition at line 1818 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().

1819 {
1820  DumpId maxDumpId = AH->maxDumpId;
1821  TocEntry *te;
1822 
1823  AH->tocsByDumpId = (TocEntry **) pg_malloc0((maxDumpId + 1) * sizeof(TocEntry *));
1824  AH->tableDataId = (DumpId *) pg_malloc0((maxDumpId + 1) * sizeof(DumpId));
1825 
1826  for (te = AH->toc->next; te != AH->toc; te = te->next)
1827  {
1828  /* this check is purely paranoia, maxDumpId should be correct */
1829  if (te->dumpId <= 0 || te->dumpId > maxDumpId)
1830  fatal("bad dumpId");
1831 
1832  /* tocsByDumpId indexes all TOCs by their dump ID */
1833  AH->tocsByDumpId[te->dumpId] = te;
1834 
1835  /*
1836  * tableDataId provides the TABLE DATA item's dump ID for each TABLE
1837  * TOC entry that has a DATA item. We compute this by reversing the
1838  * TABLE DATA item's dependency, knowing that a TABLE DATA item has
1839  * just one dependency and it is the TABLE item.
1840  */
1841  if (strcmp(te->desc, "TABLE DATA") == 0 && te->nDeps > 0)
1842  {
1843  DumpId tableId = te->dependencies[0];
1844 
1845  /*
1846  * The TABLE item might not have been in the archive, if this was
1847  * a data-only dump; but its dump ID should be less than its data
1848  * item's dump ID, so there should be a place for it in the array.
1849  */
1850  if (tableId <= 0 || tableId > maxDumpId)
1851  fatal("bad table dumpId for TABLE DATA item");
1852 
1853  AH->tableDataId[tableId] = te->dumpId;
1854  }
1855  }
1856 }
struct _tocEntry * next
int DumpId
Definition: pg_backup.h:244
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 3831 of file pg_backup_archiver.c.

References fseeko, ftello, and pgoff_t.

Referenced by InitArchiveFmt_Custom(), and InitArchiveFmt_Tar().

3832 {
3833  pgoff_t tpos;
3834 
3835  /* Check that ftello works on this file */
3836  tpos = ftello(fp);
3837  if (tpos < 0)
3838  return false;
3839 
3840  /*
3841  * Check that fseeko(SEEK_SET) works, too. NB: we used to try to test
3842  * this with fseeko(fp, 0, SEEK_CUR). But some platforms treat that as a
3843  * successful no-op even on files that are otherwise unseekable.
3844  */
3845  if (fseeko(fp, tpos, SEEK_SET) != 0)
3846  return false;
3847 
3848  return true;
3849 }
#define pgoff_t
Definition: win32_port.h:208
#define ftello(stream)
Definition: win32_port.h:218
#define fseeko(stream, offset, origin)
Definition: win32_port.h:215

◆ CloneArchive()

ArchiveHandle* CloneArchive ( ArchiveHandle AH)

Definition at line 4755 of file pg_backup_archiver.c.

References _doSetFixedOutputState(), archModeRead, Assert, _archiveHandle::connCancel, ConnectDatabase(), _archiveHandle::connection, _restoreOptions::cparams, _archiveHandle::currSchema, _archiveHandle::currTablespace, _archiveHandle::currUser, _archiveHandle::mode, Archive::n_errors, pg_malloc(), pg_strdup(), _archiveHandle::public, Archive::ropt, _archiveHandle::savedPassword, and _archiveHandle::sqlparse.

Referenced by RunWorker().

4756 {
4757  ArchiveHandle *clone;
4758 
4759  /* Make a "flat" copy */
4760  clone = (ArchiveHandle *) pg_malloc(sizeof(ArchiveHandle));
4761  memcpy(clone, AH, sizeof(ArchiveHandle));
4762 
4763  /* Handle format-independent fields */
4764  memset(&(clone->sqlparse), 0, sizeof(clone->sqlparse));
4765 
4766  /* The clone will have its own connection, so disregard connection state */
4767  clone->connection = NULL;
4768  clone->connCancel = NULL;
4769  clone->currUser = NULL;
4770  clone->currSchema = NULL;
4771  clone->currTablespace = NULL;
4772 
4773  /* savedPassword must be local in case we change it while connecting */
4774  if (clone->savedPassword)
4775  clone->savedPassword = pg_strdup(clone->savedPassword);
4776 
4777  /* clone has its own error count, too */
4778  clone->public.n_errors = 0;
4779 
4780  /*
4781  * Connect our new clone object to the database, using the same connection
4782  * parameters used for the original connection.
4783  */
4784  ConnectDatabase((Archive *) clone, &clone->public.ropt->cparams, true);
4785 
4786  /* re-establish fixed state */
4787  if (AH->mode == archModeRead)
4788  _doSetFixedOutputState(clone);
4789  /* in write case, setupDumpWorker will fix up connection state */
4790 
4791  /* Let the format-specific code have a chance too */
4792  clone->ClonePtr(clone);
4793 
4794  Assert(clone->connection != NULL);
4795  return clone;
4796 }
void ConnectDatabase(Archive *AHX, const ConnParams *cparams, bool isReconnect)
Definition: pg_backup_db.c:114
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
RestoreOptions * ropt
Definition: pg_backup.h:192
int n_errors
Definition: pg_backup.h:215
PGcancel *volatile connCancel
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static void _doSetFixedOutputState(ArchiveHandle *AH)
sqlparseInfo sqlparse
ConnParams cparams
Definition: pg_backup.h:124
#define Assert(condition)
Definition: c.h:804
ClonePtrType ClonePtr

◆ CloseArchive()

void CloseArchive ( Archive AHX)

Definition at line 263 of file pg_backup_archiver.c.

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

Referenced by main().

264 {
265  int res = 0;
266  ArchiveHandle *AH = (ArchiveHandle *) AHX;
267 
268  AH->ClosePtr(AH);
269 
270  /* Close the output */
271  if (AH->gzOut)
272  res = GZCLOSE(AH->OF);
273  else if (AH->OF != stdout)
274  res = fclose(AH->OF);
275 
276  if (res != 0)
277  fatal("could not close output file: %m");
278 }
#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 240 of file pg_backup_archiver.c.

References _allocAH().

Referenced by main().

244 {
245  ArchiveHandle *AH = _allocAH(FileSpec, fmt, compression, dosync,
247 
248  return (Archive *) AH;
249 }
static PgChecksumMode mode
Definition: pg_checksums.c:65
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:94
static void setupDumpWorker(Archive *AHX)
Definition: pg_dump.c:1255

◆ DeCloneArchive()

void DeCloneArchive ( ArchiveHandle AH)

Definition at line 4804 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().

4805 {
4806  /* Should not have an open database connection */
4807  Assert(AH->connection == NULL);
4808 
4809  /* Clear format-specific state */
4810  AH->DeClonePtr(AH);
4811 
4812  /* Clear state allocated by CloneArchive */
4813  if (AH->sqlparse.curCmd)
4815 
4816  /* Clear any connection-local state */
4817  if (AH->currUser)
4818  free(AH->currUser);
4819  if (AH->currSchema)
4820  free(AH->currSchema);
4821  if (AH->currTablespace)
4822  free(AH->currTablespace);
4823  if (AH->currTableAm)
4824  free(AH->currTableAm);
4825  if (AH->savedPassword)
4826  free(AH->savedPassword);
4827 
4828  free(AH);
4829 }
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:804

◆ dump_lo_buf()

static void dump_lo_buf ( ArchiveHandle AH)
static

Definition at line 1636 of file pg_backup_archiver.c.

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

Referenced by ahwrite(), and EndRestoreBlob().

1637 {
1638  if (AH->connection)
1639  {
1640  int res;
1641 
1642  res = lo_write(AH->connection, AH->loFd, AH->lo_buf, AH->lo_buf_used);
1643  pg_log_debug(ngettext("wrote %zu byte of large object data (result = %d)",
1644  "wrote %zu bytes of large object data (result = %d)",
1645  AH->lo_buf_used),
1646  AH->lo_buf_used, res);
1647  /* We assume there are no short writes, only errors */
1648  if (res != AH->lo_buf_used)
1649  warn_or_exit_horribly(AH, "could not write to large object: %s",
1650  PQerrorMessage(AH->connection));
1651  }
1652  else
1653  {
1655 
1657  (const unsigned char *) AH->lo_buf,
1658  AH->lo_buf_used,
1659  AH);
1660 
1661  /* Hack: turn off writingBlob so ahwrite doesn't recurse to here */
1662  AH->writingBlob = 0;
1663  ahprintf(AH, "SELECT pg_catalog.lowrite(0, %s);\n", buf->data);
1664  AH->writingBlob = 1;
1665 
1666  destroyPQExpBuffer(buf);
1667  }
1668  AH->lo_buf_used = 0;
1669 }
#define appendByteaLiteralAHX(buf, str, len, AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6744
void warn_or_exit_horribly(ArchiveHandle *AH, const char *fmt,...)
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:116
#define pg_log_debug(...)
Definition: logging.h:92
static char * buf
Definition: pg_test_fsync.c:68
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:1182
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:74

◆ dumpOptionsFromRestoreOptions()

DumpOptions* dumpOptionsFromRestoreOptions ( RestoreOptions ropt)

Definition at line 177 of file pg_backup_archiver.c.

References _restoreOptions::aclsSkip, _dumpOptions::aclsSkip, _restoreOptions::column_inserts, _dumpOptions::column_inserts, _restoreOptions::cparams, _dumpOptions::cparams, _restoreOptions::createDB, _restoreOptions::dataOnly, _dumpOptions::dataOnly, _connParams::dbname, _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, pg_strdup(), _connParams::pghost, _connParams::pgport, _connParams::promptPassword, _restoreOptions::schemaOnly, _dumpOptions::schemaOnly, _restoreOptions::sequence_data, _dumpOptions::sequence_data, _restoreOptions::superuser, _restoreOptions::use_setsessauth, _dumpOptions::use_setsessauth, and _connParams::username.

Referenced by SetArchiveOptions().

178 {
179  DumpOptions *dopt = NewDumpOptions();
180 
181  /* this is the inverse of what's at the end of pg_dump.c's main() */
182  dopt->cparams.dbname = ropt->cparams.dbname ? pg_strdup(ropt->cparams.dbname) : NULL;
183  dopt->cparams.pgport = ropt->cparams.pgport ? pg_strdup(ropt->cparams.pgport) : NULL;
184  dopt->cparams.pghost = ropt->cparams.pghost ? pg_strdup(ropt->cparams.pghost) : NULL;
185  dopt->cparams.username = ropt->cparams.username ? pg_strdup(ropt->cparams.username) : NULL;
187  dopt->outputClean = ropt->dropSchema;
188  dopt->dataOnly = ropt->dataOnly;
189  dopt->schemaOnly = ropt->schemaOnly;
190  dopt->if_exists = ropt->if_exists;
191  dopt->column_inserts = ropt->column_inserts;
192  dopt->dumpSections = ropt->dumpSections;
193  dopt->aclsSkip = ropt->aclsSkip;
194  dopt->outputSuperuser = ropt->superuser;
195  dopt->outputCreateDB = ropt->createDB;
196  dopt->outputNoOwner = ropt->noOwner;
197  dopt->outputNoTablespaces = ropt->noTablespace;
198  dopt->disable_triggers = ropt->disable_triggers;
199  dopt->use_setsessauth = ropt->use_setsessauth;
201  dopt->dump_inserts = ropt->dump_inserts;
202  dopt->no_comments = ropt->no_comments;
203  dopt->no_publications = ropt->no_publications;
205  dopt->no_subscriptions = ropt->no_subscriptions;
206  dopt->lockWaitTimeout = ropt->lockWaitTimeout;
209  dopt->sequence_data = ropt->sequence_data;
210 
211  return dopt;
212 }
int column_inserts
Definition: pg_backup.h:155
int disable_triggers
Definition: pg_backup.h:165
int disable_dollar_quoting
Definition: pg_backup.h:87
char * pgport
Definition: pg_backup.h:66
bool schemaOnly
Definition: pg_backup.h:146
int no_subscriptions
Definition: pg_backup.h:160
int no_publications
Definition: pg_backup.h:159
DumpOptions * NewDumpOptions(void)
int sequence_data
Definition: pg_backup.h:181
trivalue promptPassword
Definition: pg_backup.h:69
char * dbname
Definition: pg_backup.h:65
const char * lockWaitTimeout
Definition: pg_backup.h:103
int use_setsessauth
Definition: pg_backup.h:167
int disable_dollar_quoting
Definition: pg_backup.h:154
int column_inserts
Definition: pg_backup.h:89
const char * lockWaitTimeout
Definition: pg_backup.h:150
bool dataOnly
Definition: pg_backup.h:147
bool include_everything
Definition: pg_backup.h:172
char * outputSuperuser
Definition: pg_backup.h:179
ConnParams cparams
Definition: pg_backup.h:141
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
int include_everything
Definition: pg_backup.h:104
int no_security_labels
Definition: pg_backup.h:93
int dumpSections
Definition: pg_backup.h:148
int enable_row_security
Definition: pg_backup.h:134
int dump_inserts
Definition: pg_backup.h:151
int outputNoOwner
Definition: pg_backup.h:178
ConnParams cparams
Definition: pg_backup.h:124
int no_security_labels
Definition: pg_backup.h:158
char * pghost
Definition: pg_backup.h:67
char * username
Definition: pg_backup.h:68
int no_subscriptions
Definition: pg_backup.h:94
char * superuser
Definition: pg_backup.h:84
bool aclsSkip
Definition: pg_backup.h:149
int use_setsessauth
Definition: pg_backup.h:82
int enable_row_security
Definition: pg_backup.h:168
int outputCreateDB
Definition: pg_backup.h:175
int outputClean
Definition: pg_backup.h:174
int no_comments
Definition: pg_backup.h:157
int outputNoTablespaces
Definition: pg_backup.h:166
int no_publications
Definition: pg_backup.h:92
int disable_triggers
Definition: pg_backup.h:80

◆ dumpTimestamp()

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

Definition at line 3856 of file pg_backup_archiver.c.

References ahprintf(), buf, and PGDUMP_STRFTIME_FMT.

Referenced by RestoreArchive().

3857 {
3858  char buf[64];
3859 
3860  if (strftime(buf, sizeof(buf), PGDUMP_STRFTIME_FMT, localtime(&tim)) != 0)
3861  ahprintf(AH, "-- %s %s\n\n", msg, buf);
3862 }
static char * buf
Definition: pg_test_fsync.c:68
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 1233 of file pg_backup_archiver.c.

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

Referenced by dumpBlobs().

1234 {
1235  ArchiveHandle *AH = (ArchiveHandle *) AHX;
1236 
1237  if (AH->EndBlobPtr)
1238  AH->EndBlobPtr(AH, AH->currToc, oid);
1239 
1240  return 1;
1241 }
struct _tocEntry * currToc
EndBlobPtrType EndBlobPtr

◆ EndRestoreBlob()

void EndRestoreBlob ( ArchiveHandle AH,
Oid  oid 
)

Definition at line 1337 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().

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

◆ EndRestoreBlobs()

void EndRestoreBlobs ( ArchiveHandle AH)

Definition at line 1270 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().

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

◆ fix_dependencies()

static void fix_dependencies ( ArchiveHandle AH)
static

Definition at line 4452 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().

4453 {
4454  TocEntry *te;
4455  int i;
4456 
4457  /*
4458  * Initialize the depCount/revDeps/nRevDeps fields, and make sure the TOC
4459  * items are marked as not being in any parallel-processing list.
4460  */
4461  for (te = AH->toc->next; te != AH->toc; te = te->next)
4462  {
4463  te->depCount = te->nDeps;
4464  te->revDeps = NULL;
4465  te->nRevDeps = 0;
4466  te->pending_prev = NULL;
4467  te->pending_next = NULL;
4468  }
4469 
4470  /*
4471  * POST_DATA items that are shown as depending on a table need to be
4472  * re-pointed to depend on that table's data, instead. This ensures they
4473  * won't get scheduled until the data has been loaded.
4474  */
4476 
4477  /*
4478  * Pre-8.4 versions of pg_dump neglected to set up a dependency from BLOB
4479  * COMMENTS to BLOBS. Cope. (We assume there's only one BLOBS and only
4480  * one BLOB COMMENTS in such files.)
4481  */
4482  if (AH->version < K_VERS_1_11)
4483  {
4484  for (te = AH->toc->next; te != AH->toc; te = te->next)
4485  {
4486  if (strcmp(te->desc, "BLOB COMMENTS") == 0 && te->nDeps == 0)
4487  {
4488  TocEntry *te2;
4489 
4490  for (te2 = AH->toc->next; te2 != AH->toc; te2 = te2->next)
4491  {
4492  if (strcmp(te2->desc, "BLOBS") == 0)
4493  {
4494  te->dependencies = (DumpId *) pg_malloc(sizeof(DumpId));
4495  te->dependencies[0] = te2->dumpId;
4496  te->nDeps++;
4497  te->depCount++;
4498  break;
4499  }
4500  }
4501  break;
4502  }
4503  }
4504  }
4505 
4506  /*
4507  * At this point we start to build the revDeps reverse-dependency arrays,
4508  * so all changes of dependencies must be complete.
4509  */
4510 
4511  /*
4512  * Count the incoming dependencies for each item. Also, it is possible
4513  * that the dependencies list items that are not in the archive at all
4514  * (that should not happen in 9.2 and later, but is highly likely in older
4515  * archives). Subtract such items from the depCounts.
4516  */
4517  for (te = AH->toc->next; te != AH->toc; te = te->next)
4518  {
4519  for (i = 0; i < te->nDeps; i++)
4520  {
4521  DumpId depid = te->dependencies[i];
4522 
4523  if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL)
4524  AH->tocsByDumpId[depid]->nRevDeps++;
4525  else
4526  te->depCount--;
4527  }
4528  }
4529 
4530  /*
4531  * Allocate space for revDeps[] arrays, and reset nRevDeps so we can use
4532  * it as a counter below.
4533  */
4534  for (te = AH->toc->next; te != AH->toc; te = te->next)
4535  {
4536  if (te->nRevDeps > 0)
4537  te->revDeps = (DumpId *) pg_malloc(te->nRevDeps * sizeof(DumpId));
4538  te->nRevDeps = 0;
4539  }
4540 
4541  /*
4542  * Build the revDeps[] arrays of incoming-dependency dumpIds. This had
4543  * better agree with the loops above.
4544  */
4545  for (te = AH->toc->next; te != AH->toc; te = te->next)
4546  {
4547  for (i = 0; i < te->nDeps; i++)
4548  {
4549  DumpId depid = te->dependencies[i];
4550 
4551  if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL)
4552  {
4553  TocEntry *otherte = AH->tocsByDumpId[depid];
4554 
4555  otherte->revDeps[otherte->nRevDeps++] = te->dumpId;
4556  }
4557  }
4558  }
4559 
4560  /*
4561  * Lastly, work out the locking dependencies.
4562  */
4563  for (te = AH->toc->next; te != AH->toc; te = te->next)
4564  {
4565  te->lockDeps = NULL;
4566  te->nLockDeps = 0;
4568  }
4569 }
struct _tocEntry * next
int DumpId
Definition: pg_backup.h:244
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 1859 of file pg_backup_archiver.c.

References buildTocEntryArrays(), and _archiveHandle::tocsByDumpId.

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

1860 {
1861  /* build index arrays if we didn't already */
1862  if (AH->tocsByDumpId == NULL)
1863  buildTocEntryArrays(AH);
1864 
1865  if (id > 0 && id <= AH->maxDumpId)
1866  return AH->tocsByDumpId[id];
1867 
1868  return NULL;
1869 }
static void buildTocEntryArrays(ArchiveHandle *AH)
struct _tocEntry ** tocsByDumpId

◆ has_lock_conflicts()

static bool has_lock_conflicts ( TocEntry te1,
TocEntry te2 
)
static

Definition at line 4143 of file pg_backup_archiver.c.

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

Referenced by pop_next_work_item().

4144 {
4145  int j,
4146  k;
4147 
4148  for (j = 0; j < te1->nLockDeps; j++)
4149  {
4150  for (k = 0; k < te2->nDeps; k++)
4151  {
4152  if (te1->lockDeps[j] == te2->dependencies[k])
4153  return true;
4154  }
4155  }
4156  return false;
4157 }
DumpId * lockDeps
DumpId * dependencies

◆ identify_locking_dependencies()

static void identify_locking_dependencies ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 4616 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().

4617 {
4618  DumpId *lockids;
4619  int nlockids;
4620  int i;
4621 
4622  /*
4623  * We only care about this for POST_DATA items. PRE_DATA items are not
4624  * run in parallel, and DATA items are all independent by assumption.
4625  */
4626  if (te->section != SECTION_POST_DATA)
4627  return;
4628 
4629  /* Quick exit if no dependencies at all */
4630  if (te->nDeps == 0)
4631  return;
4632 
4633  /*
4634  * Most POST_DATA items are ALTER TABLEs or some moral equivalent of that,
4635  * and hence require exclusive lock. However, we know that CREATE INDEX
4636  * does not. (Maybe someday index-creating CONSTRAINTs will fall in that
4637  * category too ... but today is not that day.)
4638  */
4639  if (strcmp(te->desc, "INDEX") == 0)
4640  return;
4641 
4642  /*
4643  * We assume the entry requires exclusive lock on each TABLE or TABLE DATA
4644  * item listed among its dependencies. Originally all of these would have
4645  * been TABLE items, but repoint_table_dependencies would have repointed
4646  * them to the TABLE DATA items if those are present (which they might not
4647  * be, eg in a schema-only dump). Note that all of the entries we are
4648  * processing here are POST_DATA; otherwise there might be a significant
4649  * difference between a dependency on a table and a dependency on its
4650  * data, so that closer analysis would be needed here.
4651  */
4652  lockids = (DumpId *) pg_malloc(te->nDeps * sizeof(DumpId));
4653  nlockids = 0;
4654  for (i = 0; i < te->nDeps; i++)
4655  {
4656  DumpId depid = te->dependencies[i];
4657 
4658  if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL &&
4659  ((strcmp(AH->tocsByDumpId[depid]->desc, "TABLE DATA") == 0) ||
4660  strcmp(AH->tocsByDumpId[depid]->desc, "TABLE") == 0))
4661  lockids[nlockids++] = depid;
4662  }
4663 
4664  if (nlockids == 0)
4665  {
4666  free(lockids);
4667  return;
4668  }
4669 
4670  te->lockDeps = pg_realloc(lockids, nlockids * sizeof(DumpId));
4671  te->nLockDeps = nlockids;
4672 }
int DumpId
Definition: pg_backup.h:244
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 4735 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().

4736 {
4737  pg_log_info("table \"%s\" could not be created, will not restore its data",
4738  te->tag);
4739 
4740  if (AH->tableDataId[te->dumpId] != 0)
4741  {
4742  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4743 
4744  ted->reqs = 0;
4745  }
4746 }
struct _tocEntry ** tocsByDumpId
#define pg_log_info(...)
Definition: logging.h:88

◆ InitDumpOptions()

void InitDumpOptions ( DumpOptions opts)

Definition at line 163 of file pg_backup_archiver.c.

References _dumpOptions::cparams, DUMP_UNSECTIONED, _dumpOptions::dumpSections, _dumpOptions::include_everything, _connParams::promptPassword, and TRI_DEFAULT.

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;
170 }
trivalue promptPassword
Definition: pg_backup.h:69
bool include_everything
Definition: pg_backup.h:172
ConnParams cparams
Definition: pg_backup.h:141
int dumpSections
Definition: pg_backup.h:148
#define DUMP_UNSECTIONED

◆ mark_create_done()

static void mark_create_done ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 4720 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().

4721 {
4722  if (AH->tableDataId[te->dumpId] != 0)
4723  {
4724  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4725 
4726  ted->created = true;
4727  }
4728 }
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 2382 of file pg_backup_archiver.c.

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

Referenced by WriteDataChunks().

2386 {
2387  pg_log_info("finished item %d %s %s",
2388  te->dumpId, te->desc, te->tag);
2389 
2390  if (status != 0)
2391  fatal("worker process failed: exit code %d",
2392  status);
2393 }
#define fatal(...)
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:229
#define pg_log_info(...)
Definition: logging.h:88

◆ mark_restore_job_done()

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

Definition at line 4411 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().

4415 {
4416  ParallelReadyList *ready_list = (ParallelReadyList *) callback_data;
4417 
4418  pg_log_info("finished item %d %s %s",
4419  te->dumpId, te->desc, te->tag);
4420 
4421  if (status == WORKER_CREATE_DONE)
4422  mark_create_done(AH, te);
4423  else if (status == WORKER_INHIBIT_DATA)
4424  {
4426  AH->public.n_errors++;
4427  }
4428  else if (status == WORKER_IGNORED_ERRORS)
4429  AH->public.n_errors++;
4430  else if (status != 0)
4431  fatal("worker process failed: exit code %d",
4432  status);
4433 
4434  reduce_dependencies(AH, te, ready_list);
4435 }
#define WORKER_CREATE_DONE
int n_errors
Definition: pg_backup.h:215
#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:229
#define pg_log_info(...)
Definition: logging.h:88

◆ move_to_ready_list()

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

Definition at line 4296 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().

4299 {
4300  TocEntry *te;
4301  TocEntry *next_te;
4302 
4303  for (te = pending_list->pending_next; te != pending_list; te = next_te)
4304  {
4305  /* must save list link before possibly removing te from list */
4306  next_te = te->pending_next;
4307 
4308  if (te->depCount == 0 &&
4309  _tocEntryRestorePass(te) == pass)
4310  {
4311  /* Remove it from pending_list ... */
4312  pending_list_remove(te);
4313  /* ... and add to ready_list */
4314  ready_list_insert(ready_list, te);
4315  }
4316  }
4317 }
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(), opts, and pg_malloc().

Referenced by dumpOptionsFromRestoreOptions().

152 {
154 
155  InitDumpOptions(opts);
156  return opts;
157 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
static AmcheckOptions opts
Definition: pg_amcheck.c:110
void InitDumpOptions(DumpOptions *opts)

◆ NewRestoreOptions()

RestoreOptions* NewRestoreOptions ( void  )

Definition at line 964 of file pg_backup_archiver.c.

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

Referenced by _CloseArchive(), and main().

965 {
967 
968  opts = (RestoreOptions *) pg_malloc0(sizeof(RestoreOptions));
969 
970  /* set any fields that shouldn't default to zeroes */
971  opts->format = archUnknown;
974 
975  return opts;
976 }
trivalue promptPassword
Definition: pg_backup.h:69
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
ConnParams cparams
Definition: pg_backup.h:124
static AmcheckOptions opts
Definition: pg_amcheck.c:110
#define DUMP_UNSECTIONED

◆ OpenArchive()

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

Definition at line 254 of file pg_backup_archiver.c.

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

Referenced by main().

255 {
256  ArchiveHandle *AH = _allocAH(FileSpec, fmt, 0, true, archModeRead, setupRestoreWorker);
257 
258  return (Archive *) AH;
259 }
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 4388 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().

4389 {
4390  int status;
4391 
4392  Assert(AH->connection != NULL);
4393 
4394  /* Count only errors associated with this TOC entry */
4395  AH->public.n_errors = 0;
4396 
4397  /* Restore the TOC item */
4398  status = restore_toc_entry(AH, te, true);
4399 
4400  return status;
4401 }
int n_errors
Definition: pg_backup.h:215
static int restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel)
#define Assert(condition)
Definition: c.h:804
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:229

◆ pending_list_append()

static void pending_list_append ( TocEntry l,
TocEntry te 
)
static

Definition at line 4175 of file pg_backup_archiver.c.

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

Referenced by restore_toc_entries_prefork().

4176 {
4177  te->pending_prev = l->pending_prev;
4178  l->pending_prev->pending_next = te;
4179  l->pending_prev = te;
4180  te->pending_next = l;
4181 }
struct _tocEntry * pending_prev
struct _tocEntry * pending_next

◆ pending_list_header_init()

static void pending_list_header_init ( TocEntry l)
static

Definition at line 4168 of file pg_backup_archiver.c.

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

Referenced by RestoreArchive().

4169 {
4170  l->pending_prev = l->pending_next = l;
4171 }
struct _tocEntry * pending_prev
struct _tocEntry * pending_next

◆ pending_list_remove()

static void pending_list_remove ( TocEntry te)
static

Definition at line 4185 of file pg_backup_archiver.c.

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

Referenced by move_to_ready_list(), and reduce_dependencies().

4186 {
4189  te->pending_prev = NULL;
4190  te->pending_next = NULL;
4191 }
struct _tocEntry * pending_prev
struct _tocEntry * pending_next

◆ pop_next_work_item()

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

Definition at line 4331 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().

4333 {
4334  /*
4335  * Sort the ready_list so that we'll tackle larger jobs first.
4336  */
4337  ready_list_sort(ready_list);
4338 
4339  /*
4340  * Search the ready_list until we find a suitable item.
4341  */
4342  for (int i = ready_list->first_te; i <= ready_list->last_te; i++)
4343  {
4344  TocEntry *te = ready_list->tes[i];
4345  bool conflicts = false;
4346 
4347  /*
4348  * Check to see if the item would need exclusive lock on something
4349  * that a currently running item also needs lock on, or vice versa. If
4350  * so, we don't want to schedule them together.
4351  */
4352  for (int k = 0; k < pstate->numWorkers; k++)
4353  {
4354  TocEntry *running_te = pstate->te[k];
4355 
4356  if (running_te == NULL)
4357  continue;
4358  if (has_lock_conflicts(te, running_te) ||
4359  has_lock_conflicts(running_te, te))
4360  {
4361  conflicts = true;
4362  break;
4363  }
4364  }
4365 
4366  if (conflicts)
4367  continue;
4368 
4369  /* passed all tests, so this item can run */
4370  ready_list_remove(ready_list, i);
4371  return te;
4372  }
4373 
4374  pg_log_debug("no item ready");
4375  return NULL;
4376 }
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:92
TocEntry ** te
Definition: parallel.h:59
int i
static bool has_lock_conflicts(TocEntry *te1, TocEntry *te2)
int numWorkers
Definition: parallel.h:57

◆ PrintTOCSummary()

void PrintTOCSummary ( Archive AHX)

Definition at line 1115 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().

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

◆ ProcessArchiveRestoreOptions()

void ProcessArchiveRestoreOptions ( Archive AHX)

Definition at line 295 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().

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

◆ processEncodingEntry()

static void processEncodingEntry ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 2644 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().

2645 {
2646  /* te->defn should have the form SET client_encoding = 'foo'; */
2647  char *defn = pg_strdup(te->defn);
2648  char *ptr1;
2649  char *ptr2 = NULL;
2650  int encoding;
2651 
2652  ptr1 = strchr(defn, '\'');
2653  if (ptr1)
2654  ptr2 = strchr(++ptr1, '\'');
2655  if (ptr2)
2656  {
2657  *ptr2 = '\0';
2658  encoding = pg_char_to_encoding(ptr1);
2659  if (encoding < 0)
2660  fatal("unrecognized encoding \"%s\"",
2661  ptr1);
2662  AH->public.encoding = encoding;
2663  }
2664  else
2665  fatal("invalid ENCODING item: %s",
2666  te->defn);
2667 
2668  free(defn);
2669 }
int pg_char_to_encoding(const char *name)
Definition: encnames.c:550
int encoding
Definition: pg_backup.h:206
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 2688 of file pg_backup_archiver.c.

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

Referenced by ReadToc().

2689 {
2690  /*
2691  * te->defn should contain a command to set search_path. We just copy it
2692  * verbatim for use later.
2693  */
2694  AH->public.searchpath = pg_strdup(te->defn);
2695 }
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
char * searchpath
Definition: pg_backup.h:210

◆ processStdStringsEntry()

static void processStdStringsEntry ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 2672 of file pg_backup_archiver.c.

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

Referenced by ReadToc().

2673 {
2674  /* te->defn should have the form SET standard_conforming_strings = 'x'; */
2675  char *ptr1;
2676 
2677  ptr1 = strchr(te->defn, '\'');
2678  if (ptr1 && strncmp(ptr1, "'on'", 4) == 0)
2679  AH->public.std_strings = true;
2680  else if (ptr1 && strncmp(ptr1, "'off'", 5) == 0)
2681  AH->public.std_strings = false;
2682  else
2683  fatal("invalid STDSTRINGS item: %s",
2684  te->defn);
2685 }
#define fatal(...)
bool std_strings
Definition: pg_backup.h:207

◆ ReadHead()

void ReadHead ( ArchiveHandle AH)

Definition at line 3707 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, pg_tm::tm_sec, _archiveHandle::version, and Z_DEFAULT_COMPRESSION.

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

3708 {
3709  char vmaj,
3710  vmin,
3711  vrev;
3712  int fmt;
3713 
3714  /*
3715  * If we haven't already read the header, do so.
3716  *
3717  * NB: this code must agree with _discoverArchiveFormat(). Maybe find a
3718  * way to unify the cases?
3719  */
3720  if (!AH->readHeader)
3721  {
3722  char tmpMag[7];
3723 
3724  AH->ReadBufPtr(AH, tmpMag, 5);
3725 
3726  if (strncmp(tmpMag, "PGDMP", 5) != 0)
3727  fatal("did not find magic string in file header");
3728  }
3729 
3730  vmaj = AH->ReadBytePtr(AH);
3731  vmin = AH->ReadBytePtr(AH);
3732 
3733  if (vmaj > 1 || (vmaj == 1 && vmin > 0)) /* Version > 1.0 */
3734  vrev = AH->ReadBytePtr(AH);
3735  else
3736  vrev = 0;
3737 
3738  AH->version = MAKE_ARCHIVE_VERSION(vmaj, vmin, vrev);
3739 
3740  if (AH->version < K_VERS_1_0 || AH->version > K_VERS_MAX)
3741  fatal("unsupported version (%d.%d) in file header",
3742  vmaj, vmin);
3743 
3744  AH->intSize = AH->ReadBytePtr(AH);
3745  if (AH->intSize > 32)
3746  fatal("sanity check on integer size (%lu) failed",
3747  (unsigned long) AH->intSize);
3748 
3749  if (AH->intSize > sizeof(int))
3750  pg_log_warning("archive was made on a machine with larger integers, some operations might fail");
3751 
3752  if (AH->version >= K_VERS_1_7)
3753  AH->offSize = AH->ReadBytePtr(AH);
3754  else
3755  AH->offSize = AH->intSize;
3756 
3757  fmt = AH->ReadBytePtr(AH);
3758 
3759  if (AH->format != fmt)
3760  fatal("expected format (%d) differs from format found in file (%d)",
3761  AH->format, fmt);
3762 
3763  if (AH->version >= K_VERS_1_2)
3764  {
3765  if (AH->version < K_VERS_1_4)
3766  AH->compression = AH->ReadBytePtr(AH);
3767  else
3768  AH->compression = ReadInt(AH);
3769  }
3770  else
3772 
3773 #ifndef HAVE_LIBZ
3774  if (AH->compression != 0)
3775  pg_log_warning("archive is compressed, but this installation does not support compression -- no data will be available");
3776 #endif
3777 
3778  if (AH->version >= K_VERS_1_4)
3779  {
3780  struct tm crtm;
3781 
3782  crtm.tm_sec = ReadInt(AH);
3783  crtm.tm_min = ReadInt(AH);
3784  crtm.tm_hour = ReadInt(AH);
3785  crtm.tm_mday = ReadInt(AH);
3786  crtm.tm_mon = ReadInt(AH);
3787  crtm.tm_year = ReadInt(AH);
3788  crtm.tm_isdst = ReadInt(AH);
3789 
3790  /*
3791  * Newer versions of glibc have mktime() report failure if tm_isdst is
3792  * inconsistent with the prevailing timezone, e.g. tm_isdst = 1 when
3793  * TZ=UTC. This is problematic when restoring an archive under a
3794  * different timezone setting. If we get a failure, try again with
3795  * tm_isdst set to -1 ("don't know").
3796  *
3797  * XXX with or without this hack, we reconstruct createDate
3798  * incorrectly when the prevailing timezone is different from
3799  * pg_dump's. Next time we bump the archive version, we should flush
3800  * this representation and store a plain seconds-since-the-Epoch
3801  * timestamp instead.
3802  */
3803  AH->createDate = mktime(&crtm);
3804  if (AH->createDate == (time_t) -1)
3805  {
3806  crtm.tm_isdst = -1;
3807  AH->createDate = mktime(&crtm);
3808  if (AH->createDate == (time_t) -1)
3809  pg_log_warning("invalid creation date in header");
3810  }
3811  }
3812 
3813  if (AH->version >= K_VERS_1_4)
3814  {
3815  AH->archdbname = ReadStr(AH);
3816  }
3817 
3818  if (AH->version >= K_VERS_1_10)
3819  {
3820  AH->archiveRemoteVersion = ReadStr(AH);
3821  AH->archiveDumpVersion = ReadStr(AH);
3822  }
3823 }
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:102
#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(...)
int tm_sec
Definition: pgtime.h:34
#define pg_log_warning(...)
Definition: pgfnames.c:24

◆ ReadInt()

int ReadInt ( ArchiveHandle AH)

Definition at line 1995 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().

1996 {
1997  int res = 0;
1998  int bv,
1999  b;
2000  int sign = 0; /* Default positive */
2001  int bitShift = 0;
2002 
2003  if (AH->version > K_VERS_1_0)
2004  /* Read a sign byte */
2005  sign = AH->ReadBytePtr(AH);
2006 
2007  for (b = 0; b < AH->intSize; b++)
2008  {
2009  bv = AH->ReadBytePtr(AH) & 0xFF;
2010  if (bv != 0)
2011  res = res + (bv << bitShift);
2012  bitShift += 8;
2013  }
2014 
2015  if (sign)
2016  res = -res;
2017 
2018  return res;
2019 }
#define K_VERS_1_0
ReadBytePtrType ReadBytePtr
char sign
Definition: informix.c:668

◆ ReadOffset()

int ReadOffset ( ArchiveHandle AH,
pgoff_t o 
)

Definition at line 1900 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().

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

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

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

2042 {
2043  char *buf;
2044  int l;
2045 
2046  l = ReadInt(AH);
2047  if (l < 0)
2048  buf = NULL;
2049  else
2050  {
2051  buf = (char *) pg_malloc(l + 1);
2052  AH->ReadBufPtr(AH, (void *) buf, l);
2053 
2054  buf[l] = '\0';
2055  }
2056 
2057  return buf;
2058 }
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:68

◆ ReadToc()

void ReadToc ( ArchiveHandle AH)

Definition at line 2489 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().

2490 {
2491  int i;
2492  char *tmp;
2493  DumpId *deps;
2494  int depIdx;
2495  int depSize;
2496  TocEntry *te;
2497 
2498  AH->tocCount = ReadInt(AH);
2499  AH->maxDumpId = 0;
2500 
2501  for (i = 0; i < AH->tocCount; i++)
2502  {
2503  te = (TocEntry *) pg_malloc0(sizeof(TocEntry));
2504  te->dumpId = ReadInt(AH);
2505 
2506  if (te->dumpId > AH->maxDumpId)
2507  AH->maxDumpId = te->dumpId;
2508 
2509  /* Sanity check */
2510  if (te->dumpId <= 0)
2511  fatal("entry ID %d out of range -- perhaps a corrupt TOC",
2512  te->dumpId);
2513 
2514  te->hadDumper = ReadInt(AH);
2515 
2516  if (AH->version >= K_VERS_1_8)
2517  {
2518  tmp = ReadStr(AH);
2519  sscanf(tmp, "%u", &te->catalogId.tableoid);
2520  free(tmp);
2521  }
2522  else
2524  tmp = ReadStr(AH);
2525  sscanf(tmp, "%u", &te->catalogId.oid);
2526  free(tmp);
2527 
2528  te->tag = ReadStr(AH);
2529  te->desc = ReadStr(AH);
2530 
2531  if (AH->version >= K_VERS_1_11)
2532  {
2533  te->section = ReadInt(AH);
2534  }
2535  else
2536  {
2537  /*
2538  * Rules for pre-8.4 archives wherein pg_dump hasn't classified
2539  * the entries into sections. This list need not cover entry
2540  * types added later than 8.4.
2541  */
2542  if (strcmp(te->desc, "COMMENT") == 0 ||
2543  strcmp(te->desc, "ACL") == 0 ||
2544  strcmp(te->desc, "ACL LANGUAGE") == 0)
2545  te->section = SECTION_NONE;
2546  else if (strcmp(te->desc, "TABLE DATA") == 0 ||
2547  strcmp(te->desc, "BLOBS") == 0 ||
2548  strcmp(te->desc, "BLOB COMMENTS") == 0)
2549  te->section = SECTION_DATA;
2550  else if (strcmp(te->desc, "CONSTRAINT") == 0 ||
2551  strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||
2552  strcmp(te->desc, "FK CONSTRAINT") == 0 ||
2553  strcmp(te->desc, "INDEX") == 0 ||
2554  strcmp(te->desc, "RULE") == 0 ||
2555  strcmp(te->desc, "TRIGGER") == 0)
2556  te->section = SECTION_POST_DATA;
2557  else
2558  te->section = SECTION_PRE_DATA;
2559  }
2560 
2561  te->defn = ReadStr(AH);
2562  te->dropStmt = ReadStr(AH);
2563 
2564  if (AH->version >= K_VERS_1_3)
2565  te->copyStmt = ReadStr(AH);
2566 
2567  if (AH->version >= K_VERS_1_6)
2568  te->namespace = ReadStr(AH);
2569 
2570  if (AH->version >= K_VERS_1_10)
2571  te->tablespace = ReadStr(AH);
2572 
2573  if (AH->version >= K_VERS_1_14)
2574  te->tableam = ReadStr(AH);
2575 
2576  te->owner = ReadStr(AH);
2577  if (AH->version < K_VERS_1_9 || strcmp(ReadStr(AH), "true") == 0)
2578  pg_log_warning("restoring tables WITH OIDS is not supported anymore");
2579 
2580  /* Read TOC entry dependencies */
2581  if (AH->version >= K_VERS_1_5)
2582  {
2583  depSize = 100;
2584  deps = (DumpId *) pg_malloc(sizeof(DumpId) * depSize);
2585  depIdx = 0;
2586  for (;;)
2587  {
2588  tmp = ReadStr(AH);
2589  if (!tmp)
2590  break; /* end of list */
2591  if (depIdx >= depSize)
2592  {
2593  depSize *= 2;
2594  deps = (DumpId *) pg_realloc(deps, sizeof(DumpId) * depSize);
2595  }
2596  sscanf(tmp, "%d", &deps[depIdx]);
2597  free(tmp);
2598  depIdx++;
2599  }
2600 
2601  if (depIdx > 0) /* We have a non-null entry */
2602  {
2603  deps = (DumpId *) pg_realloc(deps, sizeof(DumpId) * depIdx);
2604  te->dependencies = deps;
2605  te->nDeps = depIdx;
2606  }
2607  else
2608  {
2609  free(deps);
2610  te->dependencies = NULL;
2611  te->nDeps = 0;
2612  }
2613  }
2614  else
2615  {
2616  te->dependencies = NULL;
2617  te->nDeps = 0;
2618  }
2619  te->dataLength = 0;
2620 
2621  if (AH->ReadExtraTocPtr)
2622  AH->ReadExtraTocPtr(AH, te);
2623 
2624  pg_log_debug("read TOC entry %d (ID %d) for %s %s",
2625  i, te->dumpId, te->desc, te->tag);
2626 
2627  /* link completed entry into TOC circular list */
2628  te->prev = AH->toc->prev;
2629  AH->toc->prev->next = te;
2630  AH->toc->prev = te;
2631  te->next = AH->toc;
2632 
2633  /* special processing immediately upon read for some items */
2634  if (strcmp(te->desc, "ENCODING") == 0)
2635  processEncodingEntry(AH, te);
2636  else if (strcmp(te->desc, "STDSTRINGS") == 0)
2637  processStdStringsEntry(AH, te);
2638  else if (strcmp(te->desc, "SEARCHPATH") == 0)
2639  processSearchPathEntry(AH, te);
2640  }
2641 }
struct _tocEntry * next
static void processEncodingEntry(ArchiveHandle *AH, TocEntry *te)
int DumpId
Definition: pg_backup.h:244
Oid tableoid
Definition: pg_backup.h:240
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:92
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 4211 of file pg_backup_archiver.c.

References pg_free(), and _parallelReadyList::tes.

Referenced by restore_toc_entries_parallel().

4212 {
4213  pg_free(ready_list->tes);
4214 }
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 4198 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().

4199 {
4200  ready_list->tes = (TocEntry **)
4201  pg_malloc(tocCount * sizeof(TocEntry *));
4202  ready_list->first_te = 0;
4203  ready_list->last_te = -1;
4204  ready_list->sorted = false;
4205 }
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 4218 of file pg_backup_archiver.c.

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

Referenced by move_to_ready_list(), and reduce_dependencies().

4219 {
4220  ready_list->tes[++ready_list->last_te] = te;
4221  /* List is (probably) not sorted anymore. */
4222  ready_list->sorted = false;
4223 }

◆ ready_list_remove()

static void ready_list_remove ( ParallelReadyList ready_list,
int  i 
)
static

Definition at line 4227 of file pg_backup_archiver.c.

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

Referenced by pop_next_work_item().

4228 {
4229  int f = ready_list->first_te;
4230 
4231  Assert(i >= f && i <= ready_list->last_te);
4232 
4233  /*
4234  * In the typical case where the item to be removed is the first ready
4235  * entry, we need only increment first_te to remove it. Otherwise, move
4236  * the entries before it to compact the list. (This preserves sortedness,
4237  * if any.) We could alternatively move the entries after i, but there
4238  * are typically many more of those.
4239  */
4240  if (i > f)
4241  {
4242  TocEntry **first_te_ptr = &ready_list->tes[f];
4243 
4244  memmove(first_te_ptr + 1, first_te_ptr, (i - f) * sizeof(TocEntry *));
4245  }
4246  ready_list->first_te++;
4247 }
#define Assert(condition)
Definition: c.h:804
int i

◆ ready_list_sort()

static void ready_list_sort ( ParallelReadyList ready_list)
static

Definition at line 4251 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().

4252 {
4253  if (!ready_list->sorted)
4254  {
4255  int n = ready_list->last_te - ready_list->first_te + 1;
4256 
4257  if (n > 1)
4258  qsort(ready_list->tes + ready_list->first_te, n,
4259  sizeof(TocEntry *),
4261  ready_list->sorted = true;
4262  }
4263 }
static int TocEntrySizeCompare(const void *p1, const void *p2)
#define qsort(a, b, c, d)
Definition: port.h:505

◆ reduce_dependencies()

static void reduce_dependencies ( ArchiveHandle AH,
TocEntry te,
ParallelReadyList ready_list 
)
static

Definition at line 4680 of file pg_backup_archiver.c.

References _tocEntryRestorePass(), Assert, _tocEntry::depCount, _tocEntry::dumpId, i, _tocEntry::nRevDeps, pending_list_remove(), _tocEntry::pending_prev, pg_log_debug, ready_list_insert(), _archiveHandle::restorePass, _tocEntry::revDeps, and _archiveHandle::tocsByDumpId.

Referenced by mark_restore_job_done(), restore_toc_entries_parallel(), and restore_toc_entries_prefork().

4682 {
4683  int i;
4684 
4685  pg_log_debug("reducing dependencies for %d", te->dumpId);
4686 
4687  for (i = 0; i < te->nRevDeps; i++)
4688  {
4689  TocEntry *otherte = AH->tocsByDumpId[te->revDeps[i]];
4690 
4691  Assert(otherte->depCount > 0);
4692  otherte->depCount--;
4693 
4694  /*
4695  * It's ready if it has no remaining dependencies, and it belongs in
4696  * the current restore pass, and it is currently a member of the
4697  * pending list (that check is needed to prevent double restore in
4698  * some cases where a list-file forces out-of-order restoring).
4699  * However, if ready_list == NULL then caller doesn't want any list
4700  * memberships changed.
4701  */
4702  if (otherte->depCount == 0 &&
4703  _tocEntryRestorePass(otherte) == AH->restorePass &&
4704  otherte->pending_prev != NULL &&
4705  ready_list != NULL)
4706  {
4707  /* Remove it from pending list ... */
4708  pending_list_remove(otherte);
4709  /* ... and add to ready_list */
4710  ready_list_insert(ready_list, otherte);
4711  }
4712  }
4713 }
struct _tocEntry * pending_prev
RestorePass restorePass
#define pg_log_debug(...)
Definition: logging.h:92
static RestorePass _tocEntryRestorePass(TocEntry *te)
#define Assert(condition)
Definition: c.h:804
DumpId * revDeps
struct _tocEntry ** tocsByDumpId
static void pending_list_remove(TocEntry *te)
int i
static void ready_list_insert(ParallelReadyList *ready_list, TocEntry *te)

◆ repoint_table_dependencies()

static void repoint_table_dependencies ( ArchiveHandle AH)
static