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/wait.h>
#include <signal.h>
#include <time.h>
#include "access/xlog_internal.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 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 = NULL
 
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 create_slot = false
 
static bool no_slot = false
 
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 MINIMUM_VERSION_FOR_PG_WAL   100000

Definition at line 60 of file pg_basebackup.c.

Referenced by main(), and StartLogStreamer().

#define MINIMUM_VERSION_FOR_TEMP_SLOTS   100000

Definition at line 65 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 940 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 70 of file pg_basebackup.c.

71 {
72  NO_WAL,
73  FETCH_WAL,
75 } IncludeWal;
IncludeWal
Definition: pg_basebackup.c:70

Function Documentation

static void BaseBackup ( void  )
static

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

1714 {
1715  PGresult *res;
1716  char *sysidentifier;
1717  TimeLineID latesttli;
1718  TimeLineID starttli;
1719  char *basebkp;
1720  char escaped_label[MAXPGPATH];
1721  char *maxrate_clause = NULL;
1722  int i;
1723  char xlogstart[64];
1724  char xlogend[64];
1725  int minServerMajor,
1726  maxServerMajor;
1727  int serverVersion,
1728  serverMajor;
1729 
1730  Assert(conn != NULL);
1731 
1732  /*
1733  * Check server version. BASE_BACKUP command was introduced in 9.1, so we
1734  * can't work with servers older than 9.1.
1735  */
1736  minServerMajor = 901;
1737  maxServerMajor = PG_VERSION_NUM / 100;
1738  serverVersion = PQserverVersion(conn);
1739  serverMajor = serverVersion / 100;
1740  if (serverMajor < minServerMajor || serverMajor > maxServerMajor)
1741  {
1742  const char *serverver = PQparameterStatus(conn, "server_version");
1743 
1744  fprintf(stderr, _("%s: incompatible server version %s\n"),
1745  progname, serverver ? serverver : "'unknown'");
1747  }
1748 
1749  /*
1750  * If WAL streaming was requested, also check that the server is new
1751  * enough for that.
1752  */
1754  {
1755  /*
1756  * Error message already written in CheckServerVersionForStreaming(),
1757  * but add a hint about using -X none.
1758  */
1759  fprintf(stderr, _("HINT: use -X none or -X fetch to disable log streaming\n"));
1761  }
1762 
1763  /*
1764  * Build contents of recovery.conf if requested
1765  */
1766  if (writerecoveryconf)
1768 
1769  /*
1770  * Run IDENTIFY_SYSTEM so we can get the timeline
1771  */
1772  if (!RunIdentifySystem(conn, &sysidentifier, &latesttli, NULL, NULL))
1774 
1775  /*
1776  * Start the actual backup
1777  */
1778  PQescapeStringConn(conn, escaped_label, label, sizeof(escaped_label), &i);
1779 
1780  if (maxrate > 0)
1781  maxrate_clause = psprintf("MAX_RATE %u", maxrate);
1782 
1783  if (verbose)
1784  fprintf(stderr,
1785  _("%s: initiating base backup, waiting for checkpoint to complete\n"),
1786  progname);
1787 
1788  if (showprogress && !verbose)
1789  fprintf(stderr, "waiting for checkpoint\r");
1790 
1791  basebkp =
1792  psprintf("BASE_BACKUP LABEL '%s' %s %s %s %s %s %s",
1793  escaped_label,
1794  showprogress ? "PROGRESS" : "",
1795  includewal == FETCH_WAL ? "WAL" : "",
1796  fastcheckpoint ? "FAST" : "",
1797  includewal == NO_WAL ? "" : "NOWAIT",
1798  maxrate_clause ? maxrate_clause : "",
1799  format == 't' ? "TABLESPACE_MAP" : "");
1800 
1801  if (PQsendQuery(conn, basebkp) == 0)
1802  {
1803  fprintf(stderr, _("%s: could not send replication command \"%s\": %s"),
1804  progname, "BASE_BACKUP", PQerrorMessage(conn));
1806  }
1807 
1808  /*
1809  * Get the starting WAL location
1810  */
1811  res = PQgetResult(conn);
1812  if (PQresultStatus(res) != PGRES_TUPLES_OK)
1813  {
1814  fprintf(stderr, _("%s: could not initiate base backup: %s"),
1817  }
1818  if (PQntuples(res) != 1)
1819  {
1820  fprintf(stderr,
1821  _("%s: server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields\n"),
1822  progname, PQntuples(res), PQnfields(res), 1, 2);
1824  }
1825 
1826  strlcpy(xlogstart, PQgetvalue(res, 0, 0), sizeof(xlogstart));
1827 
1828  if (verbose)
1829  fprintf(stderr, _("%s: checkpoint completed\n"), progname);
1830 
1831  /*
1832  * 9.3 and later sends the TLI of the starting point. With older servers,
1833  * assume it's the same as the latest timeline reported by
1834  * IDENTIFY_SYSTEM.
1835  */
1836  if (PQnfields(res) >= 2)
1837  starttli = atoi(PQgetvalue(res, 0, 1));
1838  else
1839  starttli = latesttli;
1840  PQclear(res);
1841  MemSet(xlogend, 0, sizeof(xlogend));
1842 
1843  if (verbose && includewal != NO_WAL)
1844  fprintf(stderr, _("%s: write-ahead log start point: %s on timeline %u\n"),
1845  progname, xlogstart, starttli);
1846 
1847  /*
1848  * Get the header
1849  */
1850  res = PQgetResult(conn);
1851  if (PQresultStatus(res) != PGRES_TUPLES_OK)
1852  {
1853  fprintf(stderr, _("%s: could not get backup header: %s"),
1856  }
1857  if (PQntuples(res) < 1)
1858  {
1859  fprintf(stderr, _("%s: no data returned from server\n"), progname);
1861  }
1862 
1863  /*
1864  * Sum up the total size, for progress reporting
1865  */
1866  totalsize = totaldone = 0;
1867  tablespacecount = PQntuples(res);
1868  for (i = 0; i < PQntuples(res); i++)
1869  {
1870  totalsize += atol(PQgetvalue(res, i, 2));
1871 
1872  /*
1873  * Verify tablespace directories are empty. Don't bother with the
1874  * first once since it can be relocated, and it will be checked before
1875  * we do anything anyway.
1876  */
1877  if (format == 'p' && !PQgetisnull(res, i, 1))
1878  {
1879  char *path = (char *) get_tablespace_mapping(PQgetvalue(res, i, 1));
1880 
1882  }
1883  }
1884 
1885  /*
1886  * When writing to stdout, require a single tablespace
1887  */
1888  if (format == 't' && strcmp(basedir, "-") == 0 && PQntuples(res) > 1)
1889  {
1890  fprintf(stderr,
1891  _("%s: can only write single tablespace to stdout, database has %d\n"),
1892  progname, PQntuples(res));
1894  }
1895 
1896  /*
1897  * If we're streaming WAL, start the streaming session before we start
1898  * receiving the actual data chunks.
1899  */
1900  if (includewal == STREAM_WAL)
1901  {
1902  if (verbose)
1903  fprintf(stderr, _("%s: starting background WAL receiver\n"),
1904  progname);
1905  StartLogStreamer(xlogstart, starttli, sysidentifier);
1906  }
1907 
1908  /*
1909  * Start receiving chunks
1910  */
1911  for (i = 0; i < PQntuples(res); i++)
1912  {
1913  if (format == 't')
1914  ReceiveTarFile(conn, res, i);
1915  else
1916  ReceiveAndUnpackTarFile(conn, res, i);
1917  } /* Loop over all tablespaces */
1918 
1919  if (showprogress)
1920  {
1921  progress_report(PQntuples(res), NULL, true);
1922  fprintf(stderr, "\n"); /* Need to move to next line */
1923  }
1924 
1925  PQclear(res);
1926 
1927  /*
1928  * Get the stop position
1929  */
1930  res = PQgetResult(conn);
1931  if (PQresultStatus(res) != PGRES_TUPLES_OK)
1932  {
1933  fprintf(stderr,
1934  _("%s: could not get write-ahead log end position from server: %s"),
1937  }
1938  if (PQntuples(res) != 1)
1939  {
1940  fprintf(stderr,
1941  _("%s: no write-ahead log end position returned from server\n"),
1942  progname);
1944  }
1945  strlcpy(xlogend, PQgetvalue(res, 0, 0), sizeof(xlogend));
1946  if (verbose && includewal != NO_WAL)
1947  fprintf(stderr, _("%s: write-ahead log end point: %s\n"), progname, xlogend);
1948  PQclear(res);
1949 
1950  res = PQgetResult(conn);
1951  if (PQresultStatus(res) != PGRES_COMMAND_OK)
1952  {
1953  fprintf(stderr, _("%s: final receive failed: %s"),
1956  }
1957 
1958  if (bgchild > 0)
1959  {
1960 #ifndef WIN32
1961  int status;
1962  int r;
1963 #else
1964  DWORD status;
1965 
1966  /*
1967  * get a pointer sized version of bgchild to avoid warnings about
1968  * casting to a different size on WIN64.
1969  */
1970  intptr_t bgchild_handle = bgchild;
1971  uint32 hi,
1972  lo;
1973 #endif
1974 
1975  if (verbose)
1976  fprintf(stderr,
1977  _("%s: waiting for background process to finish streaming ...\n"), progname);
1978 
1979 #ifndef WIN32
1980  if (write(bgpipe[1], xlogend, strlen(xlogend)) != strlen(xlogend))
1981  {
1982  fprintf(stderr,
1983  _("%s: could not send command to background pipe: %s\n"),
1984  progname, strerror(errno));
1986  }
1987 
1988  /* Just wait for the background process to exit */
1989  r = waitpid(bgchild, &status, 0);
1990  if (r == -1)
1991  {
1992  fprintf(stderr, _("%s: could not wait for child process: %s\n"),
1993  progname, strerror(errno));
1995  }
1996  if (r != bgchild)
1997  {
1998  fprintf(stderr, _("%s: child %d died, expected %d\n"),
1999  progname, r, (int) bgchild);
2001  }
2002  if (!WIFEXITED(status))
2003  {
2004  fprintf(stderr, _("%s: child process did not exit normally\n"),
2005  progname);
2007  }
2008  if (WEXITSTATUS(status) != 0)
2009  {
2010  fprintf(stderr, _("%s: child process exited with error %d\n"),
2011  progname, WEXITSTATUS(status));
2013  }
2014  /* Exited normally, we're happy! */
2015 #else /* WIN32 */
2016 
2017  /*
2018  * On Windows, since we are in the same process, we can just store the
2019  * value directly in the variable, and then set the flag that says
2020  * it's there.
2021  */
2022  if (sscanf(xlogend, "%X/%X", &hi, &lo) != 2)
2023  {
2024  fprintf(stderr,
2025  _("%s: could not parse write-ahead log location \"%s\"\n"),
2026  progname, xlogend);
2028  }
2029  xlogendptr = ((uint64) hi) << 32 | lo;
2030  InterlockedIncrement(&has_xlogendptr);
2031 
2032  /* First wait for the thread to exit */
2033  if (WaitForSingleObjectEx((HANDLE) bgchild_handle, INFINITE, FALSE) !=
2034  WAIT_OBJECT_0)
2035  {
2036  _dosmaperr(GetLastError());
2037  fprintf(stderr, _("%s: could not wait for child thread: %s\n"),
2038  progname, strerror(errno));
2040  }
2041  if (GetExitCodeThread((HANDLE) bgchild_handle, &status) == 0)
2042  {
2043  _dosmaperr(GetLastError());
2044  fprintf(stderr, _("%s: could not get child thread exit status: %s\n"),
2045  progname, strerror(errno));
2047  }
2048  if (status != 0)
2049  {
2050  fprintf(stderr, _("%s: child thread exited with error %u\n"),
2051  progname, (unsigned int) status);
2053  }
2054  /* Exited normally, we're happy */
2055 #endif
2056  }
2057 
2058  /* Free the recovery.conf contents */
2060 
2061  /*
2062  * End of copy data. Final result is already checked inside the loop.
2063  */
2064  PQclear(res);
2065  PQfinish(conn);
2066 
2067  /*
2068  * Make data persistent on disk once backup is completed. For tar format
2069  * once syncing the parent directory is fine, each tar file created per
2070  * tablespace has been already synced. In plain format, all the data of
2071  * the base directory is synced, taking into account all the tablespaces.
2072  * Errors are not considered fatal.
2073  */
2074  if (do_sync)
2075  {
2076  if (format == 't')
2077  {
2078  if (strcmp(basedir, "-") != 0)
2079  (void) fsync_fname(basedir, true, progname);
2080  }
2081  else
2082  {
2083  (void) fsync_pgdata(basedir, progname, serverVersion);
2084  }
2085  }
2086 
2087  if (verbose)
2088  fprintf(stderr, _("%s: base backup completed\n"), progname);
2089 }
int PQnfields(const PGresult *res)
Definition: fe-exec.c:2732
static PQExpBuffer recoveryconfcontents
static IncludeWal includewal
Definition: pg_basebackup.c:87
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6097
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:3118
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:6062
#define write(a, b, c)
Definition: win32.h:14
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
void fsync_fname(const char *fname, bool isdir)
Definition: fd.c:572
static int tablespacecount
bool RunIdentifySystem(PGconn *conn, char **sysid, TimeLineID *starttli, XLogRecPtr *startpos, char **db_name)
Definition: streamutil.c:316
#define WIFEXITED(w)
Definition: win32.h:172
static bool writerecoveryconf
Definition: pg_basebackup.c:89
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3630
#define MemSet(start, val, len)
Definition: c.h:863
int PQserverVersion(const PGconn *conn)
Definition: fe-connect.c:6087
const char * progname
Definition: pg_standby.c:37
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2724
static void GenerateRecoveryConf(PGconn *conn)
static char * basedir
Definition: pg_basebackup.c:78
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
int PQsendQuery(PGconn *conn, const char *query)
Definition: fe-exec.c:1183
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:113
#define FALSE
Definition: c.h:219
PGconn * conn
Definition: streamutil.c:46
#define MAXPGPATH
static uint64 totaldone
static int32 maxrate
Definition: pg_basebackup.c:93
static int has_xlogendptr
size_t PQescapeStringConn(PGconn *conn, char *to, const char *from, size_t length, int *error)
Definition: fe-exec.c:3365
unsigned int uint32
Definition: c.h:258
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:85
static bool showprogress
Definition: pg_basebackup.c:84
static void ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
static char * label
Definition: pg_basebackup.c:82
static void StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier)
void PQclear(PGresult *res)
Definition: fe-exec.c:671
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define WEXITSTATUS(w)
Definition: win32.h:174
#define Assert(condition)
Definition: c.h:681
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:88
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:90
static void verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found)
static char format
Definition: pg_basebackup.c:81
static void disconnect_and_exit(int code)
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:225
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3143
#define _(x)
Definition: elog.c:84
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:1753
bool CheckServerVersionForStreaming(PGconn *conn)
Definition: receivelog.c:367
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 WAL directory \"%s\"\n"),
181  progname, xlog_dir);
182  if (!rmtree(xlog_dir, true))
183  fprintf(stderr, _("%s: failed to remove WAL directory\n"),
184  progname);
185  }
186  else if (found_existing_xlogdir)
187  {
188  fprintf(stderr,
189  _("%s: removing contents of WAL directory \"%s\"\n"),
190  progname, xlog_dir);
191  if (!rmtree(xlog_dir, false))
192  fprintf(stderr, _("%s: failed to remove contents of WAL 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: WAL 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:78
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:80
static bool made_new_xlogdir
static bool made_tablespace_dirs
#define _(x)
Definition: elog.c:84
static bool noclean
Definition: pg_basebackup.c:83
static void disconnect_and_exit ( int  code)
static

Definition at line 216 of file pg_basebackup.c.

References bgchild, conn, 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:3630
PGconn * conn
Definition: streamutil.c:46
static pid_t bgchild
static char* escape_quotes ( const char *  src)
static

Definition at line 1585 of file pg_basebackup.c.

References _, escape_single_quotes_ascii(), and progname.

Referenced by GenerateRecoveryConf().

1586 {
1587  char *result = escape_single_quotes_ascii(src);
1588 
1589  if (!result)
1590  {
1591  fprintf(stderr, _("%s: out of memory\n"), progname);
1592  exit(1);
1593  }
1594  return result;
1595 }
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 1601 of file pg_basebackup.c.

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

Referenced by BaseBackup().

1602 {
1603  PQconninfoOption *connOptions;
1605  PQExpBufferData conninfo_buf;
1606  char *escaped;
1607 
1609  if (!recoveryconfcontents)
1610  {
1611  fprintf(stderr, _("%s: out of memory\n"), progname);
1613  }
1614 
1615  connOptions = PQconninfo(conn);
1616  if (connOptions == NULL)
1617  {
1618  fprintf(stderr, _("%s: out of memory\n"), progname);
1620  }
1621 
1622  appendPQExpBufferStr(recoveryconfcontents, "standby_mode = 'on'\n");
1623 
1624  initPQExpBuffer(&conninfo_buf);
1625  for (option = connOptions; option && option->keyword; option++)
1626  {
1627  /*
1628  * Do not emit this setting if: - the setting is "replication",
1629  * "dbname" or "fallback_application_name", since these would be
1630  * overridden by the libpqwalreceiver module anyway. - not set or
1631  * empty.
1632  */
1633  if (strcmp(option->keyword, "replication") == 0 ||
1634  strcmp(option->keyword, "dbname") == 0 ||
1635  strcmp(option->keyword, "fallback_application_name") == 0 ||
1636  (option->val == NULL) ||
1637  (option->val != NULL && option->val[0] == '\0'))
1638  continue;
1639 
1640  /* Separate key-value pairs with spaces */
1641  if (conninfo_buf.len != 0)
1642  appendPQExpBufferChar(&conninfo_buf, ' ');
1643 
1644  /*
1645  * Write "keyword=value" pieces, the value string is escaped and/or
1646  * quoted if necessary.
1647  */
1648  appendPQExpBuffer(&conninfo_buf, "%s=", option->keyword);
1649  appendConnStrVal(&conninfo_buf, option->val);
1650  }
1651 
1652  /*
1653  * Escape the connection string, so that it can be put in the config file.
1654  * Note that this is different from the escaping of individual connection
1655  * options above!
1656  */
1657  escaped = escape_quotes(conninfo_buf.data);
1658  appendPQExpBuffer(recoveryconfcontents, "primary_conninfo = '%s'\n", escaped);
1659  free(escaped);
1660 
1661  if (replication_slot)
1662  {
1663  escaped = escape_quotes(replication_slot);
1664  appendPQExpBuffer(recoveryconfcontents, "primary_slot_name = '%s'\n", replication_slot);
1665  free(escaped);
1666  }
1667 
1669  PQExpBufferDataBroken(conninfo_buf))
1670  {
1671  fprintf(stderr, _("%s: out of memory\n"), progname);
1673  }
1674 
1675  termPQExpBuffer(&conninfo_buf);
1676 
1677  PQconninfoFree(connOptions);
1678 }
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:551
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:5947
PQconninfoOption * PQconninfo(PGconn *conn)
Definition: fe-connect.c:5906
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:71
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:396
#define free(a)
Definition: header.h:65
#define PQExpBufferDataBroken(buf)
Definition: pqexpbuffer.h:67
#define PQExpBufferBroken(str)
Definition: pqexpbuffer.h:59
static void disconnect_and_exit(int code)
static char * replication_slot
Definition: pg_basebackup.c:94
#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 1303 of file pg_basebackup.c.

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

Referenced by BaseBackup(), and ReceiveAndUnpackTarFile().

1304 {
1305  TablespaceListCell *cell;
1306 
1307  for (cell = tablespace_dirs.head; cell; cell = cell->next)
1308  if (strcmp(dir, cell->old_dir) == 0)
1309  return cell->new_dir;
1310 
1311  return dir;
1312 }
static TablespaceList tablespace_dirs
Definition: pg_basebackup.c:79
char old_dir[MAXPGPATH]
Definition: pg_basebackup.c:46
char new_dir[MAXPGPATH]
Definition: pg_basebackup.c:47
struct TablespaceListCell * next
Definition: pg_basebackup.c:45
TablespaceListCell * head
Definition: pg_basebackup.c:52
static int LogStreamerMain ( logstreamer_param param)
static

Definition at line 475 of file pg_basebackup.c.

References _, logstreamer_param::bgconn, bgpipe, compresslevel, CreateWalDirectoryMethod(), CreateWalTarMethod(), StreamCtl::do_sync, do_sync, WalWriteMethod::finish, format, FreeWalDirectoryMethod(), FreeWalTarMethod(), in_log_streamer, StreamCtl::mark_done, MemSet, StreamCtl::partial_suffix, pg_free(), PGINVALID_SOCKET, PQfinish(), progname, reached_end_position(), ReceiveXlogStream(), StreamCtl::replication_slot, replication_slot, StreamCtl::standby_message_timeout, standby_message_timeout, StreamCtl::startpos, logstreamer_param::startptr, StreamCtl::stop_socket, StreamCtl::stream_stop, strerror(), StreamCtl::synchronous, StreamCtl::sysidentifier, logstreamer_param::sysidentifier, 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;
486 #ifndef WIN32
487  stream.stop_socket = bgpipe[0];
488 #else
489  stream.stop_socket = PGINVALID_SOCKET;
490 #endif
492  stream.synchronous = false;
493  stream.do_sync = do_sync;
494  stream.mark_done = true;
495  stream.partial_suffix = NULL;
497 
498  if (format == 'p')
499  stream.walmethod = CreateWalDirectoryMethod(param->xlog, 0, do_sync);
500  else
502 
503  if (!ReceiveXlogStream(param->bgconn, &stream))
504 
505  /*
506  * Any errors will already have been reported in the function process,
507  * but we need to tell the parent that we didn't shutdown in a nice
508  * way.
509  */
510  return 1;
511 
512  if (!stream.walmethod->finish())
513  {
514  fprintf(stderr,
515  _("%s: could not finish writing WAL files: %s\n"),
516  progname, strerror(errno));
517  return 1;
518  }
519 
520  PQfinish(param->bgconn);
521 
522  if (format == 'p')
524  else
526  pg_free(stream.walmethod);
527 
528  return 0;
529 }
static int bgpipe[2]
bool do_sync
Definition: receivelog.h:39
char * sysidentifier
Definition: receivelog.h:34
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3630
static int compresslevel
Definition: pg_basebackup.c:86
#define MemSet(start, val, len)
Definition: c.h:863
XLogRecPtr startpos
Definition: receivelog.h:32
char * partial_suffix
Definition: receivelog.h:48
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:75
char * replication_slot
Definition: receivelog.h:49
bool mark_done
Definition: receivelog.h:38
XLogRecPtr startptr
stream_stop_callback stream_stop
Definition: receivelog.h:42
WalWriteMethod * walmethod
Definition: receivelog.h:47
static int standby_message_timeout
Definition: pg_basebackup.c:91
void FreeWalTarMethod(void)
Definition: walmethods.c:978
#define PGINVALID_SOCKET
Definition: port.h:24
static bool in_log_streamer
WalWriteMethod * CreateWalTarMethod(const char *tarbase, int compression, bool sync)
Definition: walmethods.c:947
bool ReceiveXlogStream(PGconn *conn, StreamCtl *stream)
Definition: receivelog.c:447
bool synchronous
Definition: receivelog.h:37
void pg_free(void *ptr)
Definition: fe_memutils.c:105
pgsocket stop_socket
Definition: receivelog.h:44
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:90
static char format
Definition: pg_basebackup.c:81
static char * replication_slot
Definition: pg_basebackup.c:94
#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 2093 of file pg_basebackup.c.

References _, BaseBackup(), basedir, canonicalize_path(), cleanup_directories_atexit(), compresslevel, conn, connection_string, create_slot, 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_slot, NO_WAL, noclean, optarg, optind, parse_max_rate(), pg_strcasecmp(), pg_strdup(), PG_TEXTDOMAIN, PQserverVersion(), progname, psprintf(), replication_slot, required_argument, RetrieveWalSegSize(), 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.

2094 {
2095  static struct option long_options[] = {
2096  {"help", no_argument, NULL, '?'},
2097  {"version", no_argument, NULL, 'V'},
2098  {"pgdata", required_argument, NULL, 'D'},
2099  {"format", required_argument, NULL, 'F'},
2100  {"checkpoint", required_argument, NULL, 'c'},
2101  {"create-slot", no_argument, NULL, 'C'},
2102  {"max-rate", required_argument, NULL, 'r'},
2103  {"write-recovery-conf", no_argument, NULL, 'R'},
2104  {"slot", required_argument, NULL, 'S'},
2105  {"tablespace-mapping", required_argument, NULL, 'T'},
2106  {"wal-method", required_argument, NULL, 'X'},
2107  {"gzip", no_argument, NULL, 'z'},
2108  {"compress", required_argument, NULL, 'Z'},
2109  {"label", required_argument, NULL, 'l'},
2110  {"no-clean", no_argument, NULL, 'n'},
2111  {"no-sync", no_argument, NULL, 'N'},
2112  {"dbname", required_argument, NULL, 'd'},
2113  {"host", required_argument, NULL, 'h'},
2114  {"port", required_argument, NULL, 'p'},
2115  {"username", required_argument, NULL, 'U'},
2116  {"no-password", no_argument, NULL, 'w'},
2117  {"password", no_argument, NULL, 'W'},
2118  {"status-interval", required_argument, NULL, 's'},
2119  {"verbose", no_argument, NULL, 'v'},
2120  {"progress", no_argument, NULL, 'P'},
2121  {"waldir", required_argument, NULL, 1},
2122  {"no-slot", no_argument, NULL, 2},
2123  {NULL, 0, NULL, 0}
2124  };
2125  int c;
2126 
2127  int option_index;
2128 
2129  progname = get_progname(argv[0]);
2130  set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_basebackup"));
2131 
2132  if (argc > 1)
2133  {
2134  if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
2135  {
2136  usage();
2137  exit(0);
2138  }
2139  else if (strcmp(argv[1], "-V") == 0
2140  || strcmp(argv[1], "--version") == 0)
2141  {
2142  puts("pg_basebackup (PostgreSQL) " PG_VERSION);
2143  exit(0);
2144  }
2145  }
2146 
2148 
2149  while ((c = getopt_long(argc, argv, "CD:F:r:RS:T:X:l:nNzZ:d:c:h:p:U:s:wWvP",
2150  long_options, &option_index)) != -1)
2151  {
2152  switch (c)
2153  {
2154  case 'C':
2155  create_slot = true;
2156  break;
2157  case 'D':
2159  break;
2160  case 'F':
2161  if (strcmp(optarg, "p") == 0 || strcmp(optarg, "plain") == 0)
2162  format = 'p';
2163  else if (strcmp(optarg, "t") == 0 || strcmp(optarg, "tar") == 0)
2164  format = 't';
2165  else
2166  {
2167  fprintf(stderr,
2168  _("%s: invalid output format \"%s\", must be \"plain\" or \"tar\"\n"),
2169  progname, optarg);
2170  exit(1);
2171  }
2172  break;
2173  case 'r':
2175  break;
2176  case 'R':
2177  writerecoveryconf = true;
2178  break;
2179  case 'S':
2180 
2181  /*
2182  * When specifying replication slot name, use a permanent
2183  * slot.
2184  */
2186  temp_replication_slot = false;
2187  break;
2188  case 2:
2189  no_slot = true;
2190  break;
2191  case 'T':
2193  break;
2194  case 'X':
2195  if (strcmp(optarg, "n") == 0 ||
2196  strcmp(optarg, "none") == 0)
2197  {
2198  includewal = NO_WAL;
2199  }
2200  else if (strcmp(optarg, "f") == 0 ||
2201  strcmp(optarg, "fetch") == 0)
2202  {
2204  }
2205  else if (strcmp(optarg, "s") == 0 ||
2206  strcmp(optarg, "stream") == 0)
2207  {
2209  }
2210  else
2211  {
2212  fprintf(stderr,
2213  _("%s: invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"\n"),
2214  progname, optarg);
2215  exit(1);
2216  }
2217  break;
2218  case 1:
2220  break;
2221  case 'l':
2222  label = pg_strdup(optarg);
2223  break;
2224  case 'n':
2225  noclean = true;
2226  break;
2227  case 'N':
2228  do_sync = false;
2229  break;
2230  case 'z':
2231 #ifdef HAVE_LIBZ
2233 #else
2234  compresslevel = 1; /* will be rejected below */
2235 #endif
2236  break;
2237  case 'Z':
2238  compresslevel = atoi(optarg);
2239  if (compresslevel < 0 || compresslevel > 9)
2240  {
2241  fprintf(stderr, _("%s: invalid compression level \"%s\"\n"),
2242  progname, optarg);
2243  exit(1);
2244  }
2245  break;
2246  case 'c':
2247  if (pg_strcasecmp(optarg, "fast") == 0)
2248  fastcheckpoint = true;
2249  else if (pg_strcasecmp(optarg, "spread") == 0)
2250  fastcheckpoint = false;
2251  else
2252  {
2253  fprintf(stderr, _("%s: invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"\n"),
2254  progname, optarg);
2255  exit(1);
2256  }
2257  break;
2258  case 'd':
2260  break;
2261  case 'h':
2262  dbhost = pg_strdup(optarg);
2263  break;
2264  case 'p':
2265  dbport = pg_strdup(optarg);
2266  break;
2267  case 'U':
2268  dbuser = pg_strdup(optarg);
2269  break;
2270  case 'w':
2271  dbgetpassword = -1;
2272  break;
2273  case 'W':
2274  dbgetpassword = 1;
2275  break;
2276  case 's':
2277  standby_message_timeout = atoi(optarg) * 1000;
2278  if (standby_message_timeout < 0)
2279  {
2280  fprintf(stderr, _("%s: invalid status interval \"%s\"\n"),
2281  progname, optarg);
2282  exit(1);
2283  }
2284  break;
2285  case 'v':
2286  verbose++;
2287  break;
2288  case 'P':
2289  showprogress = true;
2290  break;
2291  default:
2292 
2293  /*
2294  * getopt_long already emitted a complaint
2295  */
2296  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2297  progname);
2298  exit(1);
2299  }
2300  }
2301 
2302  /*
2303  * Any non-option arguments?
2304  */
2305  if (optind < argc)
2306  {
2307  fprintf(stderr,
2308  _("%s: too many command-line arguments (first is \"%s\")\n"),
2309  progname, argv[optind]);
2310  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2311  progname);
2312  exit(1);
2313  }
2314 
2315  /*
2316  * Required arguments
2317  */
2318  if (basedir == NULL)
2319  {
2320  fprintf(stderr, _("%s: no target directory specified\n"), progname);
2321  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2322  progname);
2323  exit(1);
2324  }
2325 
2326  /*
2327  * Mutually exclusive arguments
2328  */
2329  if (format == 'p' && compresslevel != 0)
2330  {
2331  fprintf(stderr,
2332  _("%s: only tar mode backups can be compressed\n"),
2333  progname);
2334  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2335  progname);
2336  exit(1);
2337  }
2338 
2339  if (format == 't' && includewal == STREAM_WAL && strcmp(basedir, "-") == 0)
2340  {
2341  fprintf(stderr,
2342  _("%s: cannot stream write-ahead logs in tar mode to stdout\n"),
2343  progname);
2344  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2345  progname);
2346  exit(1);
2347  }
2348 
2350  {
2351  fprintf(stderr,
2352  _("%s: replication slots can only be used with WAL streaming\n"),
2353  progname);
2354  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2355  progname);
2356  exit(1);
2357  }
2358 
2359  if (no_slot)
2360  {
2361  if (replication_slot)
2362  {
2363  fprintf(stderr,
2364  _("%s: --no-slot cannot be used with slot name\n"),
2365  progname);
2366  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2367  progname);
2368  exit(1);
2369  }
2370  temp_replication_slot = false;
2371  }
2372 
2373  if (create_slot)
2374  {
2375  if (!replication_slot)
2376  {
2377  fprintf(stderr,
2378  _("%s: --create-slot needs a slot to be specified using --slot\n"),
2379  progname);
2380  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2381  progname);
2382  exit(1);
2383  }
2384 
2385  if (no_slot)
2386  {
2387  fprintf(stderr,
2388  _("%s: --create-slot and --no-slot are incompatible options\n"),
2389  progname);
2390  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2391  progname);
2392  exit(1);
2393  }
2394  }
2395 
2396  if (xlog_dir)
2397  {
2398  if (format != 'p')
2399  {
2400  fprintf(stderr,
2401  _("%s: WAL directory location can only be specified in plain mode\n"),
2402  progname);
2403  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2404  progname);
2405  exit(1);
2406  }
2407 
2408  /* clean up xlog directory name, check it's absolute */
2410  if (!is_absolute_path(xlog_dir))
2411  {
2412  fprintf(stderr, _("%s: WAL directory location must be "
2413  "an absolute path\n"), progname);
2414  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2415  progname);
2416  exit(1);
2417  }
2418  }
2419 
2420 #ifndef HAVE_LIBZ
2421  if (compresslevel != 0)
2422  {
2423  fprintf(stderr,
2424  _("%s: this build does not support compression\n"),
2425  progname);
2426  exit(1);
2427  }
2428 #endif
2429 
2430  /*
2431  * Verify that the target directory exists, or create it. For plaintext
2432  * backups, always require the directory. For tar backups, require it
2433  * unless we are writing to stdout.
2434  */
2435  if (format == 'p' || strcmp(basedir, "-") != 0)
2437 
2438  /* connection in replication mode to server */
2439  conn = GetConnection();
2440  if (!conn)
2441  {
2442  /* Error message already written in GetConnection() */
2443  exit(1);
2444  }
2445 
2446  /* determine remote server's xlog segment size */
2447  if (!RetrieveWalSegSize(conn))
2449 
2450  /* Create pg_wal symlink, if required */
2451  if (xlog_dir)
2452  {
2453  char *linkloc;
2454 
2456 
2457  /*
2458  * Form name of the place where the symlink must go. pg_xlog has been
2459  * renamed to pg_wal in post-10 clusters.
2460  */
2461  linkloc = psprintf("%s/%s", basedir,
2463  "pg_xlog" : "pg_wal");
2464 
2465 #ifdef HAVE_SYMLINK
2466  if (symlink(xlog_dir, linkloc) != 0)
2467  {
2468  fprintf(stderr, _("%s: could not create symbolic link \"%s\": %s\n"),
2469  progname, linkloc, strerror(errno));
2471  }
2472 #else
2473  fprintf(stderr, _("%s: symlinks are not supported on this platform\n"));
2475 #endif
2476  free(linkloc);
2477  }
2478 
2479  BaseBackup();
2480 
2481  success = true;
2482  return 0;
2483 }
static IncludeWal includewal
Definition: pg_basebackup.c:87
#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:89
static bool create_slot
Definition: pg_basebackup.c:96
static int compresslevel
Definition: pg_basebackup.c:86
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
int PQserverVersion(const PGconn *conn)
Definition: fe-connect.c:6087
const char * progname
Definition: pg_standby.c:37
static char * basedir
Definition: pg_basebackup.c:78
static void BaseBackup(void)
#define required_argument
Definition: getopt_long.h:25
int optind
Definition: getopt.c:51
char * connection_string
Definition: streamutil.c:38
bool RetrieveWalSegSize(PGconn *conn)
Definition: streamutil.c:242
PGconn * conn
Definition: streamutil.c:46
#define MINIMUM_VERSION_FOR_PG_WAL
Definition: pg_basebackup.c:60
static bool found_existing_xlogdir
static bool success
Definition: pg_basebackup.c:99
static int32 maxrate
Definition: pg_basebackup.c:93
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:85
static int standby_message_timeout
Definition: pg_basebackup.c:91
static bool showprogress
Definition: pg_basebackup.c:84
int dbgetpassword
Definition: streamutil.c:43
#define no_argument
Definition: getopt_long.h:24
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1018
static bool temp_replication_slot
Definition: pg_basebackup.c:95
static char * label
Definition: pg_basebackup.c:82
char * dbport
Definition: streamutil.c:41
static void cleanup_directories_atexit(void)
#define free(a)
Definition: header.h:65
PGconn * GetConnection(UserMapping *user, bool will_prep_stmt)
Definition: connection.c:107
char * dbhost
Definition: streamutil.c:39
static char * xlog_dir
Definition: pg_basebackup.c:80
static bool no_slot
Definition: pg_basebackup.c:97
static bool made_new_xlogdir
static bool fastcheckpoint
Definition: pg_basebackup.c:88
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:40
char * optarg
Definition: getopt.c:53
const char * strerror(int errnum)
Definition: strerror.c:19
static bool do_sync
Definition: pg_basebackup.c:90
static void verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found)
static char format
Definition: pg_basebackup.c:81
static void disconnect_and_exit(int code)
static char * replication_slot
Definition: pg_basebackup.c:94
#define _(x)
Definition: elog.c:84
static bool noclean
Definition: pg_basebackup.c:83
static int32 parse_max_rate ( char *  src)
static

Definition at line 813 of file pg_basebackup.c.

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

Referenced by main().

814 {
815  double result;
816  char *after_num;
817  char *suffix = NULL;
818 
819  errno = 0;
820  result = strtod(src, &after_num);
821  if (src == after_num)
822  {
823  fprintf(stderr,
824  _("%s: transfer rate \"%s\" is not a valid value\n"),
825  progname, src);
826  exit(1);
827  }
828  if (errno != 0)
829  {
830  fprintf(stderr,
831  _("%s: invalid transfer rate \"%s\": %s\n"),
832  progname, src, strerror(errno));
833  exit(1);
834  }
835 
836  if (result <= 0)
837  {
838  /*
839  * Reject obviously wrong values here.
840  */
841  fprintf(stderr, _("%s: transfer rate must be greater than zero\n"),
842  progname);
843  exit(1);
844  }
845 
846  /*
847  * Evaluate suffix, after skipping over possible whitespace. Lack of
848  * suffix means kilobytes.
849  */
850  while (*after_num != '\0' && isspace((unsigned char) *after_num))
851  after_num++;
852 
853  if (*after_num != '\0')
854  {
855  suffix = after_num;
856  if (*after_num == 'k')
857  {
858  /* kilobyte is the expected unit. */
859  after_num++;
860  }
861  else if (*after_num == 'M')
862  {
863  after_num++;
864  result *= 1024.0;
865  }
866  }
867 
868  /* The rest can only consist of white space. */
869  while (*after_num != '\0' && isspace((unsigned char) *after_num))
870  after_num++;
871 
872  if (*after_num != '\0')
873  {
874  fprintf(stderr,
875  _("%s: invalid --max-rate unit: \"%s\"\n"),
876  progname, suffix);
877  exit(1);
878  }
879 
880  /* Valid integer? */
881  if ((uint64) result != (uint64) ((uint32) result))
882  {
883  fprintf(stderr,
884  _("%s: transfer rate \"%s\" exceeds integer range\n"),
885  progname, src);
886  exit(1);
887  }
888 
889  /*
890  * The range is checked on the server side too, but avoid the server
891  * connection if a nonsensical value was passed.
892  */
893  if (result < MAX_RATE_LOWER || result > MAX_RATE_UPPER)
894  {
895  fprintf(stderr,
896  _("%s: transfer rate \"%s\" is out of range\n"),
897  progname, src);
898  exit(1);
899  }
900 
901  return (int32) result;
902 }
const char * progname
Definition: pg_standby.c:37
signed int int32
Definition: c.h:246
#define MAX_RATE_UPPER
Definition: basebackup.h:21
unsigned int uint32
Definition: c.h:258
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 727 of file pg_basebackup.c.

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

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

728 {
729  int percent;
730  char totaldone_str[32];
731  char totalsize_str[32];
732  pg_time_t now;
733 
734  if (!showprogress)
735  return;
736 
737  now = time(NULL);
738  if (now == last_progress_report && !force)
739  return; /* Max once per second */
740 
742  percent = totalsize ? (int) ((totaldone / 1024) * 100 / totalsize) : 0;
743 
744  /*
745  * Avoid overflowing past 100% or the full size. This may make the total
746  * size number change as we approach the end of the backup (the estimate
747  * will always be wrong if WAL is included), but that's better than having
748  * the done column be bigger than the total.
749  */
750  if (percent > 100)
751  percent = 100;
752  if (totaldone / 1024 > totalsize)
753  totalsize = totaldone / 1024;
754 
755  /*
756  * Separate step to keep platform-dependent format code out of
757  * translatable strings. And we only test for INT64_FORMAT availability
758  * in snprintf, not fprintf.
759  */
760  snprintf(totaldone_str, sizeof(totaldone_str), INT64_FORMAT,
761  totaldone / 1024);
762  snprintf(totalsize_str, sizeof(totalsize_str), INT64_FORMAT, totalsize);
763 
764 #define VERBOSE_FILENAME_LENGTH 35
765  if (verbose)
766  {
767  if (!filename)
768 
769  /*
770  * No filename given, so clear the status line (used for last
771  * call)
772  */
773  fprintf(stderr,
774  ngettext("%*s/%s kB (100%%), %d/%d tablespace %*s",
775  "%*s/%s kB (100%%), %d/%d tablespaces %*s",
777  (int) strlen(totalsize_str),
778  totaldone_str, totalsize_str,
779  tablespacenum, tablespacecount,
780  VERBOSE_FILENAME_LENGTH + 5, "");
781  else
782  {
783  bool truncate = (strlen(filename) > VERBOSE_FILENAME_LENGTH);
784 
785  fprintf(stderr,
786  ngettext("%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)",
787  "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)",
789  (int) strlen(totalsize_str),
790  totaldone_str, totalsize_str, percent,
791  tablespacenum, tablespacecount,
792  /* Prefix with "..." if we do leading truncation */
793  truncate ? "..." : "",
796  /* Truncate filename at beginning if it's too long */
797  truncate ? filename + strlen(filename) - VERBOSE_FILENAME_LENGTH + 3 : filename);
798  }
799  }
800  else
801  fprintf(stderr,
802  ngettext("%*s/%s kB (%d%%), %d/%d tablespace",
803  "%*s/%s kB (%d%%), %d/%d tablespaces",
805  (int) strlen(totalsize_str),
806  totaldone_str, totalsize_str, percent,
807  tablespacenum, tablespacecount);
808 
809  fprintf(stderr, "\r");
810 }
int64 pg_time_t
Definition: pgtime.h:23
static pg_time_t last_progress_report
Definition: pg_basebackup.c:92
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:85
static bool showprogress
Definition: pg_basebackup.c:84
#define ngettext(s, p, n)
Definition: c.h:127
#define INT64_FORMAT
Definition: c.h:300
static char * filename
Definition: pg_dumpall.c:90
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1534
static bool reached_end_position ( XLogRecPtr  segendpos,
uint32  timeline,
bool  segment_finished 
)
static

Definition at line 383 of file pg_basebackup.c.

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

Referenced by LogStreamerMain().

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

Definition at line 1325 of file pg_basebackup.c.

References _, basedir, copybuf, disconnect_and_exit(), filename, get_tablespace_mapping(), MAXPGPATH, mkdir, 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().

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

Definition at line 954 of file pg_basebackup.c.

References _, basedir, compresslevel, copybuf, PQExpBufferData::data, disconnect_and_exit(), do_sync, filename, fsync_fname(), header(), PQExpBufferData::len, MAXPGPATH, MemSet, 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().

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

Definition at line 537 of file pg_basebackup.c.

References _, basedir, bgchild, logstreamer_param::bgconn, bgpipe, conn, create_slot, CreateReplicationSlot(), disconnect_and_exit(), format, GetConnection(), LogStreamerMain(), MAXPGPATH, MINIMUM_VERSION_FOR_PG_WAL, MINIMUM_VERSION_FOR_TEMP_SLOTS, pg_malloc0(), pg_mkdir_p(), PQbackendPID(), PQserverVersion(), progname, psprintf(), replication_slot, snprintf(), logstreamer_param::startptr, strerror(), logstreamer_param::sysidentifier, temp_replication_slot, logstreamer_param::timeline, verbose, WalSegSz, logstreamer_param::xlog, and XLogSegmentOffset.

Referenced by BaseBackup().

538 {
539  logstreamer_param *param;
540  uint32 hi,
541  lo;
542  char statusdir[MAXPGPATH];
543 
544  param = pg_malloc0(sizeof(logstreamer_param));
545  param->timeline = timeline;
546  param->sysidentifier = sysidentifier;
547 
548  /* Convert the starting position */
549  if (sscanf(startpos, "%X/%X", &hi, &lo) != 2)
550  {
551  fprintf(stderr,
552  _("%s: could not parse write-ahead log location \"%s\"\n"),
553  progname, startpos);
555  }
556  param->startptr = ((uint64) hi) << 32 | lo;
557  /* Round off to even segment position */
558  param->startptr -= XLogSegmentOffset(param->startptr, WalSegSz);
559 
560 #ifndef WIN32
561  /* Create our background pipe */
562  if (pipe(bgpipe) < 0)
563  {
564  fprintf(stderr,
565  _("%s: could not create pipe for background process: %s\n"),
566  progname, strerror(errno));
568  }
569 #endif
570 
571  /* Get a second connection */
572  param->bgconn = GetConnection();
573  if (!param->bgconn)
574  /* Error message already written in GetConnection() */
575  exit(1);
576 
577  /* In post-10 cluster, pg_xlog has been renamed to pg_wal */
578  snprintf(param->xlog, sizeof(param->xlog), "%s/%s",
579  basedir,
581  "pg_xlog" : "pg_wal");
582 
583  /* Temporary replication slots are only supported in 10 and newer */
585  temp_replication_slot = false;
586 
587  /*
588  * Create replication slot if requested
589  */
591  replication_slot = psprintf("pg_basebackup_%d", (int) PQbackendPID(param->bgconn));
593  {
594  if (!CreateReplicationSlot(param->bgconn, replication_slot, NULL,
595  temp_replication_slot, true, true, false))
597 
598  if (verbose)
599  {
601  fprintf(stderr, _("%s: created temporary replication slot \"%s\"\n"),
603  else
604  fprintf(stderr, _("%s: created replication slot \"%s\"\n"),
606  }
607  }
608 
609  if (format == 'p')
610  {
611  /*
612  * Create pg_wal/archive_status or pg_xlog/archive_status (and thus
613  * pg_wal or pg_xlog) depending on the target server so we can write
614  * to basedir/pg_wal or basedir/pg_xlog as the directory entry in the
615  * tar file may arrive later.
616  */
617  snprintf(statusdir, sizeof(statusdir), "%s/%s/archive_status",
618  basedir,
620  "pg_xlog" : "pg_wal");
621 
622  if (pg_mkdir_p(statusdir, S_IRWXU) != 0 && errno != EEXIST)
623  {
624  fprintf(stderr,
625  _("%s: could not create directory \"%s\": %s\n"),
626  progname, statusdir, strerror(errno));
628  }
629  }
630 
631  /*
632  * Start a child process and tell it to start streaming. On Unix, this is
633  * a fork(). On Windows, we create a thread.
634  */
635 #ifndef WIN32
636  bgchild = fork();
637  if (bgchild == 0)
638  {
639  /* in child process */
640  exit(LogStreamerMain(param));
641  }
642  else if (bgchild < 0)
643  {
644  fprintf(stderr, _("%s: could not create background process: %s\n"),
645  progname, strerror(errno));
647  }
648 
649  /*
650  * Else we are in the parent process and all is well.
651  */
652 #else /* WIN32 */
653  bgchild = _beginthreadex(NULL, 0, (void *) LogStreamerMain, param, 0, NULL);
654  if (bgchild == 0)
655  {
656  fprintf(stderr, _("%s: could not create background thread: %s\n"),
657  progname, strerror(errno));
659  }
660 #endif
661 }
static int bgpipe[2]
int pg_mkdir_p(char *path, int omode)
Definition: pgmkdirp.c:57
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
static bool create_slot
Definition: pg_basebackup.c:96
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
int PQserverVersion(const PGconn *conn)
Definition: fe-connect.c:6087
const char * progname
Definition: pg_standby.c:37
static char * basedir
Definition: pg_basebackup.c:78
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
PGconn * conn
Definition: streamutil.c:46
#define MAXPGPATH
#define MINIMUM_VERSION_FOR_PG_WAL
Definition: pg_basebackup.c:60
unsigned int uint32
Definition: c.h:258
XLogRecPtr startptr
static int verbose
Definition: pg_basebackup.c:85
static bool temp_replication_slot
Definition: pg_basebackup.c:95
int PQbackendPID(const PGconn *conn)
Definition: fe-connect.c:6123
#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)
PGconn * GetConnection(UserMapping *user, bool will_prep_stmt)
Definition: connection.c:107
static XLogRecPtr startpos
static void CreateReplicationSlot(CreateReplicationSlotCmd *cmd)
Definition: walsender.c:835
int WalSegSz
Definition: pg_standby.c:39
static pid_t bgchild
const char * strerror(int errnum)
Definition: strerror.c:19
static char format
Definition: pg_basebackup.c:81
static void disconnect_and_exit(int code)
static char * replication_slot
Definition: pg_basebackup.c:94
static int LogStreamerMain(logstreamer_param *param)
#define _(x)
Definition: elog.c:84
#define MINIMUM_VERSION_FOR_TEMP_SLOTS
Definition: pg_basebackup.c:65
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:79
char old_dir[MAXPGPATH]
Definition: pg_basebackup.c:46
void canonicalize_path(char *path)
Definition: path.c:254
char new_dir[MAXPGPATH]
Definition: pg_basebackup.c:47
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:45
TablespaceListCell * tail
Definition: pg_basebackup.c:53
TablespaceListCell * head
Definition: pg_basebackup.c:52
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(_(" -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
342  " relocate tablespace in OLDDIR to NEWDIR\n"));
343  printf(_(" --waldir=WALDIR location for the write-ahead log directory\n"));
344  printf(_(" -X, --wal-method=none|fetch|stream\n"
345  " include required WAL files with specified method\n"));
346  printf(_(" -z, --gzip compress tar output\n"));
347  printf(_(" -Z, --compress=0-9 compress tar output with given compression level\n"));
348  printf(_("\nGeneral options:\n"));
349  printf(_(" -c, --checkpoint=fast|spread\n"
350  " set fast or spread checkpointing\n"));
351  printf(_(" -C, --create-slot create replication slot\n"));
352  printf(_(" -l, --label=LABEL set backup label\n"));
353  printf(_(" -n, --no-clean do not clean up after errors\n"));
354  printf(_(" -N, --no-sync do not wait for changes to be written safely to disk\n"));
355  printf(_(" -P, --progress show progress information\n"));
356  printf(_(" -S, --slot=SLOTNAME replication slot to use\n"));
357  printf(_(" --no-slot prevent creation of temporary replication slot\n"));
358  printf(_(" -v, --verbose output verbose messages\n"));
359  printf(_(" -V, --version output version information, then exit\n"));
360  printf(_(" -?, --help show this help, then exit\n"));
361  printf(_("\nConnection options:\n"));
362  printf(_(" -d, --dbname=CONNSTR connection string\n"));
363  printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
364  printf(_(" -p, --port=PORT database server port number\n"));
365  printf(_(" -s, --status-interval=INTERVAL\n"
366  " time between status packets sent to server (in seconds)\n"));
367  printf(_(" -U, --username=NAME connect as specified database user\n"));
368  printf(_(" -w, --no-password never prompt for password\n"));
369  printf(_(" -W, --password force password prompt (should happen automatically)\n"));
370  printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
371 }
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 669 of file pg_basebackup.c.

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

Referenced by BaseBackup(), and main().

670 {
671  switch (pg_check_dir(dirname))
672  {
673  case 0:
674 
675  /*
676  * Does not exist, so create
677  */
678  if (pg_mkdir_p(dirname, S_IRWXU) == -1)
679  {
680  fprintf(stderr,
681  _("%s: could not create directory \"%s\": %s\n"),
682  progname, dirname, strerror(errno));
684  }
685  if (created)
686  *created = true;
687  return;
688  case 1:
689 
690  /*
691  * Exists, empty
692  */
693  if (found)
694  *found = true;
695  return;
696  case 2:
697  case 3:
698  case 4:
699 
700  /*
701  * Exists, not empty
702  */
703  fprintf(stderr,
704  _("%s: directory \"%s\" exists but is not empty\n"),
705  progname, dirname);
707  case -1:
708 
709  /*
710  * Access problem
711  */
712  fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"),
713  progname, dirname, strerror(errno));
715  }
716 }
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 1686 of file pg_basebackup.c.

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

Referenced by ReceiveAndUnpackTarFile().

1687 {
1688  char filename[MAXPGPATH];
1689  FILE *cf;
1690 
1691  sprintf(filename, "%s/recovery.conf", basedir);
1692 
1693  cf = fopen(filename, "w");
1694  if (cf == NULL)
1695  {
1696  fprintf(stderr, _("%s: could not create file \"%s\": %s\n"), progname, filename, strerror(errno));
1698  }
1699 
1700  if (fwrite(recoveryconfcontents->data, recoveryconfcontents->len, 1, cf) != 1)
1701  {
1702  fprintf(stderr,
1703  _("%s: could not write to file \"%s\": %s\n"),
1704  progname, filename, strerror(errno));
1706  }
1707 
1708  fclose(cf);
1709 }
static PQExpBuffer recoveryconfcontents
const char * progname
Definition: pg_standby.c:37
static char * basedir
Definition: pg_basebackup.c:78
#define MAXPGPATH
static char * filename
Definition: pg_dumpall.c:90
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 908 of file pg_basebackup.c.

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

913 {
914 #ifdef HAVE_LIBZ
915  if (ztarfile != NULL)
916  {
917  if (gzwrite(ztarfile, buf, r) != r)
918  {
919  fprintf(stderr,
920  _("%s: could not write to compressed file \"%s\": %s\n"),
921  progname, current_file, get_gz_error(ztarfile));
923  }
924  }
925  else
926 #endif
927  {
928  if (fwrite(buf, r, 1, tarfile) != 1)
929  {
930  fprintf(stderr, _("%s: could not write to file \"%s\": %s\n"),
931  progname, current_file, strerror(errno));
933  }
934  }
935 }
const char * progname
Definition: pg_standby.c:37
static char * buf
Definition: pg_test_fsync.c:67
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
int compresslevel = 0
static

Definition at line 86 of file pg_basebackup.c.

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

bool create_slot = false
static

Definition at line 96 of file pg_basebackup.c.

Referenced by CreateSubscription(), main(), and StartLogStreamer().

bool do_sync = true
static

Definition at line 90 of file pg_basebackup.c.

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

bool fastcheckpoint = false
static

Definition at line 88 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 87 of file pg_basebackup.c.

Referenced by BaseBackup(), and main().

pg_time_t last_progress_report = 0
static

Definition at line 92 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 93 of file pg_basebackup.c.

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

bool no_slot = false
static

Definition at line 97 of file pg_basebackup.c.

Referenced by main().

bool noclean = false
static

Definition at line 83 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 94 of file pg_basebackup.c.

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

bool showprogress = false
static

Definition at line 84 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 91 of file pg_basebackup.c.

Referenced by LogStreamerMain(), and main().

TablespaceList tablespace_dirs = {NULL, NULL}
static

Definition at line 79 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 95 of file pg_basebackup.c.

Referenced by main(), and StartLogStreamer().

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

Definition at line 89 of file pg_basebackup.c.

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

char* xlog_dir = NULL
static

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