PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pg_basebackup.c File Reference
#include "postgres_fe.h"
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <time.h>
#include "common/file_utils.h"
#include "common/string.h"
#include "fe_utils/string_utils.h"
#include "getopt_long.h"
#include "libpq-fe.h"
#include "pqexpbuffer.h"
#include "pgtar.h"
#include "pgtime.h"
#include "receivelog.h"
#include "replication/basebackup.h"
#include "streamutil.h"
Include dependency graph for pg_basebackup.c:

Go to the source code of this file.

Data Structures

struct  TablespaceListCell
 
struct  TablespaceList
 
struct  logstreamer_param
 

Macros

#define atooid(x)   ((Oid) strtoul((x), NULL, 10))
 
#define MINIMUM_VERSION_FOR_PG_WAL   100000
 
#define MINIMUM_VERSION_FOR_TEMP_SLOTS   100000
 
#define VERBOSE_FILENAME_LENGTH   35
 
#define WRITE_TAR_DATA(buf, sz)   writeTarData(tarfile, buf, sz, filename)
 

Typedefs

typedef struct TablespaceListCell TablespaceListCell
 
typedef struct TablespaceList TablespaceList
 

Enumerations

enum  IncludeWal { NO_WAL, FETCH_WAL, STREAM_WAL }
 

Functions

static void usage (void)
 
static void disconnect_and_exit (int code)
 
static void verify_dir_is_empty_or_create (char *dirname, bool *created, bool *found)
 
static void progress_report (int tablespacenum, const char *filename, bool force)
 
static void ReceiveTarFile (PGconn *conn, PGresult *res, int rownum)
 
static void ReceiveAndUnpackTarFile (PGconn *conn, PGresult *res, int rownum)
 
static void GenerateRecoveryConf (PGconn *conn)
 
static void WriteRecoveryConf (void)
 
static void BaseBackup (void)
 
static bool reached_end_position (XLogRecPtr segendpos, uint32 timeline, bool segment_finished)
 
static const char * get_tablespace_mapping (const char *dir)
 
static void tablespace_list_append (const char *arg)
 
static void cleanup_directories_atexit (void)
 
static int LogStreamerMain (logstreamer_param *param)
 
static void StartLogStreamer (char *startpos, uint32 timeline, char *sysidentifier)
 
static int32 parse_max_rate (char *src)
 
static void writeTarData (FILE *tarfile, char *buf, int r, char *current_file)
 
static char * escape_quotes (const char *src)
 
int main (int argc, char **argv)
 

Variables

static char * basedir = NULL
 
static TablespaceList tablespace_dirs = {NULL, NULL}
 
static char * xlog_dir = ""
 
static char format = 'p'
 
static char * label = "pg_basebackup base backup"
 
static bool noclean = false
 
static bool showprogress = false
 
static int verbose = 0
 
static int compresslevel = 0
 
static IncludeWal includewal = STREAM_WAL
 
static bool fastcheckpoint = false
 
static bool writerecoveryconf = false
 
static bool do_sync = true
 
static int standby_message_timeout = 10 * 1000
 
static pg_time_t last_progress_report = 0
 
static int32 maxrate = 0
 
static char * replication_slot = NULL
 
static bool temp_replication_slot = true
 
static bool success = false
 
static bool made_new_pgdata = false
 
static bool found_existing_pgdata = false
 
static bool made_new_xlogdir = false
 
static bool found_existing_xlogdir = false
 
static bool made_tablespace_dirs = false
 
static bool found_tablespace_dirs = false
 
static uint64 totalsize
 
static uint64 totaldone
 
static int tablespacecount
 
static int bgpipe [2] = {-1, -1}
 
static pid_t bgchild = -1
 
static bool in_log_streamer = false
 
static XLogRecPtr xlogendptr
 
static int has_xlogendptr = 0
 
static PQExpBuffer recoveryconfcontents = NULL
 

Macro Definition Documentation

#define atooid (   x)    ((Oid) strtoul((x), NULL, 10))

Definition at line 43 of file pg_basebackup.c.

#define MINIMUM_VERSION_FOR_PG_WAL   100000

Definition at line 62 of file pg_basebackup.c.

Referenced by main(), and StartLogStreamer().

#define MINIMUM_VERSION_FOR_TEMP_SLOTS   100000

Definition at line 67 of file pg_basebackup.c.

Referenced by StartLogStreamer().

#define VERBOSE_FILENAME_LENGTH   35

Referenced by progress_report().

#define WRITE_TAR_DATA (   buf,
  sz 
)    writeTarData(tarfile, buf, sz, filename)

Definition at line 918 of file pg_basebackup.c.

Referenced by ReceiveTarFile().

Typedef Documentation

Enumeration Type Documentation

enum IncludeWal
Enumerator
NO_WAL 
FETCH_WAL 
STREAM_WAL 

Definition at line 72 of file pg_basebackup.c.

73 {
74  NO_WAL,
75  FETCH_WAL,
77 } IncludeWal;
IncludeWal
Definition: pg_basebackup.c:72

Function Documentation

static void BaseBackup ( void  )
static

Definition at line 1687 of file pg_basebackup.c.

References _, _dosmaperr(), Assert, basedir, bgchild, bgpipe, CheckServerVersionForStreaming(), conn, destroyPQExpBuffer(), disconnect_and_exit(), do_sync, FALSE, fastcheckpoint, FETCH_WAL, format, found_tablespace_dirs, fsync_fname(), fsync_pgdata(), GenerateRecoveryConf(), get_tablespace_mapping(), has_xlogendptr, i, includewal, label, made_tablespace_dirs, MAXPGPATH, maxrate, MemSet, NO_WAL, NULL, PGRES_COMMAND_OK, PGRES_TUPLES_OK, PQclear(), PQerrorMessage(), PQescapeStringConn(), PQfinish(), PQgetisnull(), PQgetResult(), PQgetvalue(), PQnfields(), PQntuples(), PQparameterStatus(), PQresultStatus(), PQsendQuery(), PQserverVersion(), progname, progress_report(), psprintf(), ReceiveAndUnpackTarFile(), ReceiveTarFile(), RunIdentifySystem(), showprogress, StartLogStreamer(), status(), STREAM_WAL, strerror(), strlcpy(), tablespacecount, totaldone, totalsize, verbose, verify_dir_is_empty_or_create(), WEXITSTATUS, WIFEXITED, write, writerecoveryconf, and xlogendptr.

Referenced by main().

1688 {
1689  PGresult *res;
1690  char *sysidentifier;
1691  TimeLineID latesttli;
1692  TimeLineID starttli;
1693  char *basebkp;
1694  char escaped_label[MAXPGPATH];
1695  char *maxrate_clause = NULL;
1696  int i;
1697  char xlogstart[64];
1698  char xlogend[64];
1699  int minServerMajor,
1700  maxServerMajor;
1701  int serverVersion,
1702  serverMajor;
1703 
1704  Assert(conn != NULL);
1705 
1706  /*
1707  * Check server version. BASE_BACKUP command was introduced in 9.1, so we
1708  * can't work with servers older than 9.1.
1709  */
1710  minServerMajor = 901;
1711  maxServerMajor = PG_VERSION_NUM / 100;
1712  serverVersion = PQserverVersion(conn);
1713  serverMajor = serverVersion / 100;
1714  if (serverMajor < minServerMajor || serverMajor > maxServerMajor)
1715  {
1716  const char *serverver = PQparameterStatus(conn, "server_version");
1717 
1718  fprintf(stderr, _("%s: incompatible server version %s\n"),
1719  progname, serverver ? serverver : "'unknown'");
1721  }
1722 
1723  /*
1724  * If WAL streaming was requested, also check that the server is new
1725  * enough for that.
1726  */
1728  {
1729  /*
1730  * Error message already written in CheckServerVersionForStreaming(),
1731  * but add a hint about using -X none.
1732  */
1733  fprintf(stderr, _("HINT: use -X none or -X fetch to disable log streaming\n"));
1735  }
1736 
1737  /*
1738  * Build contents of recovery.conf if requested
1739  */
1740  if (writerecoveryconf)
1742 
1743  /*
1744  * Run IDENTIFY_SYSTEM so we can get the timeline
1745  */
1746  if (!RunIdentifySystem(conn, &sysidentifier, &latesttli, NULL, NULL))
1748 
1749  /*
1750  * Start the actual backup
1751  */
1752  PQescapeStringConn(conn, escaped_label, label, sizeof(escaped_label), &i);
1753 
1754  if (maxrate > 0)
1755  maxrate_clause = psprintf("MAX_RATE %u", maxrate);
1756 
1757  basebkp =
1758  psprintf("BASE_BACKUP LABEL '%s' %s %s %s %s %s %s",
1759  escaped_label,
1760  showprogress ? "PROGRESS" : "",
1761  includewal == FETCH_WAL ? "WAL" : "",
1762  fastcheckpoint ? "FAST" : "",
1763  includewal == NO_WAL ? "" : "NOWAIT",
1764  maxrate_clause ? maxrate_clause : "",
1765  format == 't' ? "TABLESPACE_MAP" : "");
1766 
1767  if (PQsendQuery(conn, basebkp) == 0)
1768  {
1769  fprintf(stderr, _("%s: could not send replication command \"%s\": %s"),
1770  progname, "BASE_BACKUP", PQerrorMessage(conn));
1772  }
1773 
1774  /*
1775  * Get the starting xlog position
1776  */
1777  res = PQgetResult(conn);
1778  if (PQresultStatus(res) != PGRES_TUPLES_OK)
1779  {
1780  fprintf(stderr, _("%s: could not initiate base backup: %s"),
1783  }
1784  if (PQntuples(res) != 1)
1785  {
1786  fprintf(stderr,
1787  _("%s: server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields\n"),
1788  progname, PQntuples(res), PQnfields(res), 1, 2);
1790  }
1791 
1792  strlcpy(xlogstart, PQgetvalue(res, 0, 0), sizeof(xlogstart));
1793 
1794  /*
1795  * 9.3 and later sends the TLI of the starting point. With older servers,
1796  * assume it's the same as the latest timeline reported by
1797  * IDENTIFY_SYSTEM.
1798  */
1799  if (PQnfields(res) >= 2)
1800  starttli = atoi(PQgetvalue(res, 0, 1));
1801  else
1802  starttli = latesttli;
1803  PQclear(res);
1804  MemSet(xlogend, 0, sizeof(xlogend));
1805 
1806  if (verbose && includewal != NO_WAL)
1807  fprintf(stderr, _("transaction log start point: %s on timeline %u\n"),
1808  xlogstart, starttli);
1809 
1810  /*
1811  * Get the header
1812  */
1813  res = PQgetResult(conn);
1814  if (PQresultStatus(res) != PGRES_TUPLES_OK)
1815  {
1816  fprintf(stderr, _("%s: could not get backup header: %s"),
1819  }
1820  if (PQntuples(res) < 1)
1821  {
1822  fprintf(stderr, _("%s: no data returned from server\n"), progname);
1824  }
1825 
1826  /*
1827  * Sum up the total size, for progress reporting
1828  */
1829  totalsize = totaldone = 0;
1830  tablespacecount = PQntuples(res);
1831  for (i = 0; i < PQntuples(res); i++)
1832  {
1833  totalsize += atol(PQgetvalue(res, i, 2));
1834 
1835  /*
1836  * Verify tablespace directories are empty. Don't bother with the
1837  * first once since it can be relocated, and it will be checked before
1838  * we do anything anyway.
1839  */
1840  if (format == 'p' && !PQgetisnull(res, i, 1))
1841  {
1842  char *path = (char *) get_tablespace_mapping(PQgetvalue(res, i, 1));
1843 
1845  }
1846  }
1847 
1848  /*
1849  * When writing to stdout, require a single tablespace
1850  */
1851  if (format == 't' && strcmp(basedir, "-") == 0 && PQntuples(res) > 1)
1852  {
1853  fprintf(stderr,
1854  _("%s: can only write single tablespace to stdout, database has %d\n"),
1855  progname, PQntuples(res));
1857  }
1858 
1859  /*
1860  * If we're streaming WAL, start the streaming session before we start
1861  * receiving the actual data chunks.
1862  */
1863  if (includewal == STREAM_WAL)
1864  {
1865  if (verbose)
1866  fprintf(stderr, _("%s: starting background WAL receiver\n"),
1867  progname);
1868  StartLogStreamer(xlogstart, starttli, sysidentifier);
1869  }
1870 
1871  /*
1872  * Start receiving chunks
1873  */
1874  for (i = 0; i < PQntuples(res); i++)
1875  {
1876  if (format == 't')
1877  ReceiveTarFile(conn, res, i);
1878  else
1879  ReceiveAndUnpackTarFile(conn, res, i);
1880  } /* Loop over all tablespaces */
1881 
1882  if (showprogress)
1883  {
1884  progress_report(PQntuples(res), NULL, true);
1885  fprintf(stderr, "\n"); /* Need to move to next line */
1886  }
1887 
1888  PQclear(res);
1889 
1890  /*
1891  * Get the stop position
1892  */
1893  res = PQgetResult(conn);
1894  if (PQresultStatus(res) != PGRES_TUPLES_OK)
1895  {
1896  fprintf(stderr,
1897  _("%s: could not get transaction log end position from server: %s"),
1900  }
1901  if (PQntuples(res) != 1)
1902  {
1903  fprintf(stderr,
1904  _("%s: no transaction log end position returned from server\n"),
1905  progname);
1907  }
1908  strlcpy(xlogend, PQgetvalue(res, 0, 0), sizeof(xlogend));
1909  if (verbose && includewal != NO_WAL)
1910  fprintf(stderr, "transaction log end point: %s\n", xlogend);
1911  PQclear(res);
1912 
1913  res = PQgetResult(conn);
1914  if (PQresultStatus(res) != PGRES_COMMAND_OK)
1915  {
1916  fprintf(stderr, _("%s: final receive failed: %s"),
1919  }
1920 
1921  if (bgchild > 0)
1922  {
1923 #ifndef WIN32
1924  int status;
1925  int r;
1926 #else
1927  DWORD status;
1928 
1929  /*
1930  * get a pointer sized version of bgchild to avoid warnings about
1931  * casting to a different size on WIN64.
1932  */
1933  intptr_t bgchild_handle = bgchild;
1934  uint32 hi,
1935  lo;
1936 #endif
1937 
1938  if (verbose)
1939  fprintf(stderr,
1940  _("%s: waiting for background process to finish streaming ...\n"), progname);
1941 
1942 #ifndef WIN32
1943  if (write(bgpipe[1], xlogend, strlen(xlogend)) != strlen(xlogend))
1944  {
1945  fprintf(stderr,
1946  _("%s: could not send command to background pipe: %s\n"),
1947  progname, strerror(errno));
1949  }
1950 
1951  /* Just wait for the background process to exit */
1952  r = waitpid(bgchild, &status, 0);
1953  if (r == -1)
1954  {
1955  fprintf(stderr, _("%s: could not wait for child process: %s\n"),
1956  progname, strerror(errno));
1958  }
1959  if (r != bgchild)
1960  {
1961  fprintf(stderr, _("%s: child %d died, expected %d\n"),
1962  progname, r, (int) bgchild);
1964  }
1965  if (!WIFEXITED(status))
1966  {
1967  fprintf(stderr, _("%s: child process did not exit normally\n"),
1968  progname);
1970  }
1971  if (WEXITSTATUS(status) != 0)
1972  {
1973  fprintf(stderr, _("%s: child process exited with error %d\n"),
1974  progname, WEXITSTATUS(status));
1976  }
1977  /* Exited normally, we're happy! */
1978 #else /* WIN32 */
1979 
1980  /*
1981  * On Windows, since we are in the same process, we can just store the
1982  * value directly in the variable, and then set the flag that says
1983  * it's there.
1984  */
1985  if (sscanf(xlogend, "%X/%X", &hi, &lo) != 2)
1986  {
1987  fprintf(stderr,
1988  _("%s: could not parse transaction log location \"%s\"\n"),
1989  progname, xlogend);
1991  }
1992  xlogendptr = ((uint64) hi) << 32 | lo;
1993  InterlockedIncrement(&has_xlogendptr);
1994 
1995  /* First wait for the thread to exit */
1996  if (WaitForSingleObjectEx((HANDLE) bgchild_handle, INFINITE, FALSE) !=
1997  WAIT_OBJECT_0)
1998  {
1999  _dosmaperr(GetLastError());
2000  fprintf(stderr, _("%s: could not wait for child thread: %s\n"),
2001  progname, strerror(errno));
2003  }
2004  if (GetExitCodeThread((HANDLE) bgchild_handle, &status) == 0)
2005  {
2006  _dosmaperr(GetLastError());
2007  fprintf(stderr, _("%s: could not get child thread exit status: %s\n"),
2008  progname, strerror(errno));
2010  }
2011  if (status != 0)
2012  {
2013  fprintf(stderr, _("%s: child thread exited with error %u\n"),
2014  progname, (unsigned int) status);
2016  }
2017  /* Exited normally, we're happy */
2018 #endif
2019  }
2020 
2021  /* Free the recovery.conf contents */
2023 
2024  /*
2025  * End of copy data. Final result is already checked inside the loop.
2026  */
2027  PQclear(res);
2028  PQfinish(conn);
2029 
2030  /*
2031  * Make data persistent on disk once backup is completed. For tar
2032  * format once syncing the parent directory is fine, each tar file
2033  * created per tablespace has been already synced. In plain format,
2034  * all the data of the base directory is synced, taking into account
2035  * all the tablespaces. Errors are not considered fatal.
2036  */
2037  if (do_sync)
2038  {
2039  if (format == 't')
2040  {
2041  if (strcmp(basedir, "-") != 0)
2042  (void) fsync_fname(basedir, true, progname);
2043  }
2044  else
2045  {
2046  (void) fsync_pgdata(basedir, progname, serverVersion);
2047  }
2048  }
2049 
2050  if (verbose)
2051  fprintf(stderr, "%s: base backup completed\n", progname);
2052 }
int PQnfields(const PGresult *res)
Definition: fe-exec.c:2681
static PQExpBuffer recoveryconfcontents
static IncludeWal includewal
Definition: pg_basebackup.c:89
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:5960
static int bgpipe[2]
void fsync_pgdata(const char *pg_data, const char *progname, int serverVersion)
Definition: file_utils.c:58
uint32 TimeLineID
Definition: xlogdefs.h:45
static bool found_tablespace_dirs
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:5925
#define write(a, b, c)
Definition: win32.h:19
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
void fsync_fname(const char *fname, bool isdir)
Definition: fd.c:567
static int tablespacecount
bool RunIdentifySystem(PGconn *conn, char **sysid, TimeLineID *starttli, XLogRecPtr *startpos, char **db_name)
Definition: streamutil.c:245
#define WIFEXITED(w)
Definition: win32.h:180
static bool writerecoveryconf
Definition: pg_basebackup.c:91
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3517
#define MemSet(start, val, len)
Definition: c.h:853
int PQserverVersion(const PGconn *conn)
Definition: fe-connect.c:5950
const char * progname
Definition: pg_standby.c:37
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
static void GenerateRecoveryConf(PGconn *conn)
static char * basedir
Definition: pg_basebackup.c:80
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2596
int PQsendQuery(PGconn *conn, const char *query)
Definition: fe-exec.c:1132
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:113
#define FALSE
Definition: c.h:218
PGconn * conn
Definition: streamutil.c:45
#define MAXPGPATH
static uint64 totaldone
static int32 maxrate
Definition: pg_basebackup.c:95
static int has_xlogendptr
size_t PQescapeStringConn(PGconn *conn, char *to, const char *from, size_t length, int *error)
Definition: fe-exec.c:3314
unsigned int uint32
Definition: c.h:265
static uint64 totalsize
static const char * get_tablespace_mapping(const char *dir)
static void progress_report(int tablespacenum, const char *filename, bool force)
static int verbose
Definition: pg_basebackup.c:87
static bool showprogress
Definition: pg_basebackup.c:86
static void ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
static char * label
Definition: pg_basebackup.c:84
static void StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier)
void PQclear(PGresult *res)
Definition: fe-exec.c:650
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define WEXITSTATUS(w)
Definition: win32.h:182
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
void _dosmaperr(unsigned long)
Definition: win32error.c:171
static void ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
static XLogRecPtr xlogendptr
static bool fastcheckpoint
Definition: pg_basebackup.c:90
static bool made_tablespace_dirs
static pid_t bgchild
int i
const char * strerror(int errnum)
Definition: strerror.c:19
static bool do_sync
Definition: pg_basebackup.c:92
static void verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found)
static char format
Definition: pg_basebackup.c:83
static void disconnect_and_exit(int code)
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:222
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3092
#define _(x)
Definition: elog.c:84
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:1702
bool CheckServerVersionForStreaming(PGconn *conn)
Definition: receivelog.c:360
static void cleanup_directories_atexit ( void  )
static

Definition at line 153 of file pg_basebackup.c.

References _, basedir, found_existing_pgdata, found_existing_xlogdir, found_tablespace_dirs, in_log_streamer, made_new_pgdata, made_new_xlogdir, made_tablespace_dirs, noclean, progname, rmtree(), success, and xlog_dir.

Referenced by main().

154 {
155  if (success || in_log_streamer)
156  return;
157 
158  if (!noclean)
159  {
160  if (made_new_pgdata)
161  {
162  fprintf(stderr, _("%s: removing data directory \"%s\"\n"),
163  progname, basedir);
164  if (!rmtree(basedir, true))
165  fprintf(stderr, _("%s: failed to remove data directory\n"),
166  progname);
167  }
168  else if (found_existing_pgdata)
169  {
170  fprintf(stderr,
171  _("%s: removing contents of data directory \"%s\"\n"),
172  progname, basedir);
173  if (!rmtree(basedir, false))
174  fprintf(stderr, _("%s: failed to remove contents of data directory\n"),
175  progname);
176  }
177 
178  if (made_new_xlogdir)
179  {
180  fprintf(stderr, _("%s: removing transaction log directory \"%s\"\n"),
181  progname, xlog_dir);
182  if (!rmtree(xlog_dir, true))
183  fprintf(stderr, _("%s: failed to remove transaction log directory\n"),
184  progname);
185  }
186  else if (found_existing_xlogdir)
187  {
188  fprintf(stderr,
189  _("%s: removing contents of transaction log directory \"%s\"\n"),
190  progname, xlog_dir);
191  if (!rmtree(xlog_dir, false))
192  fprintf(stderr, _("%s: failed to remove contents of transaction log directory\n"),
193  progname);
194  }
195  }
196  else
197  {
199  fprintf(stderr,
200  _("%s: data directory \"%s\" not removed at user's request\n"),
201  progname, basedir);
202 
204  fprintf(stderr,
205  _("%s: transaction log directory \"%s\" not removed at user's request\n"),
206  progname, xlog_dir);
207  }
208 
210  fprintf(stderr,
211  _("%s: changes to tablespace directories will not be undone\n"),
212  progname);
213 }
static bool found_existing_pgdata
static bool found_tablespace_dirs
const char * progname
Definition: pg_standby.c:37
static char * basedir
Definition: pg_basebackup.c:80
static bool found_existing_xlogdir
static bool success
Definition: pg_basebackup.c:99
static bool made_new_pgdata
bool rmtree(const char *path, bool rmtopdir)
Definition: rmtree.c:36
static bool in_log_streamer
static char * xlog_dir
Definition: pg_basebackup.c:82
static bool made_new_xlogdir
static bool made_tablespace_dirs
#define _(x)
Definition: elog.c:84
static bool noclean
Definition: pg_basebackup.c:85
static void disconnect_and_exit ( int  code)
static

Definition at line 216 of file pg_basebackup.c.

References bgchild, conn, NULL, and PQfinish().

Referenced by BaseBackup(), GenerateRecoveryConf(), main(), ReceiveAndUnpackTarFile(), ReceiveTarFile(), StartLogStreamer(), verify_dir_is_empty_or_create(), WriteRecoveryConf(), and writeTarData().

217 {
218  if (conn != NULL)
219  PQfinish(conn);
220 
221 #ifndef WIN32
222 
223  /*
224  * On windows, our background thread dies along with the process. But on
225  * Unix, if we have started a subprocess, we want to kill it off so it
226  * doesn't remain running trying to stream data.
227  */
228  if (bgchild > 0)
229  kill(bgchild, SIGTERM);
230 #endif
231 
232  exit(code);
233 }
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3517
PGconn * conn
Definition: streamutil.c:45
#define NULL
Definition: c.h:226
static pid_t bgchild
static char* escape_quotes ( const char *  src)
static

Definition at line 1559 of file pg_basebackup.c.

References _, escape_single_quotes_ascii(), and progname.

Referenced by GenerateRecoveryConf().

1560 {
1561  char *result = escape_single_quotes_ascii(src);
1562 
1563  if (!result)
1564  {
1565  fprintf(stderr, _("%s: out of memory\n"), progname);
1566  exit(1);
1567  }
1568  return result;
1569 }
const char * progname
Definition: pg_standby.c:37
char * escape_single_quotes_ascii(const char *src)
Definition: quotes.c:33
#define _(x)
Definition: elog.c:84
static void GenerateRecoveryConf ( PGconn conn)
static

Definition at line 1575 of file pg_basebackup.c.

References _, appendConnStrVal(), appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), createPQExpBuffer(), PQExpBufferData::data, disconnect_and_exit(), escape_quotes(), free, initPQExpBuffer(), _PQconninfoOption::keyword, PQExpBufferData::len, NULL, PQconninfo(), PQconninfoFree(), PQExpBufferBroken, PQExpBufferDataBroken, progname, replication_slot, termPQExpBuffer(), and _PQconninfoOption::val.

Referenced by BaseBackup().

1576 {
1577  PQconninfoOption *connOptions;
1579  PQExpBufferData conninfo_buf;
1580  char *escaped;
1581 
1583  if (!recoveryconfcontents)
1584  {
1585  fprintf(stderr, _("%s: out of memory\n"), progname);
1587  }
1588 
1589  connOptions = PQconninfo(conn);
1590  if (connOptions == NULL)
1591  {
1592  fprintf(stderr, _("%s: out of memory\n"), progname);
1594  }
1595 
1596  appendPQExpBufferStr(recoveryconfcontents, "standby_mode = 'on'\n");
1597 
1598  initPQExpBuffer(&conninfo_buf);
1599  for (option = connOptions; option && option->keyword; option++)
1600  {
1601  /*
1602  * Do not emit this setting if: - the setting is "replication",
1603  * "dbname" or "fallback_application_name", since these would be
1604  * overridden by the libpqwalreceiver module anyway. - not set or
1605  * empty.
1606  */
1607  if (strcmp(option->keyword, "replication") == 0 ||
1608  strcmp(option->keyword, "dbname") == 0 ||
1609  strcmp(option->keyword, "fallback_application_name") == 0 ||
1610  (option->val == NULL) ||
1611  (option->val != NULL && option->val[0] == '\0'))
1612  continue;
1613 
1614  /* Separate key-value pairs with spaces */
1615  if (conninfo_buf.len != 0)
1616  appendPQExpBufferChar(&conninfo_buf, ' ');
1617 
1618  /*
1619  * Write "keyword=value" pieces, the value string is escaped and/or
1620  * quoted if necessary.
1621  */
1622  appendPQExpBuffer(&conninfo_buf, "%s=", option->keyword);
1623  appendConnStrVal(&conninfo_buf, option->val);
1624  }
1625 
1626  /*
1627  * Escape the connection string, so that it can be put in the config file.
1628  * Note that this is different from the escaping of individual connection
1629  * options above!
1630  */
1631  escaped = escape_quotes(conninfo_buf.data);
1632  appendPQExpBuffer(recoveryconfcontents, "primary_conninfo = '%s'\n", escaped);
1633  free(escaped);
1634 
1635  if (replication_slot)
1636  {
1637  escaped = escape_quotes(replication_slot);
1638  appendPQExpBuffer(recoveryconfcontents, "primary_slot_name = '%s'\n", replication_slot);
1639  free(escaped);
1640  }
1641 
1643  PQExpBufferDataBroken(conninfo_buf))
1644  {
1645  fprintf(stderr, _("%s: out of memory\n"), progname);
1647  }
1648 
1649  termPQExpBuffer(&conninfo_buf);
1650 
1651  PQconninfoFree(connOptions);
1652 }
static PQExpBuffer recoveryconfcontents
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
void appendConnStrVal(PQExpBuffer buf, const char *str)
Definition: string_utils.c:536
static char * escape_quotes(const char *src)
const char * progname
Definition: pg_standby.c:37
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5810
PQconninfoOption * PQconninfo(PGconn *conn)
Definition: fe-connect.c:5769
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:71
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:396
#define free(a)
Definition: header.h:60
#define PQExpBufferDataBroken(buf)
Definition: pqexpbuffer.h:67
#define NULL
Definition: c.h:226
#define PQExpBufferBroken(str)
Definition: pqexpbuffer.h:59
static void disconnect_and_exit(int code)
static char * replication_slot
Definition: pg_basebackup.c:96
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
static const char * get_tablespace_mapping ( const char *  dir)
static

Definition at line 1277 of file pg_basebackup.c.

References TablespaceList::head, TablespaceListCell::new_dir, TablespaceListCell::next, and TablespaceListCell::old_dir.

Referenced by BaseBackup(), and ReceiveAndUnpackTarFile().

1278 {
1279  TablespaceListCell *cell;
1280 
1281  for (cell = tablespace_dirs.head; cell; cell = cell->next)
1282  if (strcmp(dir, cell->old_dir) == 0)
1283  return cell->new_dir;
1284 
1285  return dir;
1286 }
static TablespaceList tablespace_dirs
Definition: pg_basebackup.c:81
char old_dir[MAXPGPATH]
Definition: pg_basebackup.c:48
char new_dir[MAXPGPATH]
Definition: pg_basebackup.c:49
struct TablespaceListCell * next
Definition: pg_basebackup.c:47
TablespaceListCell * head
Definition: pg_basebackup.c:54
static int LogStreamerMain ( logstreamer_param param)
static

Definition at line 475 of file pg_basebackup.c.

References _, logstreamer_param::bgconn, compresslevel, CreateWalDirectoryMethod(), CreateWalTarMethod(), StreamCtl::do_sync, do_sync, WalWriteMethod::finish, format, FreeWalDirectoryMethod(), FreeWalTarMethod(), in_log_streamer, StreamCtl::mark_done, MemSet, NULL, StreamCtl::partial_suffix, pg_free(), PQfinish(), progname, psprintf(), reached_end_position(), ReceiveXlogStream(), StreamCtl::replication_slot, replication_slot, StreamCtl::standby_message_timeout, standby_message_timeout, StreamCtl::startpos, logstreamer_param::startptr, StreamCtl::stream_stop, strerror(), StreamCtl::synchronous, StreamCtl::sysidentifier, logstreamer_param::sysidentifier, StreamCtl::temp_slot, logstreamer_param::temp_slot, StreamCtl::timeline, logstreamer_param::timeline, StreamCtl::walmethod, and logstreamer_param::xlog.

Referenced by StartLogStreamer().

476 {
477  StreamCtl stream;
478 
479  in_log_streamer = true;
480 
481  MemSet(&stream, 0, sizeof(stream));
482  stream.startpos = param->startptr;
483  stream.timeline = param->timeline;
484  stream.sysidentifier = param->sysidentifier;
487  stream.synchronous = false;
488  stream.do_sync = do_sync;
489  stream.mark_done = true;
490  stream.partial_suffix = NULL;
492  stream.temp_slot = param->temp_slot;
493  if (stream.temp_slot && !stream.replication_slot)
494  stream.replication_slot = psprintf("pg_basebackup_%d", (int) getpid());
495 
496  if (format == 'p')
497  stream.walmethod = CreateWalDirectoryMethod(param->xlog, 0, do_sync);
498  else
500 
501  if (!ReceiveXlogStream(param->bgconn, &stream))
502 
503  /*
504  * Any errors will already have been reported in the function process,
505  * but we need to tell the parent that we didn't shutdown in a nice
506  * way.
507  */
508  return 1;
509 
510  if (!stream.walmethod->finish())
511  {
512  fprintf(stderr,
513  _("%s: could not finish writing WAL files: %s\n"),
514  progname, strerror(errno));
515  return 1;
516  }
517 
518  PQfinish(param->bgconn);
519 
520  if (format == 'p')
522  else
524  pg_free(stream.walmethod);
525 
526  return 0;
527 }
bool do_sync
Definition: receivelog.h:40
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
char * sysidentifier
Definition: receivelog.h:34
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3517
static int compresslevel
Definition: pg_basebackup.c:88
#define MemSet(start, val, len)
Definition: c.h:853
XLogRecPtr startpos
Definition: receivelog.h:32
char * partial_suffix
Definition: receivelog.h:46
const char * progname
Definition: pg_standby.c:37
static bool reached_end_position(XLogRecPtr segendpos, uint32 timeline, bool segment_finished)
TimeLineID timeline
Definition: receivelog.h:33
WalWriteMethod * CreateWalDirectoryMethod(const char *basedir, int compression, bool sync)
Definition: walmethods.c:346
bool(* finish)(void)
Definition: walmethods.h:33
char * replication_slot
Definition: receivelog.h:47
bool mark_done
Definition: receivelog.h:39
XLogRecPtr startptr
stream_stop_callback stream_stop
Definition: receivelog.h:43
WalWriteMethod * walmethod
Definition: receivelog.h:45
static int standby_message_timeout
Definition: pg_basebackup.c:93
void FreeWalTarMethod(void)
Definition: walmethods.c:978
static bool in_log_streamer
#define NULL
Definition: c.h:226
WalWriteMethod * CreateWalTarMethod(const char *tarbase, int compression, bool sync)
Definition: walmethods.c:947
bool ReceiveXlogStream(PGconn *conn, StreamCtl *stream)
Definition: receivelog.c:433
bool synchronous
Definition: receivelog.h:38
void pg_free(void *ptr)
Definition: fe_memutils.c:105
const char * strerror(int errnum)
Definition: strerror.c:19
int standby_message_timeout
Definition: receivelog.h:36
static bool do_sync
Definition: pg_basebackup.c:92
static char format
Definition: pg_basebackup.c:83
static char * replication_slot
Definition: pg_basebackup.c:96
bool temp_slot
Definition: receivelog.h:48
#define _(x)
Definition: elog.c:84
void FreeWalDirectoryMethod(void)
Definition: walmethods.c:370
char xlog[MAXPGPATH]
int main ( int  argc,
char **  argv 
)

Definition at line 2056 of file pg_basebackup.c.

References _, BaseBackup(), basedir, canonicalize_path(), cleanup_directories_atexit(), compresslevel, conn, connection_string, dbgetpassword, dbhost, dbport, dbuser, disconnect_and_exit(), do_sync, fastcheckpoint, FETCH_WAL, format, found_existing_pgdata, found_existing_xlogdir, free, get_progname(), GetConnection(), getopt_long(), includewal, is_absolute_path, label, made_new_pgdata, made_new_xlogdir, maxrate, MINIMUM_VERSION_FOR_PG_WAL, no_argument, NO_WAL, noclean, NULL, optarg, optind, parse_max_rate(), pg_strcasecmp(), pg_strdup(), PG_TEXTDOMAIN, PQserverVersion(), progname, psprintf(), replication_slot, required_argument, set_pglocale_pgservice(), showprogress, standby_message_timeout, STREAM_WAL, strerror(), success, tablespace_list_append(), temp_replication_slot, usage(), verbose, verify_dir_is_empty_or_create(), writerecoveryconf, xlog_dir, and Z_DEFAULT_COMPRESSION.

2057 {
2058  static struct option long_options[] = {
2059  {"help", no_argument, NULL, '?'},
2060  {"version", no_argument, NULL, 'V'},
2061  {"pgdata", required_argument, NULL, 'D'},
2062  {"format", required_argument, NULL, 'F'},
2063  {"checkpoint", required_argument, NULL, 'c'},
2064  {"max-rate", required_argument, NULL, 'r'},
2065  {"write-recovery-conf", no_argument, NULL, 'R'},
2066  {"slot", required_argument, NULL, 'S'},
2067  {"tablespace-mapping", required_argument, NULL, 'T'},
2068  {"wal-method", required_argument, NULL, 'X'},
2069  {"gzip", no_argument, NULL, 'z'},
2070  {"compress", required_argument, NULL, 'Z'},
2071  {"label", required_argument, NULL, 'l'},
2072  {"no-clean", no_argument, NULL, 'n'},
2073  {"no-sync", no_argument, NULL, 'N'},
2074  {"dbname", required_argument, NULL, 'd'},
2075  {"host", required_argument, NULL, 'h'},
2076  {"port", required_argument, NULL, 'p'},
2077  {"username", required_argument, NULL, 'U'},
2078  {"no-password", no_argument, NULL, 'w'},
2079  {"password", no_argument, NULL, 'W'},
2080  {"status-interval", required_argument, NULL, 's'},
2081  {"verbose", no_argument, NULL, 'v'},
2082  {"progress", no_argument, NULL, 'P'},
2083  {"waldir", required_argument, NULL, 1},
2084  {"no-slot", no_argument, NULL, 2},
2085  {NULL, 0, NULL, 0}
2086  };
2087  int c;
2088 
2089  int option_index;
2090  bool no_slot = false;
2091 
2092  progname = get_progname(argv[0]);
2093  set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_basebackup"));
2094 
2095  if (argc > 1)
2096  {
2097  if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
2098  {
2099  usage();
2100  exit(0);
2101  }
2102  else if (strcmp(argv[1], "-V") == 0
2103  || strcmp(argv[1], "--version") == 0)
2104  {
2105  puts("pg_basebackup (PostgreSQL) " PG_VERSION);
2106  exit(0);
2107  }
2108  }
2109 
2111 
2112  while ((c = getopt_long(argc, argv, "D:F:r:RT:X:l:nNzZ:d:c:h:p:U:s:S:wWvP",
2113  long_options, &option_index)) != -1)
2114  {
2115  switch (c)
2116  {
2117  case 'D':
2119  break;
2120  case 'F':
2121  if (strcmp(optarg, "p") == 0 || strcmp(optarg, "plain") == 0)
2122  format = 'p';
2123  else if (strcmp(optarg, "t") == 0 || strcmp(optarg, "tar") == 0)
2124  format = 't';
2125  else
2126  {
2127  fprintf(stderr,
2128  _("%s: invalid output format \"%s\", must be \"plain\" or \"tar\"\n"),
2129  progname, optarg);
2130  exit(1);
2131  }
2132  break;
2133  case 'r':
2135  break;
2136  case 'R':
2137  writerecoveryconf = true;
2138  break;
2139  case 'S':
2140 
2141  /*
2142  * When specifying replication slot name, use a permanent
2143  * slot.
2144  */
2146  temp_replication_slot = false;
2147  break;
2148  case 2:
2149  no_slot = true;
2150  break;
2151  case 'T':
2153  break;
2154  case 'X':
2155  if (strcmp(optarg, "n") == 0 ||
2156  strcmp(optarg, "none") == 0)
2157  {
2158  includewal = NO_WAL;
2159  }
2160  else if (strcmp(optarg, "f") == 0 ||
2161  strcmp(optarg, "fetch") == 0)
2162  {
2164  }
2165  else if (strcmp(optarg, "s") == 0 ||
2166  strcmp(optarg, "stream") == 0)
2167  {
2169  }
2170  else
2171  {
2172  fprintf(stderr,
2173  _("%s: invalid wal-method option \"%s\", must be \"fetch\", \"stream\" or \"none\"\n"),
2174  progname, optarg);
2175  exit(1);
2176  }
2177  break;
2178  case 1:
2180  break;
2181  case 'l':
2182  label = pg_strdup(optarg);
2183  break;
2184  case 'n':
2185  noclean = true;
2186  break;
2187  case 'N':
2188  do_sync = false;
2189  break;
2190  case 'z':
2191 #ifdef HAVE_LIBZ
2193 #else
2194  compresslevel = 1; /* will be rejected below */
2195 #endif
2196  break;
2197  case 'Z':
2198  compresslevel = atoi(optarg);
2199  if (compresslevel < 0 || compresslevel > 9)
2200  {
2201  fprintf(stderr, _("%s: invalid compression level \"%s\"\n"),
2202  progname, optarg);
2203  exit(1);
2204  }
2205  break;
2206  case 'c':
2207  if (pg_strcasecmp(optarg, "fast") == 0)
2208  fastcheckpoint = true;
2209  else if (pg_strcasecmp(optarg, "spread") == 0)
2210  fastcheckpoint = false;
2211  else
2212  {
2213  fprintf(stderr, _("%s: invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"\n"),
2214  progname, optarg);
2215  exit(1);
2216  }
2217  break;
2218  case 'd':
2220  break;
2221  case 'h':
2222  dbhost = pg_strdup(optarg);
2223  break;
2224  case 'p':
2225  dbport = pg_strdup(optarg);
2226  break;
2227  case 'U':
2228  dbuser = pg_strdup(optarg);
2229  break;
2230  case 'w':
2231  dbgetpassword = -1;
2232  break;
2233  case 'W':
2234  dbgetpassword = 1;
2235  break;
2236  case 's':
2237  standby_message_timeout = atoi(optarg) * 1000;
2238  if (standby_message_timeout < 0)
2239  {
2240  fprintf(stderr, _("%s: invalid status interval \"%s\"\n"),
2241  progname, optarg);
2242  exit(1);
2243  }
2244  break;
2245  case 'v':
2246  verbose++;
2247  break;
2248  case 'P':
2249  showprogress = true;
2250  break;
2251  default:
2252 
2253  /*
2254  * getopt_long already emitted a complaint
2255  */
2256  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2257  progname);
2258  exit(1);
2259  }
2260  }
2261 
2262  /*
2263  * Any non-option arguments?
2264  */
2265  if (optind < argc)
2266  {
2267  fprintf(stderr,
2268  _("%s: too many command-line arguments (first is \"%s\")\n"),
2269  progname, argv[optind]);
2270  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2271  progname);
2272  exit(1);
2273  }
2274 
2275  /*
2276  * Required arguments
2277  */
2278  if (basedir == NULL)
2279  {
2280  fprintf(stderr, _("%s: no target directory specified\n"), progname);
2281  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2282  progname);
2283  exit(1);
2284  }
2285 
2286  /*
2287  * Mutually exclusive arguments
2288  */
2289  if (format == 'p' && compresslevel != 0)
2290  {
2291  fprintf(stderr,
2292  _("%s: only tar mode backups can be compressed\n"),
2293  progname);
2294  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2295  progname);
2296  exit(1);
2297  }
2298 
2299  if (format == 't' && includewal == STREAM_WAL && strcmp(basedir, "-") == 0)
2300  {
2301  fprintf(stderr,
2302  _("%s: cannot stream transaction logs in tar mode to stdout\n"),
2303  progname);
2304  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2305  progname);
2306  exit(1);
2307  }
2308 
2310  {
2311  fprintf(stderr,
2312  _("%s: replication slots can only be used with WAL streaming\n"),
2313  progname);
2314  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2315  progname);
2316  exit(1);
2317  }
2318 
2319  if (no_slot)
2320  {
2321  if (replication_slot)
2322  {
2323  fprintf(stderr,
2324  _("%s: --no-slot cannot be used with slot name\n"),
2325  progname);
2326  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2327  progname);
2328  exit(1);
2329  }
2330  temp_replication_slot = false;
2331  }
2332 
2333  if (strcmp(xlog_dir, "") != 0)
2334  {
2335  if (format != 'p')
2336  {
2337  fprintf(stderr,
2338  _("%s: transaction log directory location can only be specified in plain mode\n"),
2339  progname);
2340  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2341  progname);
2342  exit(1);
2343  }
2344 
2345  /* clean up xlog directory name, check it's absolute */
2347  if (!is_absolute_path(xlog_dir))
2348  {
2349  fprintf(stderr, _("%s: transaction log directory location must be "
2350  "an absolute path\n"), progname);
2351  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2352  progname);
2353  exit(1);
2354  }
2355  }
2356 
2357 #ifndef HAVE_LIBZ
2358  if (compresslevel != 0)
2359  {
2360  fprintf(stderr,
2361  _("%s: this build does not support compression\n"),
2362  progname);
2363  exit(1);
2364  }
2365 #endif
2366 
2367  /*
2368  * Verify that the target directory exists, or create it. For plaintext
2369  * backups, always require the directory. For tar backups, require it
2370  * unless we are writing to stdout.
2371  */
2372  if (format == 'p' || strcmp(basedir, "-") != 0)
2374 
2375  /* connection in replication mode to server */
2376  conn = GetConnection();
2377  if (!conn)
2378  {
2379  /* Error message already written in GetConnection() */
2380  exit(1);
2381  }
2382 
2383  /* Create transaction log symlink, if required */
2384  if (strcmp(xlog_dir, "") != 0)
2385  {
2386  char *linkloc;
2387 
2389 
2390  /*
2391  * Form name of the place where the symlink must go. pg_xlog has
2392  * been renamed to pg_wal in post-10 clusters.
2393  */
2394  linkloc = psprintf("%s/%s", basedir,
2396  "pg_xlog" : "pg_wal");
2397 
2398 #ifdef HAVE_SYMLINK
2399  if (symlink(xlog_dir, linkloc) != 0)
2400  {
2401  fprintf(stderr, _("%s: could not create symbolic link \"%s\": %s\n"),
2402  progname, linkloc, strerror(errno));
2404  }
2405 #else
2406  fprintf(stderr, _("%s: symlinks are not supported on this platform\n"));
2408 #endif
2409  free(linkloc);
2410  }
2411 
2412  BaseBackup();
2413 
2414  success = true;
2415  return 0;
2416 }
static IncludeWal includewal
Definition: pg_basebackup.c:89
#define Z_DEFAULT_COMPRESSION
static bool found_existing_pgdata
static void usage(void)
const char * get_progname(const char *argv0)
Definition: path.c:453
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
Definition: getopt_long.c:57
static int32 parse_max_rate(char *src)
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
void canonicalize_path(char *path)
Definition: path.c:254
static bool writerecoveryconf
Definition: pg_basebackup.c:91
static int compresslevel
Definition: pg_basebackup.c:88
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
int PQserverVersion(const PGconn *conn)
Definition: fe-connect.c:5950
const char * progname
Definition: pg_standby.c:37
static char * basedir
Definition: pg_basebackup.c:80
static void BaseBackup(void)
#define required_argument
Definition: getopt_long.h:25
int optind
Definition: getopt.c:51
char * connection_string
Definition: streamutil.c:37
PGconn * conn
Definition: streamutil.c:45
#define MINIMUM_VERSION_FOR_PG_WAL
Definition: pg_basebackup.c:62
static bool found_existing_xlogdir
static bool success
Definition: pg_basebackup.c:99
static int32 maxrate
Definition: pg_basebackup.c:95
char * c
static bool made_new_pgdata
#define is_absolute_path(filename)
Definition: port.h:77
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static int verbose
Definition: pg_basebackup.c:87
static int standby_message_timeout
Definition: pg_basebackup.c:93
static bool showprogress
Definition: pg_basebackup.c:86
int dbgetpassword
Definition: streamutil.c:42
#define no_argument
Definition: getopt_long.h:24
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1012
static bool temp_replication_slot
Definition: pg_basebackup.c:97
static char * label
Definition: pg_basebackup.c:84
char * dbport
Definition: streamutil.c:40
static void cleanup_directories_atexit(void)
#define free(a)
Definition: header.h:60
PGconn * GetConnection(UserMapping *user, bool will_prep_stmt)
Definition: connection.c:97
#define NULL
Definition: c.h:226
char * dbhost
Definition: streamutil.c:38
static char * xlog_dir
Definition: pg_basebackup.c:82
static bool made_new_xlogdir
static bool fastcheckpoint
Definition: pg_basebackup.c:90
static void tablespace_list_append(const char *arg)
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:550
char * dbuser
Definition: streamutil.c:39
char * optarg
Definition: getopt.c:53
const char * strerror(int errnum)
Definition: strerror.c:19
static bool do_sync
Definition: pg_basebackup.c:92
static void verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found)
static char format
Definition: pg_basebackup.c:83
static void disconnect_and_exit(int code)
static char * replication_slot
Definition: pg_basebackup.c:96
#define _(x)
Definition: elog.c:84
static bool noclean
Definition: pg_basebackup.c:85
static int32 parse_max_rate ( char *  src)
static

Definition at line 791 of file pg_basebackup.c.

References _, MAX_RATE_UPPER, NULL, progname, and strerror().

Referenced by main().

792 {
793  double result;
794  char *after_num;
795  char *suffix = NULL;
796 
797  errno = 0;
798  result = strtod(src, &after_num);
799  if (src == after_num)
800  {
801  fprintf(stderr,
802  _("%s: transfer rate \"%s\" is not a valid value\n"),
803  progname, src);
804  exit(1);
805  }
806  if (errno != 0)
807  {
808  fprintf(stderr,
809  _("%s: invalid transfer rate \"%s\": %s\n"),
810  progname, src, strerror(errno));
811  exit(1);
812  }
813 
814  if (result <= 0)
815  {
816  /*
817  * Reject obviously wrong values here.
818  */
819  fprintf(stderr, _("%s: transfer rate must be greater than zero\n"),
820  progname);
821  exit(1);
822  }
823 
824  /*
825  * Evaluate suffix, after skipping over possible whitespace. Lack of
826  * suffix means kilobytes.
827  */
828  while (*after_num != '\0' && isspace((unsigned char) *after_num))
829  after_num++;
830 
831  if (*after_num != '\0')
832  {
833  suffix = after_num;
834  if (*after_num == 'k')
835  {
836  /* kilobyte is the expected unit. */
837  after_num++;
838  }
839  else if (*after_num == 'M')
840  {
841  after_num++;
842  result *= 1024.0;
843  }
844  }
845 
846  /* The rest can only consist of white space. */
847  while (*after_num != '\0' && isspace((unsigned char) *after_num))
848  after_num++;
849 
850  if (*after_num != '\0')
851  {
852  fprintf(stderr,
853  _("%s: invalid --max-rate unit: \"%s\"\n"),
854  progname, suffix);
855  exit(1);
856  }
857 
858  /* Valid integer? */
859  if ((uint64) result != (uint64) ((uint32) result))
860  {
861  fprintf(stderr,
862  _("%s: transfer rate \"%s\" exceeds integer range\n"),
863  progname, src);
864  exit(1);
865  }
866 
867  /*
868  * The range is checked on the server side too, but avoid the server
869  * connection if a nonsensical value was passed.
870  */
871  if (result < MAX_RATE_LOWER || result > MAX_RATE_UPPER)
872  {
873  fprintf(stderr,
874  _("%s: transfer rate \"%s\" is out of range\n"),
875  progname, src);
876  exit(1);
877  }
878 
879  return (int32) result;
880 }
const char * progname
Definition: pg_standby.c:37
signed int int32
Definition: c.h:253
#define MAX_RATE_UPPER
Definition: basebackup.h:21
unsigned int uint32
Definition: c.h:265
#define NULL
Definition: c.h:226
const char * strerror(int errnum)
Definition: strerror.c:19
#define _(x)
Definition: elog.c:84
static void progress_report ( int  tablespacenum,
const char *  filename,
bool  force 
)
static

Definition at line 705 of file pg_basebackup.c.

References INT64_FORMAT, last_progress_report, ngettext, now(), NULL, showprogress, snprintf(), tablespacecount, totaldone, totalsize, verbose, and VERBOSE_FILENAME_LENGTH.

Referenced by BaseBackup(), main(), ReceiveAndUnpackTarFile(), ReceiveTarFile(), and write_target_range().

706 {
707  int percent;
708  char totaldone_str[32];
709  char totalsize_str[32];
710  pg_time_t now;
711 
712  if (!showprogress)
713  return;
714 
715  now = time(NULL);
716  if (now == last_progress_report && !force)
717  return; /* Max once per second */
718 
720  percent = totalsize ? (int) ((totaldone / 1024) * 100 / totalsize) : 0;
721 
722  /*
723  * Avoid overflowing past 100% or the full size. This may make the total
724  * size number change as we approach the end of the backup (the estimate
725  * will always be wrong if WAL is included), but that's better than having
726  * the done column be bigger than the total.
727  */
728  if (percent > 100)
729  percent = 100;
730  if (totaldone / 1024 > totalsize)
731  totalsize = totaldone / 1024;
732 
733  /*
734  * Separate step to keep platform-dependent format code out of
735  * translatable strings. And we only test for INT64_FORMAT availability
736  * in snprintf, not fprintf.
737  */
738  snprintf(totaldone_str, sizeof(totaldone_str), INT64_FORMAT,
739  totaldone / 1024);
740  snprintf(totalsize_str, sizeof(totalsize_str), INT64_FORMAT, totalsize);
741 
742 #define VERBOSE_FILENAME_LENGTH 35
743  if (verbose)
744  {
745  if (!filename)
746 
747  /*
748  * No filename given, so clear the status line (used for last
749  * call)
750  */
751  fprintf(stderr,
752  ngettext("%*s/%s kB (100%%), %d/%d tablespace %*s",
753  "%*s/%s kB (100%%), %d/%d tablespaces %*s",
755  (int) strlen(totalsize_str),
756  totaldone_str, totalsize_str,
757  tablespacenum, tablespacecount,
758  VERBOSE_FILENAME_LENGTH + 5, "");
759  else
760  {
761  bool truncate = (strlen(filename) > VERBOSE_FILENAME_LENGTH);
762 
763  fprintf(stderr,
764  ngettext("%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)",
765  "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)",
767  (int) strlen(totalsize_str),
768  totaldone_str, totalsize_str, percent,
769  tablespacenum, tablespacecount,
770  /* Prefix with "..." if we do leading truncation */
771  truncate ? "..." : "",
774  /* Truncate filename at beginning if it's too long */
775  truncate ? filename + strlen(filename) - VERBOSE_FILENAME_LENGTH + 3 : filename);
776  }
777  }
778  else
779  fprintf(stderr,
780  ngettext("%*s/%s kB (%d%%), %d/%d tablespace",
781  "%*s/%s kB (%d%%), %d/%d tablespaces",
783  (int) strlen(totalsize_str),
784  totaldone_str, totalsize_str, percent,
785  tablespacenum, tablespacecount);
786 
787  fprintf(stderr, "\r");
788 }
int64 pg_time_t
Definition: pgtime.h:23
static pg_time_t last_progress_report
Definition: pg_basebackup.c:94
static int tablespacecount
#define VERBOSE_FILENAME_LENGTH
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
static uint64 totaldone
static uint64 totalsize
static int verbose
Definition: pg_basebackup.c:87
static bool showprogress
Definition: pg_basebackup.c:86
#define ngettext(s, p, n)
Definition: c.h:127
#define NULL
Definition: c.h:226
#define INT64_FORMAT
Definition: c.h:312
static char * filename
Definition: pg_dumpall.c:84
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1533
static bool reached_end_position ( XLogRecPtr  segendpos,
uint32  timeline,
bool  segment_finished 
)
static

Definition at line 382 of file pg_basebackup.c.

References _, bgpipe, has_xlogendptr, MemSet, NULL, progname, read, select, strerror(), and xlogendptr.

Referenced by LogStreamerMain().

384 {
385  if (!has_xlogendptr)
386  {
387 #ifndef WIN32
388  fd_set fds;
389  struct timeval tv;
390  int r;
391 
392  /*
393  * Don't have the end pointer yet - check our pipe to see if it has
394  * been sent yet.
395  */
396  FD_ZERO(&fds);
397  FD_SET(bgpipe[0], &fds);
398 
399  MemSet(&tv, 0, sizeof(tv));
400 
401  r = select(bgpipe[0] + 1, &fds, NULL, NULL, &tv);
402  if (r == 1)
403  {
404  char xlogend[64];
405  uint32 hi,
406  lo;
407 
408  MemSet(xlogend, 0, sizeof(xlogend));
409  r = read(bgpipe[0], xlogend, sizeof(xlogend) - 1);
410  if (r < 0)
411  {
412  fprintf(stderr, _("%s: could not read from ready pipe: %s\n"),
413  progname, strerror(errno));
414  exit(1);
415  }
416 
417  if (sscanf(xlogend, "%X/%X", &hi, &lo) != 2)
418  {
419  fprintf(stderr,
420  _("%s: could not parse transaction log location \"%s\"\n"),
421  progname, xlogend);
422  exit(1);
423  }
424  xlogendptr = ((uint64) hi) << 32 | lo;
425  has_xlogendptr = 1;
426 
427  /*
428  * Fall through to check if we've reached the point further
429  * already.
430  */
431  }
432  else
433  {
434  /*
435  * No data received on the pipe means we don't know the end
436  * position yet - so just say it's not time to stop yet.
437  */
438  return false;
439  }
440 #else
441 
442  /*
443  * On win32, has_xlogendptr is set by the main thread, so if it's not
444  * set here, we just go back and wait until it shows up.
445  */
446  return false;
447 #endif
448  }
449 
450  /*
451  * At this point we have an end pointer, so compare it to the current
452  * position to figure out if it's time to stop.
453  */
454  if (segendpos >= xlogendptr)
455  return true;
456 
457  /*
458  * Have end pointer, but haven't reached it yet - so tell the caller to
459  * keep streaming.
460  */
461  return false;
462 }
static int bgpipe[2]
#define MemSet(start, val, len)
Definition: c.h:853
#define select(n, r, w, e, timeout)
Definition: win32.h:384
const char * progname
Definition: pg_standby.c:37
static int has_xlogendptr
unsigned int uint32
Definition: c.h:265
#define NULL
Definition: c.h:226
static XLogRecPtr xlogendptr
const char * strerror(int errnum)
Definition: strerror.c:19
#define _(x)
Definition: elog.c:84
#define read(a, b, c)
Definition: win32.h:18
static void ReceiveAndUnpackTarFile ( PGconn conn,
PGresult res,
int  rownum 
)
static

Definition at line 1299 of file pg_basebackup.c.

References _, basedir, disconnect_and_exit(), filename, get_tablespace_mapping(), MAXPGPATH, mkdir, NULL, pg_str_endswith(), pgoff_t, PGRES_COPY_OUT, PQerrorMessage(), PQfreemem(), PQgetCopyData(), PQgetisnull(), PQgetResult(), PQgetvalue(), PQresultStatus(), progname, progress_report(), read_tar_number(), snprintf(), strerror(), strlcpy(), totaldone, writerecoveryconf, and WriteRecoveryConf().

Referenced by BaseBackup().

1300 {
1301  char current_path[MAXPGPATH];
1302  char filename[MAXPGPATH];
1303  const char *mapped_tblspc_path;
1304  pgoff_t current_len_left = 0;
1305  int current_padding = 0;
1306  bool basetablespace;
1307  char *copybuf = NULL;
1308  FILE *file = NULL;
1309 
1310  basetablespace = PQgetisnull(res, rownum, 0);
1311  if (basetablespace)
1312  strlcpy(current_path, basedir, sizeof(current_path));
1313  else
1314  strlcpy(current_path,
1315  get_tablespace_mapping(PQgetvalue(res, rownum, 1)),
1316  sizeof(current_path));
1317 
1318  /*
1319  * Get the COPY data
1320  */
1321  res = PQgetResult(conn);
1322  if (PQresultStatus(res) != PGRES_COPY_OUT)
1323  {
1324  fprintf(stderr, _("%s: could not get COPY data stream: %s"),
1325  progname, PQerrorMessage(conn));
1327  }
1328 
1329  while (1)
1330  {
1331  int r;
1332 
1333  if (copybuf != NULL)
1334  {
1335  PQfreemem(copybuf);
1336  copybuf = NULL;
1337  }
1338 
1339  r = PQgetCopyData(conn, &copybuf, 0);
1340 
1341  if (r == -1)
1342  {
1343  /*
1344  * End of chunk
1345  */
1346  if (file)
1347  fclose(file);
1348 
1349  break;
1350  }
1351  else if (r == -2)
1352  {
1353  fprintf(stderr, _("%s: could not read COPY data: %s"),
1354  progname, PQerrorMessage(conn));
1356  }
1357 
1358  if (file == NULL)
1359  {
1360  int filemode;
1361 
1362  /*
1363  * No current file, so this must be the header for a new file
1364  */
1365  if (r != 512)
1366  {
1367  fprintf(stderr, _("%s: invalid tar block header size: %d\n"),
1368  progname, r);
1370  }
1371  totaldone += 512;
1372 
1373  current_len_left = read_tar_number(&copybuf[124], 12);
1374 
1375  /* Set permissions on the file */
1376  filemode = read_tar_number(&copybuf[100], 8);
1377 
1378  /*
1379  * All files are padded up to 512 bytes
1380  */
1381  current_padding =
1382  ((current_len_left + 511) & ~511) - current_len_left;
1383 
1384  /*
1385  * First part of header is zero terminated filename
1386  */
1387  snprintf(filename, sizeof(filename), "%s/%s", current_path,
1388  copybuf);
1389  if (filename[strlen(filename) - 1] == '/')
1390  {
1391  /*
1392  * Ends in a slash means directory or symlink to directory
1393  */
1394  if (copybuf[156] == '5')
1395  {
1396  /*
1397  * Directory
1398  */
1399  filename[strlen(filename) - 1] = '\0'; /* Remove trailing slash */
1400  if (mkdir(filename, S_IRWXU) != 0)
1401  {
1402  /*
1403  * When streaming WAL, pg_wal (or pg_xlog for pre-9.6
1404  * clusters) will have been created by the wal receiver
1405  * process. Also, when transaction log directory location
1406  * was specified, pg_wal (or pg_xlog) has already been
1407  * created as a symbolic link before starting the actual
1408  * backup. So just ignore creation failures on related
1409  * directories.
1410  */
1411  if (!((pg_str_endswith(filename, "/pg_wal") ||
1412  pg_str_endswith(filename, "/pg_xlog")||
1413  pg_str_endswith(filename, "/archive_status")) &&
1414  errno == EEXIST))
1415  {
1416  fprintf(stderr,
1417  _("%s: could not create directory \"%s\": %s\n"),
1418  progname, filename, strerror(errno));
1420  }
1421  }
1422 #ifndef WIN32
1423  if (chmod(filename, (mode_t) filemode))
1424  fprintf(stderr,
1425  _("%s: could not set permissions on directory \"%s\": %s\n"),
1426  progname, filename, strerror(errno));
1427 #endif
1428  }
1429  else if (copybuf[156] == '2')
1430  {
1431  /*
1432  * Symbolic link
1433  *
1434  * It's most likely a link in pg_tblspc directory, to the
1435  * location of a tablespace. Apply any tablespace mapping
1436  * given on the command line (--tablespace-mapping). (We
1437  * blindly apply the mapping without checking that the
1438  * link really is inside pg_tblspc. We don't expect there
1439  * to be other symlinks in a data directory, but if there
1440  * are, you can call it an undocumented feature that you
1441  * can map them too.)
1442  */
1443  filename[strlen(filename) - 1] = '\0'; /* Remove trailing slash */
1444 
1445  mapped_tblspc_path = get_tablespace_mapping(&copybuf[157]);
1446  if (symlink(mapped_tblspc_path, filename) != 0)
1447  {
1448  fprintf(stderr,
1449  _("%s: could not create symbolic link from \"%s\" to \"%s\": %s\n"),
1450  progname, filename, mapped_tblspc_path,
1451  strerror(errno));
1453  }
1454  }
1455  else
1456  {
1457  fprintf(stderr,
1458  _("%s: unrecognized link indicator \"%c\"\n"),
1459  progname, copybuf[156]);
1461  }
1462  continue; /* directory or link handled */
1463  }
1464 
1465  /*
1466  * regular file
1467  */
1468  file = fopen(filename, "wb");
1469  if (!file)
1470  {
1471  fprintf(stderr, _("%s: could not create file \"%s\": %s\n"),
1472  progname, filename, strerror(errno));
1474  }
1475 
1476 #ifndef WIN32
1477  if (chmod(filename, (mode_t) filemode))
1478  fprintf(stderr, _("%s: could not set permissions on file \"%s\": %s\n"),
1479  progname, filename, strerror(errno));
1480 #endif
1481 
1482  if (current_len_left == 0)
1483  {
1484  /*
1485  * Done with this file, next one will be a new tar header
1486  */
1487  fclose(file);
1488  file = NULL;
1489  continue;
1490  }
1491  } /* new file */
1492  else
1493  {
1494  /*
1495  * Continuing blocks in existing file
1496  */
1497  if (current_len_left == 0 && r == current_padding)
1498  {
1499  /*
1500  * Received the padding block for this file, ignore it and
1501  * close the file, then move on to the next tar header.
1502  */
1503  fclose(file);
1504  file = NULL;
1505  totaldone += r;
1506  continue;
1507  }
1508 
1509  if (fwrite(copybuf, r, 1, file) != 1)
1510  {
1511  fprintf(stderr, _("%s: could not write to file \"%s\": %s\n"),
1512  progname, filename, strerror(errno));
1514  }
1515  totaldone += r;
1516  progress_report(rownum, filename, false);
1517 
1518  current_len_left -= r;
1519  if (current_len_left == 0 && current_padding == 0)
1520  {
1521  /*
1522  * Received the last block, and there is no padding to be
1523  * expected. Close the file and move on to the next tar
1524  * header.
1525  */
1526  fclose(file);
1527  file = NULL;
1528  continue;
1529  }
1530  } /* continuing data in existing file */
1531  } /* loop over all data blocks */
1532  progress_report(rownum, filename, true);
1533 
1534  if (file != NULL)
1535  {
1536  fprintf(stderr,
1537  _("%s: COPY stream ended before last file was finished\n"),
1538  progname);
1540  }
1541 
1542  if (copybuf != NULL)
1543  PQfreemem(copybuf);
1544 
1545  if (basetablespace && writerecoveryconf)
1547 
1548  /*
1549  * No data is synced here, everything is done for all tablespaces at the
1550  * end.
1551  */
1552 }
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:5960
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
bool pg_str_endswith(const char *str, const char *end)
Definition: string.c:31
uint64 read_tar_number(const char *s, int len)
Definition: tar.c:56
#define mkdir(a, b)
Definition: win32.h:65
static bool writerecoveryconf
Definition: pg_basebackup.c:91
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
const char * progname
Definition: pg_standby.c:37
static char * basedir
Definition: pg_basebackup.c:80
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2596
int PQgetCopyData(PGconn *conn, char **buffer, int async)
Definition: fe-exec.c:2377
#define MAXPGPATH
static uint64 totaldone
static const char * get_tablespace_mapping(const char *dir)
static void progress_report(int tablespacenum, const char *filename, bool force)
#define pgoff_t
Definition: win32.h:241
static void WriteRecoveryConf(void)
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define NULL
Definition: c.h:226
static char * filename
Definition: pg_dumpall.c:84
const char * strerror(int errnum)
Definition: strerror.c:19
static void disconnect_and_exit(int code)
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3092
#define _(x)
Definition: elog.c:84
void PQfreemem(void *ptr)
Definition: fe-exec.c:3200
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:1702
static void ReceiveTarFile ( PGconn conn,
PGresult res,
int  rownum 
)
static

Definition at line 932 of file pg_basebackup.c.

References _, basedir, compresslevel, PQExpBufferData::data, disconnect_and_exit(), do_sync, filename, fsync_fname(), header(), PQExpBufferData::len, MAXPGPATH, MemSet, NULL, pgoff_t, PGRES_COPY_OUT, PQerrorMessage(), PQfreemem(), PQgetCopyData(), PQgetisnull(), PQgetResult(), PQgetvalue(), PQresultStatus(), progname, progress_report(), read_tar_number(), snprintf(), strerror(), tarCreateHeader(), totaldone, WRITE_TAR_DATA, and writerecoveryconf.

Referenced by BaseBackup().

933 {
934  char filename[MAXPGPATH];
935  char *copybuf = NULL;
936  FILE *tarfile = NULL;
937  char tarhdr[512];
938  bool basetablespace = PQgetisnull(res, rownum, 0);
939  bool in_tarhdr = true;
940  bool skip_file = false;
941  size_t tarhdrsz = 0;
942  pgoff_t filesz = 0;
943 
944 #ifdef HAVE_LIBZ
945  gzFile ztarfile = NULL;
946 #endif
947 
948  if (basetablespace)
949  {
950  /*
951  * Base tablespaces
952  */
953  if (strcmp(basedir, "-") == 0)
954  {
955 #ifdef HAVE_LIBZ
956  if (compresslevel != 0)
957  {
958  ztarfile = gzdopen(dup(fileno(stdout)), "wb");
959  if (gzsetparams(ztarfile, compresslevel,
960  Z_DEFAULT_STRATEGY) != Z_OK)
961  {
962  fprintf(stderr,
963  _("%s: could not set compression level %d: %s\n"),
964  progname, compresslevel, get_gz_error(ztarfile));
966  }
967  }
968  else
969 #endif
970  tarfile = stdout;
971  strcpy(filename, "-");
972  }
973  else
974  {
975 #ifdef HAVE_LIBZ
976  if (compresslevel != 0)
977  {
978  snprintf(filename, sizeof(filename), "%s/base.tar.gz", basedir);
979  ztarfile = gzopen(filename, "wb");
980  if (gzsetparams(ztarfile, compresslevel,
981  Z_DEFAULT_STRATEGY) != Z_OK)
982  {
983  fprintf(stderr,
984  _("%s: could not set compression level %d: %s\n"),
985  progname, compresslevel, get_gz_error(ztarfile));
987  }
988  }
989  else
990 #endif
991  {
992  snprintf(filename, sizeof(filename), "%s/base.tar", basedir);
993  tarfile = fopen(filename, "wb");
994  }
995  }
996  }
997  else
998  {
999  /*
1000  * Specific tablespace
1001  */
1002 #ifdef HAVE_LIBZ
1003  if (compresslevel != 0)
1004  {
1005  snprintf(filename, sizeof(filename), "%s/%s.tar.gz", basedir,
1006  PQgetvalue(res, rownum, 0));
1007  ztarfile = gzopen(filename, "wb");
1008  if (gzsetparams(ztarfile, compresslevel,
1009  Z_DEFAULT_STRATEGY) != Z_OK)
1010  {
1011  fprintf(stderr,
1012  _("%s: could not set compression level %d: %s\n"),
1013  progname, compresslevel, get_gz_error(ztarfile));
1015  }
1016  }
1017  else
1018 #endif
1019  {
1020  snprintf(filename, sizeof(filename), "%s/%s.tar", basedir,
1021  PQgetvalue(res, rownum, 0));
1022  tarfile = fopen(filename, "wb");
1023  }
1024  }
1025 
1026 #ifdef HAVE_LIBZ
1027  if (compresslevel != 0)
1028  {
1029  if (!ztarfile)
1030  {
1031  /* Compression is in use */
1032  fprintf(stderr,
1033  _("%s: could not create compressed file \"%s\": %s\n"),
1034  progname, filename, get_gz_error(ztarfile));
1036  }
1037  }
1038  else
1039 #endif
1040  {
1041  /* Either no zlib support, or zlib support but compresslevel = 0 */
1042  if (!tarfile)
1043  {
1044  fprintf(stderr, _("%s: could not create file \"%s\": %s\n"),
1045  progname, filename, strerror(errno));
1047  }
1048  }
1049 
1050  /*
1051  * Get the COPY data stream
1052  */
1053  res = PQgetResult(conn);
1054  if (PQresultStatus(res) != PGRES_COPY_OUT)
1055  {
1056  fprintf(stderr, _("%s: could not get COPY data stream: %s"),
1057  progname, PQerrorMessage(conn));
1059  }
1060 
1061  while (1)
1062  {
1063  int r;
1064 
1065  if (copybuf != NULL)
1066  {
1067  PQfreemem(copybuf);
1068  copybuf = NULL;
1069  }
1070 
1071  r = PQgetCopyData(conn, &copybuf, 0);
1072  if (r == -1)
1073  {
1074  /*
1075  * End of chunk. If requested, and this is the base tablespace,
1076  * write recovery.conf into the tarfile. When done, close the file
1077  * (but not stdout).
1078  *
1079  * Also, write two completely empty blocks at the end of the tar
1080  * file, as required by some tar programs.
1081  */
1082  char zerobuf[1024];
1083 
1084  MemSet(zerobuf, 0, sizeof(zerobuf));
1085 
1086  if (basetablespace && writerecoveryconf)
1087  {
1088  char header[512];
1089  int padding;
1090 
1091  tarCreateHeader(header, "recovery.conf", NULL,
1093  0600, 04000, 02000,
1094  time(NULL));
1095 
1096  padding = ((recoveryconfcontents->len + 511) & ~511) - recoveryconfcontents->len;
1097 
1098  WRITE_TAR_DATA(header, sizeof(header));
1100  if (padding)
1101  WRITE_TAR_DATA(zerobuf, padding);
1102  }
1103 
1104  /* 2 * 512 bytes empty data at end of file */
1105  WRITE_TAR_DATA(zerobuf, sizeof(zerobuf));
1106 
1107 #ifdef HAVE_LIBZ
1108  if (ztarfile != NULL)
1109  {
1110  if (gzclose(ztarfile) != 0)
1111  {
1112  fprintf(stderr,
1113  _("%s: could not close compressed file \"%s\": %s\n"),
1114  progname, filename, get_gz_error(ztarfile));
1116  }
1117  }
1118  else
1119 #endif
1120  {
1121  if (strcmp(basedir, "-") != 0)
1122  {
1123  if (fclose(tarfile) != 0)
1124  {
1125  fprintf(stderr,
1126  _("%s: could not close file \"%s\": %s\n"),
1127  progname, filename, strerror(errno));
1129  }
1130  }
1131  }
1132 
1133  break;
1134  }
1135  else if (r == -2)
1136  {
1137  fprintf(stderr, _("%s: could not read COPY data: %s"),
1138  progname, PQerrorMessage(conn));
1140  }
1141 
1142  if (!writerecoveryconf || !basetablespace)
1143  {
1144  /*
1145  * When not writing recovery.conf, or when not working on the base
1146  * tablespace, we never have to look for an existing recovery.conf
1147  * file in the stream.
1148  */
1149  WRITE_TAR_DATA(copybuf, r);
1150  }
1151  else
1152  {
1153  /*
1154  * Look for a recovery.conf in the existing tar stream. If it's
1155  * there, we must skip it so we can later overwrite it with our
1156  * own version of the file.
1157  *
1158  * To do this, we have to process the individual files inside the
1159  * TAR stream. The stream consists of a header and zero or more
1160  * chunks, all 512 bytes long. The stream from the server is
1161  * broken up into smaller pieces, so we have to track the size of
1162  * the files to find the next header structure.
1163  */
1164  int rr = r;
1165  int pos = 0;
1166 
1167  while (rr > 0)
1168  {
1169  if (in_tarhdr)
1170  {
1171  /*
1172  * We're currently reading a header structure inside the
1173  * TAR stream, i.e. the file metadata.
1174  */
1175  if (tarhdrsz < 512)
1176  {
1177  /*
1178  * Copy the header structure into tarhdr in case the
1179  * header is not aligned to 512 bytes or it's not
1180  * returned in whole by the last PQgetCopyData call.
1181  */
1182  int hdrleft;
1183  int bytes2copy;
1184 
1185  hdrleft = 512 - tarhdrsz;
1186  bytes2copy = (rr > hdrleft ? hdrleft : rr);
1187 
1188  memcpy(&tarhdr[tarhdrsz], copybuf + pos, bytes2copy);
1189 
1190  rr -= bytes2copy;
1191  pos += bytes2copy;
1192  tarhdrsz += bytes2copy;
1193  }
1194  else
1195  {
1196  /*
1197  * We have the complete header structure in tarhdr,
1198  * look at the file metadata: - the subsequent file
1199  * contents have to be skipped if the filename is
1200  * recovery.conf - find out the size of the file
1201  * padded to the next multiple of 512
1202  */
1203  int padding;
1204 
1205  skip_file = (strcmp(&tarhdr[0], "recovery.conf") == 0);
1206 
1207  filesz = read_tar_number(&tarhdr[124], 12);
1208 
1209  padding = ((filesz + 511) & ~511) - filesz;
1210  filesz += padding;
1211 
1212  /* Next part is the file, not the header */
1213  in_tarhdr = false;
1214 
1215  /*
1216  * If we're not skipping the file, write the tar
1217  * header unmodified.
1218  */
1219  if (!skip_file)
1220  WRITE_TAR_DATA(tarhdr, 512);
1221  }
1222  }
1223  else
1224  {
1225  /*
1226  * We're processing a file's contents.
1227  */
1228  if (filesz > 0)
1229  {
1230  /*
1231  * We still have data to read (and possibly write).
1232  */
1233  int bytes2write;
1234 
1235  bytes2write = (filesz > rr ? rr : filesz);
1236 
1237  if (!skip_file)
1238  WRITE_TAR_DATA(copybuf + pos, bytes2write);
1239 
1240  rr -= bytes2write;
1241  pos += bytes2write;
1242  filesz -= bytes2write;
1243  }
1244  else
1245  {
1246  /*
1247  * No more data in the current file, the next piece of
1248  * data (if any) will be a new file header structure.
1249  */
1250  in_tarhdr = true;
1251  skip_file = false;
1252  tarhdrsz = 0;
1253  filesz = 0;
1254  }
1255  }
1256  }
1257  }
1258  totaldone += r;
1259  progress_report(rownum, filename, false);
1260  } /* while (1) */
1261  progress_report(rownum, filename, true);
1262 
1263  if (copybuf != NULL)
1264  PQfreemem(copybuf);
1265 
1266  /* sync the resulting tar file, errors are not considered fatal */
1267  if (do_sync && strcmp(basedir, "-") != 0)
1268  (void) fsync_fname(filename, false, progname);
1269 }
static PQExpBuffer recoveryconfcontents
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:5960
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
uint64 read_tar_number(const char *s, int len)
Definition: tar.c:56
void fsync_fname(const char *fname, bool isdir)
Definition: fd.c:567
static bool writerecoveryconf
Definition: pg_basebackup.c:91
static int compresslevel
Definition: pg_basebackup.c:88
#define MemSet(start, val, len)
Definition: c.h:853
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
const char * progname
Definition: pg_standby.c:37
static char * basedir
Definition: pg_basebackup.c:80
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2596
int PQgetCopyData(PGconn *conn, char **buffer, int async)
Definition: fe-exec.c:2377
#define MAXPGPATH
static uint64 totaldone
static void progress_report(int tablespacenum, const char *filename, bool force)
enum tarError tarCreateHeader(char *h, const char *filename, const char *linktarget, pgoff_t size, mode_t mode, uid_t uid, gid_t gid, time_t mtime)
Definition: tar.c:112
#define pgoff_t
Definition: win32.h:241
#define NULL
Definition: c.h:226
static void header(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:205
#define WRITE_TAR_DATA(buf, sz)
static char * filename
Definition: pg_dumpall.c:84
const char * strerror(int errnum)
Definition: strerror.c:19
static bool do_sync
Definition: pg_basebackup.c:92
static void disconnect_and_exit(int code)
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3092
#define _(x)
Definition: elog.c:84
void PQfreemem(void *ptr)
Definition: fe-exec.c:3200
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:1702
static void StartLogStreamer ( char *  startpos,
uint32  timeline,
char *  sysidentifier 
)
static

Definition at line 535 of file pg_basebackup.c.

References _, basedir, bgchild, logstreamer_param::bgconn, bgpipe, conn, disconnect_and_exit(), format, GetConnection(), LogStreamerMain(), MAXPGPATH, MINIMUM_VERSION_FOR_PG_WAL, MINIMUM_VERSION_FOR_TEMP_SLOTS, NULL, pg_malloc0(), pg_mkdir_p(), PQserverVersion(), progname, snprintf(), logstreamer_param::startptr, strerror(), logstreamer_param::sysidentifier, temp_replication_slot, logstreamer_param::temp_slot, logstreamer_param::timeline, and logstreamer_param::xlog.

Referenced by BaseBackup().

536 {
537  logstreamer_param *param;
538  uint32 hi,
539  lo;
540  char statusdir[MAXPGPATH];
541 
542  param = pg_malloc0(sizeof(logstreamer_param));
543  param->timeline = timeline;
544  param->sysidentifier = sysidentifier;
545 
546  /* Convert the starting position */
547  if (sscanf(startpos, "%X/%X", &hi, &lo) != 2)
548  {
549  fprintf(stderr,
550  _("%s: could not parse transaction log location \"%s\"\n"),
551  progname, startpos);
553  }
554  param->startptr = ((uint64) hi) << 32 | lo;
555  /* Round off to even segment position */
556  param->startptr -= param->startptr % XLOG_SEG_SIZE;
557 
558 #ifndef WIN32
559  /* Create our background pipe */
560  if (pipe(bgpipe) < 0)
561  {
562  fprintf(stderr,
563  _("%s: could not create pipe for background process: %s\n"),
564  progname, strerror(errno));
566  }
567 #endif
568 
569  /* Get a second connection */
570  param->bgconn = GetConnection();
571  if (!param->bgconn)
572  /* Error message already written in GetConnection() */
573  exit(1);
574 
575  /* In post-10 cluster, pg_xlog has been renamed to pg_wal */
576  snprintf(param->xlog, sizeof(param->xlog), "%s/%s",
577  basedir,
579  "pg_xlog" : "pg_wal");
580 
581  /* Temporary replication slots are only supported in 10 and newer */
583  param->temp_slot = false;
584  else
586 
587  if (format == 'p')
588  {
589  /*
590  * Create pg_wal/archive_status or pg_xlog/archive_status (and thus
591  * pg_wal or pg_xlog) depending on the target server so we can write to
592  * basedir/pg_wal or basedir/pg_xlog as the directory entry in the tar
593  * file may arrive later.
594  */
595  snprintf(statusdir, sizeof(statusdir), "%s/%s/archive_status",
596  basedir,
598  "pg_xlog" : "pg_wal");
599 
600  if (pg_mkdir_p(statusdir, S_IRWXU) != 0 && errno != EEXIST)
601  {
602  fprintf(stderr,
603  _("%s: could not create directory \"%s\": %s\n"),
604  progname, statusdir, strerror(errno));
606  }
607  }
608 
609  /*
610  * Start a child process and tell it to start streaming. On Unix, this is
611  * a fork(). On Windows, we create a thread.
612  */
613 #ifndef WIN32
614  bgchild = fork();
615  if (bgchild == 0)
616  {
617  /* in child process */
618  exit(LogStreamerMain(param));
619  }
620  else if (bgchild < 0)
621  {
622  fprintf(stderr, _("%s: could not create background process: %s\n"),
623  progname, strerror(errno));
625  }
626 
627  /*
628  * Else we are in the parent process and all is well.
629  */
630 #else /* WIN32 */
631  bgchild = _beginthreadex(NULL, 0, (void *) LogStreamerMain, param, 0, NULL);
632  if (bgchild == 0)
633  {
634  fprintf(stderr, _("%s: could not create background thread: %s\n"),
635  progname, strerror(errno));
637  }
638 #endif
639 }
static int bgpipe[2]
int pg_mkdir_p(char *path, int omode)
Definition: pgmkdirp.c:57
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
int PQserverVersion(const PGconn *conn)
Definition: fe-connect.c:5950
const char * progname
Definition: pg_standby.c:37
static char * basedir
Definition: pg_basebackup.c:80
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
PGconn * conn
Definition: streamutil.c:45
#define MAXPGPATH
#define MINIMUM_VERSION_FOR_PG_WAL
Definition: pg_basebackup.c:62
unsigned int uint32
Definition: c.h:265
XLogRecPtr startptr
static bool temp_replication_slot
Definition: pg_basebackup.c:97
PGconn * GetConnection(UserMapping *user, bool will_prep_stmt)
Definition: connection.c:97
#define NULL
Definition: c.h:226
static XLogRecPtr startpos
static pid_t bgchild
const char * strerror(int errnum)
Definition: strerror.c:19
static char format
Definition: pg_basebackup.c:83
static void disconnect_and_exit(int code)
static int LogStreamerMain(logstreamer_param *param)
#define _(x)
Definition: elog.c:84
#define MINIMUM_VERSION_FOR_TEMP_SLOTS
Definition: pg_basebackup.c:67
char xlog[MAXPGPATH]
static void tablespace_list_append ( const char *  arg)
static

Definition at line 241 of file pg_basebackup.c.

References _, canonicalize_path(), TablespaceList::head, is_absolute_path, MAXPGPATH, TablespaceListCell::new_dir, TablespaceListCell::next, TablespaceListCell::old_dir, pg_malloc0(), progname, and TablespaceList::tail.

Referenced by main().

242 {
244  char *dst;
245  char *dst_ptr;
246  const char *arg_ptr;
247 
248  dst_ptr = dst = cell->old_dir;
249  for (arg_ptr = arg; *arg_ptr; arg_ptr++)
250  {
251  if (dst_ptr - dst >= MAXPGPATH)
252  {
253  fprintf(stderr, _("%s: directory name too long\n"), progname);
254  exit(1);
255  }
256 
257  if (*arg_ptr == '\\' && *(arg_ptr + 1) == '=')
258  ; /* skip backslash escaping = */
259  else if (*arg_ptr == '=' && (arg_ptr == arg || *(arg_ptr - 1) != '\\'))
260  {
261  if (*cell->new_dir)
262  {
263  fprintf(stderr, _("%s: multiple \"=\" signs in tablespace mapping\n"), progname);
264  exit(1);
265  }
266  else
267  dst = dst_ptr = cell->new_dir;
268  }
269  else
270  *dst_ptr++ = *arg_ptr;
271  }
272 
273  if (!*cell->old_dir || !*cell->new_dir)
274  {
275  fprintf(stderr,
276  _("%s: invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"\n"),
277  progname, arg);
278  exit(1);
279  }
280 
281  /*
282  * This check isn't absolutely necessary. But all tablespaces are created
283  * with absolute directories, so specifying a non-absolute path here would
284  * just never match, possibly confusing users. It's also good to be
285  * consistent with the new_dir check.
286  */
287  if (!is_absolute_path(cell->old_dir))
288  {
289  fprintf(stderr, _("%s: old directory is not an absolute path in tablespace mapping: %s\n"),
290  progname, cell->old_dir);
291  exit(1);
292  }
293 
294  if (!is_absolute_path(cell->new_dir))
295  {
296  fprintf(stderr, _("%s: new directory is not an absolute path in tablespace mapping: %s\n"),
297  progname, cell->new_dir);
298  exit(1);
299  }
300 
301  canonicalize_path(cell->old_dir);
302  canonicalize_path(cell->new_dir);
303 
304  if (tablespace_dirs.tail)
305  tablespace_dirs.tail->next = cell;
306  else
307  tablespace_dirs.head = cell;
308  tablespace_dirs.tail = cell;
309 }
static TablespaceList tablespace_dirs
Definition: pg_basebackup.c:81
char old_dir[MAXPGPATH]
Definition: pg_basebackup.c:48
void canonicalize_path(char *path)
Definition: path.c:254
char new_dir[MAXPGPATH]
Definition: pg_basebackup.c:49
const char * progname
Definition: pg_standby.c:37
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
#define MAXPGPATH
#define is_absolute_path(filename)
Definition: port.h:77
struct TablespaceListCell * next
Definition: pg_basebackup.c:47
TablespaceListCell * tail
Definition: pg_basebackup.c:55
TablespaceListCell * head
Definition: pg_basebackup.c:54
void * arg
#define _(x)
Definition: elog.c:84
static void usage ( void  )
static

Definition at line 328 of file pg_basebackup.c.

References _, and progname.

Referenced by main().

329 {
330  printf(_("%s takes a base backup of a running PostgreSQL server.\n\n"),
331  progname);
332  printf(_("Usage:\n"));
333  printf(_(" %s [OPTION]...\n"), progname);
334  printf(_("\nOptions controlling the output:\n"));
335  printf(_(" -D, --pgdata=DIRECTORY receive base backup into directory\n"));
336  printf(_(" -F, --format=p|t output format (plain (default), tar)\n"));
337  printf(_(" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n"
338  " (in kB/s, or use suffix \"k\" or \"M\")\n"));
339  printf(_(" -R, --write-recovery-conf\n"
340  " write recovery.conf for replication\n"));
341  printf(_(" -S, --slot=SLOTNAME replication slot to use\n"));
342  printf(_(" --no-slot prevent creation of temporary replication slot\n"));
343  printf(_(" -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
344  " relocate tablespace in OLDDIR to NEWDIR\n"));
345  printf(_(" -X, --wal-method=none|fetch|stream\n"
346  " include required WAL files with specified method\n"));
347  printf(_(" --waldir=WALDIR location for the transaction log directory\n"));
348  printf(_(" -z, --gzip compress tar output\n"));
349  printf(_(" -Z, --compress=0-9 compress tar output with given compression level\n"));
350  printf(_("\nGeneral options:\n"));
351  printf(_(" -c, --checkpoint=fast|spread\n"
352  " set fast or spread checkpointing\n"));
353  printf(_(" -l, --label=LABEL set backup label\n"));
354  printf(_(" -n, --no-clean do not clean up after errors\n"));
355  printf(_(" -N, --no-sync do not wait for changes to be written safely to disk\n"));
356  printf(_(" -P, --progress show progress information\n"));
357  printf(_(" -v, --verbose output verbose messages\n"));
358  printf(_(" -V, --version output version information, then exit\n"));
359  printf(_(" -?, --help show this help, then exit\n"));
360  printf(_("\nConnection options:\n"));
361  printf(_(" -d, --dbname=CONNSTR connection string\n"));
362  printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
363  printf(_(" -p, --port=PORT database server port number\n"));
364  printf(_(" -s, --status-interval=INTERVAL\n"
365  " time between status packets sent to server (in seconds)\n"));
366  printf(_(" -U, --username=NAME connect as specified database user\n"));
367  printf(_(" -w, --no-password never prompt for password\n"));
368  printf(_(" -W, --password force password prompt (should happen automatically)\n"));
369  printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
370 }
const char * progname
Definition: pg_standby.c:37
#define _(x)
Definition: elog.c:84
static void verify_dir_is_empty_or_create ( char *  dirname,
bool created,
bool found 
)
static

Definition at line 647 of file pg_basebackup.c.

References _, disconnect_and_exit(), pg_check_dir(), pg_mkdir_p(), progname, and strerror().

Referenced by BaseBackup(), and main().

648 {
649  switch (pg_check_dir(dirname))
650  {
651  case 0:
652 
653  /*
654  * Does not exist, so create
655  */
656  if (pg_mkdir_p(dirname, S_IRWXU) == -1)
657  {
658  fprintf(stderr,
659  _("%s: could not create directory \"%s\": %s\n"),
660  progname, dirname, strerror(errno));
662  }
663  if (created)
664  *created = true;
665  return;
666  case 1:
667 
668  /*
669  * Exists, empty
670  */
671  if (found)
672  *found = true;
673  return;
674  case 2:
675  case 3:
676  case 4:
677 
678  /*
679  * Exists, not empty
680  */
681  fprintf(stderr,
682  _("%s: directory \"%s\" exists but is not empty\n"),
683  progname, dirname);
685  case -1:
686 
687  /*
688  * Access problem
689  */
690  fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"),
691  progname, dirname, strerror(errno));
693  }
694 }
int pg_mkdir_p(char *path, int omode)
Definition: pgmkdirp.c:57
const char * progname
Definition: pg_standby.c:37
int pg_check_dir(const char *dir)
Definition: pgcheckdir.c:31
const char * strerror(int errnum)
Definition: strerror.c:19
static void disconnect_and_exit(int code)
#define _(x)
Definition: elog.c:84
static void WriteRecoveryConf ( void  )
static

Definition at line 1660 of file pg_basebackup.c.

References _, basedir, PQExpBufferData::data, disconnect_and_exit(), filename, PQExpBufferData::len, MAXPGPATH, NULL, progname, and strerror().

Referenced by ReceiveAndUnpackTarFile().

1661 {
1662  char filename[MAXPGPATH];
1663  FILE *cf;
1664 
1665  sprintf(filename, "%s/recovery.conf", basedir);
1666 
1667  cf = fopen(filename, "w");
1668  if (cf == NULL)
1669  {
1670  fprintf(stderr, _("%s: could not create file \"%s\": %s\n"), progname, filename, strerror(errno));
1672  }
1673 
1674  if (fwrite(recoveryconfcontents->data, recoveryconfcontents->len, 1, cf) != 1)
1675  {
1676  fprintf(stderr,
1677  _("%s: could not write to file \"%s\": %s\n"),
1678  progname, filename, strerror(errno));
1680  }
1681 
1682  fclose(cf);
1683 }
static PQExpBuffer recoveryconfcontents
const char * progname
Definition: pg_standby.c:37
static char * basedir
Definition: pg_basebackup.c:80
#define MAXPGPATH
#define NULL
Definition: c.h:226
static char * filename
Definition: pg_dumpall.c:84
const char * strerror(int errnum)
Definition: strerror.c:19
static void disconnect_and_exit(int code)
#define _(x)
Definition: elog.c:84
static void writeTarData ( FILE *  tarfile,
char *  buf,
int  r,
char *  current_file 
)
static

Definition at line 886 of file pg_basebackup.c.

References _, disconnect_and_exit(), NULL, progname, and strerror().

891 {
892 #ifdef HAVE_LIBZ
893  if (ztarfile != NULL)
894  {
895  if (gzwrite(ztarfile, buf, r) != r)
896  {
897  fprintf(stderr,
898  _("%s: could not write to compressed file \"%s\": %s\n"),
899  progname, current_file, get_gz_error(ztarfile));
901  }
902  }
903  else
904 #endif
905  {
906  if (fwrite(buf, r, 1, tarfile) != 1)
907  {
908  fprintf(stderr, _("%s: could not write to file \"%s\": %s\n"),
909  progname, current_file, strerror(errno));
911  }
912  }
913 }
const char * progname
Definition: pg_standby.c:37
static char * buf
Definition: pg_test_fsync.c:65
#define NULL
Definition: c.h:226
const char * strerror(int errnum)
Definition: strerror.c:19
static void disconnect_and_exit(int code)
#define _(x)
Definition: elog.c:84

Variable Documentation

pid_t bgchild = -1
static

Definition at line 118 of file pg_basebackup.c.

Referenced by BaseBackup(), disconnect_and_exit(), and StartLogStreamer().

int bgpipe[2] = {-1, -1}
static

Definition at line 114 of file pg_basebackup.c.

Referenced by BaseBackup(), reached_end_position(), and StartLogStreamer().

int compresslevel = 0
static

Definition at line 88 of file pg_basebackup.c.

Referenced by LogStreamerMain(), main(), and ReceiveTarFile().

bool do_sync = true
static

Definition at line 92 of file pg_basebackup.c.

Referenced by BaseBackup(), LogStreamerMain(), main(), and ReceiveTarFile().

bool fastcheckpoint = false
static

Definition at line 90 of file pg_basebackup.c.

Referenced by BaseBackup(), and main().

bool found_existing_pgdata = false
static

Definition at line 101 of file pg_basebackup.c.

Referenced by cleanup_directories_atexit(), and main().

bool found_existing_xlogdir = false
static

Definition at line 103 of file pg_basebackup.c.

Referenced by cleanup_directories_atexit(), and main().

bool found_tablespace_dirs = false
static

Definition at line 105 of file pg_basebackup.c.

Referenced by BaseBackup(), and cleanup_directories_atexit().

int has_xlogendptr = 0
static

Definition at line 125 of file pg_basebackup.c.

Referenced by BaseBackup(), and reached_end_position().

bool in_log_streamer = false
static

Definition at line 119 of file pg_basebackup.c.

Referenced by cleanup_directories_atexit(), and LogStreamerMain().

IncludeWal includewal = STREAM_WAL
static

Definition at line 89 of file pg_basebackup.c.

Referenced by BaseBackup(), and main().

pg_time_t last_progress_report = 0
static

Definition at line 94 of file pg_basebackup.c.

Referenced by progress_report().

bool made_new_pgdata = false
static

Definition at line 100 of file pg_basebackup.c.

Referenced by cleanup_directories_atexit(), and main().

bool made_new_xlogdir = false
static

Definition at line 102 of file pg_basebackup.c.

Referenced by cleanup_directories_atexit(), and main().

bool made_tablespace_dirs = false
static

Definition at line 104 of file pg_basebackup.c.

Referenced by BaseBackup(), and cleanup_directories_atexit().

int32 maxrate = 0
static

Definition at line 95 of file pg_basebackup.c.

Referenced by BaseBackup(), main(), and parse_basebackup_options().

bool noclean = false
static

Definition at line 85 of file pg_basebackup.c.

Referenced by cleanup_directories_atexit(), and main().

PQExpBuffer recoveryconfcontents = NULL
static

Definition at line 131 of file pg_basebackup.c.

char* replication_slot = NULL
static

Definition at line 96 of file pg_basebackup.c.

Referenced by GenerateRecoveryConf(), LogStreamerMain(), and main().

bool showprogress = false
static

Definition at line 86 of file pg_basebackup.c.

Referenced by BaseBackup(), main(), pg_attribute_printf(), and progress_report().

int standby_message_timeout = 10 * 1000
static

Definition at line 93 of file pg_basebackup.c.

Referenced by LogStreamerMain(), and main().

TablespaceList tablespace_dirs = {NULL, NULL}
static

Definition at line 81 of file pg_basebackup.c.

int tablespacecount
static

Definition at line 110 of file pg_basebackup.c.

Referenced by BaseBackup(), and progress_report().

bool temp_replication_slot = true
static

Definition at line 97 of file pg_basebackup.c.

Referenced by main(), and StartLogStreamer().

uint64 totaldone
static
int verbose = 0
static
bool writerecoveryconf = false
static

Definition at line 91 of file pg_basebackup.c.

Referenced by BaseBackup(), main(), ReceiveAndUnpackTarFile(), and ReceiveTarFile().

char* xlog_dir = ""
static

Definition at line 82 of file pg_basebackup.c.

Referenced by cleanup_directories_atexit(), and main().

XLogRecPtr xlogendptr
static

Definition at line 122 of file pg_basebackup.c.

Referenced by BaseBackup(), and reached_end_position().