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

Macro Definition Documentation

#define MINIMUM_VERSION_FOR_PG_WAL   100000

Definition at line 59 of file pg_basebackup.c.

Referenced by main(), and StartLogStreamer().

#define MINIMUM_VERSION_FOR_TEMP_SLOTS   100000

Definition at line 64 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 920 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 69 of file pg_basebackup.c.

70 {
71  NO_WAL,
72  FETCH_WAL,
74 } IncludeWal;
IncludeWal
Definition: pg_basebackup.c:69

Function Documentation

static void BaseBackup ( void  )
static

Definition at line 1693 of file pg_basebackup.c.

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

Referenced by main().

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

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

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

Definition at line 213 of file pg_basebackup.c.

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

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

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

Definition at line 1565 of file pg_basebackup.c.

References _, escape_single_quotes_ascii(), progname, and result.

Referenced by GenerateRecoveryConf().

1566 {
1567  char *result = escape_single_quotes_ascii(src);
1568 
1569  if (!result)
1570  {
1571  fprintf(stderr, _("%s: out of memory\n"), progname);
1572  exit(1);
1573  }
1574  return result;
1575 }
return result
Definition: formatting.c:1633
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 1581 of file pg_basebackup.c.

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

Referenced by BaseBackup().

1582 {
1583  PQconninfoOption *connOptions;
1585  PQExpBufferData conninfo_buf;
1586  char *escaped;
1587 
1589  if (!recoveryconfcontents)
1590  {
1591  fprintf(stderr, _("%s: out of memory\n"), progname);
1593  }
1594 
1595  connOptions = PQconninfo(conn);
1596  if (connOptions == NULL)
1597  {
1598  fprintf(stderr, _("%s: out of memory\n"), progname);
1600  }
1601 
1602  appendPQExpBufferStr(recoveryconfcontents, "standby_mode = 'on'\n");
1603 
1604  initPQExpBuffer(&conninfo_buf);
1605  for (option = connOptions; option && option->keyword; option++)
1606  {
1607  /*
1608  * Do not emit this setting if: - the setting is "replication",
1609  * "dbname" or "fallback_application_name", since these would be
1610  * overridden by the libpqwalreceiver module anyway. - not set or
1611  * empty.
1612  */
1613  if (strcmp(option->keyword, "replication") == 0 ||
1614  strcmp(option->keyword, "dbname") == 0 ||
1615  strcmp(option->keyword, "fallback_application_name") == 0 ||
1616  (option->val == NULL) ||
1617  (option->val != NULL && option->val[0] == '\0'))
1618  continue;
1619 
1620  /* Separate key-value pairs with spaces */
1621  if (conninfo_buf.len != 0)
1622  appendPQExpBufferChar(&conninfo_buf, ' ');
1623 
1624  /*
1625  * Write "keyword=value" pieces, the value string is escaped and/or
1626  * quoted if necessary.
1627  */
1628  appendPQExpBuffer(&conninfo_buf, "%s=", option->keyword);
1629  appendConnStrVal(&conninfo_buf, option->val);
1630  }
1631 
1632  /*
1633  * Escape the connection string, so that it can be put in the config file.
1634  * Note that this is different from the escaping of individual connection
1635  * options above!
1636  */
1637  escaped = escape_quotes(conninfo_buf.data);
1638  appendPQExpBuffer(recoveryconfcontents, "primary_conninfo = '%s'\n", escaped);
1639  free(escaped);
1640 
1641  if (replication_slot)
1642  {
1643  escaped = escape_quotes(replication_slot);
1644  appendPQExpBuffer(recoveryconfcontents, "primary_slot_name = '%s'\n", replication_slot);
1645  free(escaped);
1646  }
1647 
1649  PQExpBufferDataBroken(conninfo_buf))
1650  {
1651  fprintf(stderr, _("%s: out of memory\n"), progname);
1653  }
1654 
1655  termPQExpBuffer(&conninfo_buf);
1656 
1657  PQconninfoFree(connOptions);
1658 }
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 NULL
Definition: c.h:229
#define PQExpBufferBroken(str)
Definition: pqexpbuffer.h:59
static void disconnect_and_exit(int code)
static char * replication_slot
Definition: pg_basebackup.c:93
#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 1283 of file pg_basebackup.c.

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

Referenced by BaseBackup(), and ReceiveAndUnpackTarFile().

1284 {
1285  TablespaceListCell *cell;
1286 
1287  for (cell = tablespace_dirs.head; cell; cell = cell->next)
1288  if (strcmp(dir, cell->old_dir) == 0)
1289  return cell->new_dir;
1290 
1291  return dir;
1292 }
static TablespaceList tablespace_dirs
Definition: pg_basebackup.c:78
char old_dir[MAXPGPATH]
Definition: pg_basebackup.c:45
char new_dir[MAXPGPATH]
Definition: pg_basebackup.c:46
struct TablespaceListCell * next
Definition: pg_basebackup.c:44
TablespaceListCell * head
Definition: pg_basebackup.c:51
static int LogStreamerMain ( logstreamer_param param)
static

Definition at line 472 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, NULL, StreamCtl::partial_suffix, pg_free(), PGINVALID_SOCKET, PQbackendPID(), PQfinish(), progname, psprintf(), reached_end_position(), ReceiveXlogStream(), StreamCtl::replication_slot, replication_slot, StreamCtl::standby_message_timeout, standby_message_timeout, StreamCtl::startpos, logstreamer_param::startptr, StreamCtl::stop_socket, StreamCtl::stream_stop, strerror(), StreamCtl::synchronous, StreamCtl::sysidentifier, logstreamer_param::sysidentifier, StreamCtl::temp_slot, logstreamer_param::temp_slot, StreamCtl::timeline, logstreamer_param::timeline, StreamCtl::walmethod, and logstreamer_param::xlog.

Referenced by StartLogStreamer().

473 {
474  StreamCtl stream;
475 
476  in_log_streamer = true;
477 
478  MemSet(&stream, 0, sizeof(stream));
479  stream.startpos = param->startptr;
480  stream.timeline = param->timeline;
481  stream.sysidentifier = param->sysidentifier;
483 #ifndef WIN32
484  stream.stop_socket = bgpipe[0];
485 #else
486  stream.stop_socket = PGINVALID_SOCKET;
487 #endif
489  stream.synchronous = false;
490  stream.do_sync = do_sync;
491  stream.mark_done = true;
492  stream.partial_suffix = NULL;
494  stream.temp_slot = param->temp_slot;
495  if (stream.temp_slot && !stream.replication_slot)
496  stream.replication_slot = psprintf("pg_basebackup_%d", (int) PQbackendPID(param->bgconn));
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 * psprintf(const char *fmt,...)
Definition: psprintf.c:46
char * sysidentifier
Definition: receivelog.h:34
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3630
static int compresslevel
Definition: pg_basebackup.c:85
#define MemSet(start, val, len)
Definition: c.h:858
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:90
void FreeWalTarMethod(void)
Definition: walmethods.c:978
int PQbackendPID(const PGconn *conn)
Definition: fe-connect.c:6123
#define PGINVALID_SOCKET
Definition: port.h:24
static bool in_log_streamer
#define NULL
Definition: c.h:229
WalWriteMethod * CreateWalTarMethod(const char *tarbase, int compression, bool sync)
Definition: walmethods.c:947
bool ReceiveXlogStream(PGconn *conn, StreamCtl *stream)
Definition: receivelog.c:446
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:89
static char format
Definition: pg_basebackup.c:80
static char * replication_slot
Definition: pg_basebackup.c:93
bool temp_slot
Definition: receivelog.h:50
#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 2073 of file pg_basebackup.c.

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

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

Definition at line 793 of file pg_basebackup.c.

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

Referenced by main().

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

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

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

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

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

Referenced by LogStreamerMain().

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

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

Referenced by BaseBackup().

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

Definition at line 934 of file pg_basebackup.c.

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

Referenced by BaseBackup().

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

Definition at line 537 of file pg_basebackup.c.

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

Referenced by BaseBackup().

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 -= param->startptr % XLOG_SEG_SIZE;
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  param->temp_slot = false;
586  else
588 
589  if (format == 'p')
590  {
591  /*
592  * Create pg_wal/archive_status or pg_xlog/archive_status (and thus
593  * pg_wal or pg_xlog) depending on the target server so we can write
594  * to basedir/pg_wal or basedir/pg_xlog as the directory entry in the
595  * tar file may arrive later.
596  */
597  snprintf(statusdir, sizeof(statusdir), "%s/%s/archive_status",
598  basedir,
600  "pg_xlog" : "pg_wal");
601 
602  if (pg_mkdir_p(statusdir, S_IRWXU) != 0 && errno != EEXIST)
603  {
604  fprintf(stderr,
605  _("%s: could not create directory \"%s\": %s\n"),
606  progname, statusdir, strerror(errno));
608  }
609  }
610 
611  /*
612  * Start a child process and tell it to start streaming. On Unix, this is
613  * a fork(). On Windows, we create a thread.
614  */
615 #ifndef WIN32
616  bgchild = fork();
617  if (bgchild == 0)
618  {
619  /* in child process */
620  exit(LogStreamerMain(param));
621  }
622  else if (bgchild < 0)
623  {
624  fprintf(stderr, _("%s: could not create background process: %s\n"),
625  progname, strerror(errno));
627  }
628 
629  /*
630  * Else we are in the parent process and all is well.
631  */
632 #else /* WIN32 */
633  bgchild = _beginthreadex(NULL, 0, (void *) LogStreamerMain, param, 0, NULL);
634  if (bgchild == 0)
635  {
636  fprintf(stderr, _("%s: could not create background thread: %s\n"),
637  progname, strerror(errno));
639  }
640 #endif
641 }
static int bgpipe[2]
int pg_mkdir_p(char *path, int omode)
Definition: pgmkdirp.c:57
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
int PQserverVersion(const PGconn *conn)
Definition: fe-connect.c:6087
const char * progname
Definition: pg_standby.c:37
static char * basedir
Definition: pg_basebackup.c:77
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
PGconn * conn
Definition: streamutil.c:43
#define MAXPGPATH
#define MINIMUM_VERSION_FOR_PG_WAL
Definition: pg_basebackup.c:59
unsigned int uint32
Definition: c.h:268
XLogRecPtr startptr
static bool temp_replication_slot
Definition: pg_basebackup.c:94
PGconn * GetConnection(UserMapping *user, bool will_prep_stmt)
Definition: connection.c:107
#define NULL
Definition: c.h:229
static XLogRecPtr startpos
static pid_t bgchild
const char * strerror(int errnum)
Definition: strerror.c:19
static char format
Definition: pg_basebackup.c:80
static void disconnect_and_exit(int code)
static int LogStreamerMain(logstreamer_param *param)
#define _(x)
Definition: elog.c:84
#define MINIMUM_VERSION_FOR_TEMP_SLOTS
Definition: pg_basebackup.c:64
char xlog[MAXPGPATH]
static void tablespace_list_append ( const char *  arg)
static

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

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

Definition at line 325 of file pg_basebackup.c.

References _, and progname.

Referenced by main().

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

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

Referenced by BaseBackup(), and main().

650 {
651  switch (pg_check_dir(dirname))
652  {
653  case 0:
654 
655  /*
656  * Does not exist, so create
657  */
658  if (pg_mkdir_p(dirname, S_IRWXU) == -1)
659  {
660  fprintf(stderr,
661  _("%s: could not create directory \"%s\": %s\n"),
662  progname, dirname, strerror(errno));
664  }
665  if (created)
666  *created = true;
667  return;
668  case 1:
669 
670  /*
671  * Exists, empty
672  */
673  if (found)
674  *found = true;
675  return;
676  case 2:
677  case 3:
678  case 4:
679 
680  /*
681  * Exists, not empty
682  */
683  fprintf(stderr,
684  _("%s: directory \"%s\" exists but is not empty\n"),
685  progname, dirname);
687  case -1:
688 
689  /*
690  * Access problem
691  */
692  fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"),
693  progname, dirname, strerror(errno));
695  }
696 }
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 1666 of file pg_basebackup.c.

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

Referenced by ReceiveAndUnpackTarFile().

1667 {
1668  char filename[MAXPGPATH];
1669  FILE *cf;
1670 
1671  sprintf(filename, "%s/recovery.conf", basedir);
1672 
1673  cf = fopen(filename, "w");
1674  if (cf == NULL)
1675  {
1676  fprintf(stderr, _("%s: could not create file \"%s\": %s\n"), progname, filename, strerror(errno));
1678  }
1679 
1680  if (fwrite(recoveryconfcontents->data, recoveryconfcontents->len, 1, cf) != 1)
1681  {
1682  fprintf(stderr,
1683  _("%s: could not write to file \"%s\": %s\n"),
1684  progname, filename, strerror(errno));
1686  }
1687 
1688  fclose(cf);
1689 }
static PQExpBuffer recoveryconfcontents
const char * progname
Definition: pg_standby.c:37
static char * basedir
Definition: pg_basebackup.c:77
#define MAXPGPATH
#define NULL
Definition: c.h:229
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 888 of file pg_basebackup.c.

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

893 {
894 #ifdef HAVE_LIBZ
895  if (ztarfile != NULL)
896  {
897  if (gzwrite(ztarfile, buf, r) != r)
898  {
899  fprintf(stderr,
900  _("%s: could not write to compressed file \"%s\": %s\n"),
901  progname, current_file, get_gz_error(ztarfile));
903  }
904  }
905  else
906 #endif
907  {
908  if (fwrite(buf, r, 1, tarfile) != 1)
909  {
910  fprintf(stderr, _("%s: could not write to file \"%s\": %s\n"),
911  progname, current_file, strerror(errno));
913  }
914  }
915 }
const char * progname
Definition: pg_standby.c:37
static char * buf
Definition: pg_test_fsync.c:66
#define NULL
Definition: c.h:229
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 115 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 85 of file pg_basebackup.c.

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

bool do_sync = true
static

Definition at line 89 of file pg_basebackup.c.

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

bool fastcheckpoint = false
static

Definition at line 87 of file pg_basebackup.c.

Referenced by BaseBackup(), and main().

bool found_existing_pgdata = false
static

Definition at line 98 of file pg_basebackup.c.

Referenced by cleanup_directories_atexit(), and main().

bool found_existing_xlogdir = false
static

Definition at line 100 of file pg_basebackup.c.

Referenced by cleanup_directories_atexit(), and main().

bool found_tablespace_dirs = false
static

Definition at line 102 of file pg_basebackup.c.

Referenced by BaseBackup(), and cleanup_directories_atexit().

int has_xlogendptr = 0
static

Definition at line 122 of file pg_basebackup.c.

Referenced by BaseBackup(), and reached_end_position().

bool in_log_streamer = false
static

Definition at line 116 of file pg_basebackup.c.

Referenced by cleanup_directories_atexit(), and LogStreamerMain().

IncludeWal includewal = STREAM_WAL
static

Definition at line 86 of file pg_basebackup.c.

Referenced by BaseBackup(), and main().

pg_time_t last_progress_report = 0
static

Definition at line 91 of file pg_basebackup.c.

Referenced by progress_report().

bool made_new_pgdata = false
static

Definition at line 97 of file pg_basebackup.c.

Referenced by cleanup_directories_atexit(), and main().

bool made_new_xlogdir = false
static

Definition at line 99 of file pg_basebackup.c.

Referenced by cleanup_directories_atexit(), and main().

bool made_tablespace_dirs = false
static

Definition at line 101 of file pg_basebackup.c.

Referenced by BaseBackup(), and cleanup_directories_atexit().

int32 maxrate = 0
static

Definition at line 92 of file pg_basebackup.c.

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

bool noclean = false
static

Definition at line 82 of file pg_basebackup.c.

Referenced by cleanup_directories_atexit(), and main().

PQExpBuffer recoveryconfcontents = NULL
static

Definition at line 128 of file pg_basebackup.c.

char* replication_slot = NULL
static

Definition at line 93 of file pg_basebackup.c.

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

bool showprogress = false
static

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

Referenced by LogStreamerMain(), and main().

TablespaceList tablespace_dirs = {NULL, NULL}
static

Definition at line 78 of file pg_basebackup.c.

int tablespacecount
static

Definition at line 107 of file pg_basebackup.c.

Referenced by BaseBackup(), and progress_report().

bool temp_replication_slot = true
static

Definition at line 94 of file pg_basebackup.c.

Referenced by main(), and StartLogStreamer().

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

Definition at line 88 of file pg_basebackup.c.

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

char* xlog_dir = ""
static

Definition at line 79 of file pg_basebackup.c.

Referenced by cleanup_directories_atexit(), and main().

XLogRecPtr xlogendptr
static

Definition at line 119 of file pg_basebackup.c.

Referenced by BaseBackup(), and reached_end_position().