1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-09 06:21:09 +03:00

Integrate recovery.conf into postgresql.conf

recovery.conf settings are now set in postgresql.conf (or other GUC
sources).  Currently, all the affected settings are PGC_POSTMASTER;
this could be refined in the future case by case.

Recovery is now initiated by a file recovery.signal.  Standby mode is
initiated by a file standby.signal.  The standby_mode setting is
gone.  If a recovery.conf file is found, an error is issued.

The trigger_file setting has been renamed to promote_trigger_file as
part of the move.

The documentation chapter "Recovery Configuration" has been integrated
into "Server Configuration".

pg_basebackup -R now appends settings to postgresql.auto.conf and
creates a standby.signal file.

Author: Fujii Masao <masao.fujii@gmail.com>
Author: Simon Riggs <simon@2ndquadrant.com>
Author: Abhijit Menon-Sen <ams@2ndquadrant.com>
Author: Sergei Kornilov <sk@zsrv.org>
Discussion: https://www.postgresql.org/message-id/flat/607741529606767@web3g.yandex.ru/
This commit is contained in:
Peter Eisentraut
2018-11-25 16:31:16 +01:00
parent ab69ea9fee
commit 2dedf4d9a8
40 changed files with 1408 additions and 1178 deletions

View File

@@ -131,7 +131,7 @@ static int has_xlogendptr = 0;
static volatile LONG has_xlogendptr = 0;
#endif
/* Contents of recovery.conf to be generated */
/* Contents of configuration file to be generated */
static PQExpBuffer recoveryconfcontents = NULL;
/* Function headers */
@@ -346,7 +346,7 @@ usage(void)
printf(_(" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n"
" (in kB/s, or use suffix \"k\" or \"M\")\n"));
printf(_(" -R, --write-recovery-conf\n"
" write recovery.conf for replication\n"));
" write configuration for replication\n"));
printf(_(" -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
" relocate tablespace in OLDDIR to NEWDIR\n"));
printf(_(" --waldir=WALDIR location for the write-ahead log directory\n"));
@@ -974,6 +974,9 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
bool basetablespace = PQgetisnull(res, rownum, 0);
bool in_tarhdr = true;
bool skip_file = false;
bool is_postgresql_auto_conf = false;
bool found_postgresql_auto_conf = false;
int file_padding_len = 0;
size_t tarhdrsz = 0;
pgoff_t filesz = 0;
@@ -1113,8 +1116,8 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
{
/*
* End of chunk. If requested, and this is the base tablespace,
* write recovery.conf into the tarfile. When done, close the file
* (but not stdout).
* write configuration file into the tarfile. When done, close the
* file (but not stdout).
*
* Also, write two completely empty blocks at the end of the tar
* file, as required by some tar programs.
@@ -1126,19 +1129,31 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
if (basetablespace && writerecoveryconf)
{
char header[512];
int padding;
tarCreateHeader(header, "recovery.conf", NULL,
recoveryconfcontents->len,
if (!found_postgresql_auto_conf)
{
int padding;
tarCreateHeader(header, "postgresql.auto.conf", NULL,
recoveryconfcontents->len,
pg_file_create_mode, 04000, 02000,
time(NULL));
padding = ((recoveryconfcontents->len + 511) & ~511) - recoveryconfcontents->len;
WRITE_TAR_DATA(header, sizeof(header));
WRITE_TAR_DATA(recoveryconfcontents->data, recoveryconfcontents->len);
if (padding)
WRITE_TAR_DATA(zerobuf, padding);
}
tarCreateHeader(header, "standby.signal", NULL,
0, /* zero-length file */
pg_file_create_mode, 04000, 02000,
time(NULL));
padding = ((recoveryconfcontents->len + 511) & ~511) - recoveryconfcontents->len;
WRITE_TAR_DATA(header, sizeof(header));
WRITE_TAR_DATA(recoveryconfcontents->data, recoveryconfcontents->len);
if (padding)
WRITE_TAR_DATA(zerobuf, padding);
WRITE_TAR_DATA(zerobuf, 511);
}
/* 2 * 512 bytes empty data at end of file */
@@ -1182,8 +1197,8 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
if (!writerecoveryconf || !basetablespace)
{
/*
* When not writing recovery.conf, or when not working on the base
* tablespace, we never have to look for an existing recovery.conf
* When not writing config file, or when not working on the base
* tablespace, we never have to look for an existing configuration
* file in the stream.
*/
WRITE_TAR_DATA(copybuf, r);
@@ -1191,7 +1206,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
else
{
/*
* Look for a recovery.conf in the existing tar stream. If it's
* Look for a config file in the existing tar stream. If it's
* there, we must skip it so we can later overwrite it with our
* own version of the file.
*
@@ -1235,29 +1250,46 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
{
/*
* We have the complete header structure in tarhdr,
* look at the file metadata: - the subsequent file
* contents have to be skipped if the filename is
* recovery.conf - find out the size of the file
* padded to the next multiple of 512
* look at the file metadata: we may want append
* recovery info into postgresql.auto.conf and skip
* standby.signal file. In both cases we must
* calculate tar padding
*/
int padding;
skip_file = (strcmp(&tarhdr[0], "recovery.conf") == 0);
skip_file = (strcmp(&tarhdr[0], "standby.signal") == 0);
is_postgresql_auto_conf = (strcmp(&tarhdr[0], "postgresql.auto.conf") == 0);
filesz = read_tar_number(&tarhdr[124], 12);
file_padding_len = ((filesz + 511) & ~511) - filesz;
padding = ((filesz + 511) & ~511) - filesz;
filesz += padding;
if (is_postgresql_auto_conf && writerecoveryconf)
{
/* replace tar header */
char header[512];
tarCreateHeader(header, "postgresql.auto.conf", NULL,
filesz + recoveryconfcontents->len,
pg_file_create_mode, 04000, 02000,
time(NULL));
WRITE_TAR_DATA(header, sizeof(header));
}
else
{
/* copy stream with padding */
filesz += file_padding_len;
if (!skip_file)
{
/*
* If we're not skipping the file, write the
* tar header unmodified.
*/
WRITE_TAR_DATA(tarhdr, 512);
}
}
/* Next part is the file, not the header */
in_tarhdr = false;
/*
* If we're not skipping the file, write the tar
* header unmodified.
*/
if (!skip_file)
WRITE_TAR_DATA(tarhdr, 512);
}
}
else
@@ -1281,6 +1313,32 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
pos += bytes2write;
filesz -= bytes2write;
}
else if (is_postgresql_auto_conf && writerecoveryconf)
{
/* append recovery config to postgresql.auto.conf */
int padding;
int tailsize;
tailsize = (512 - file_padding_len) + recoveryconfcontents->len;
padding = ((tailsize + 511) & ~511) - tailsize;
WRITE_TAR_DATA(recoveryconfcontents->data, recoveryconfcontents->len);
if (padding)
{
char zerobuf[512];
MemSet(zerobuf, 0, sizeof(zerobuf));
WRITE_TAR_DATA(zerobuf, padding);
}
/* skip original file padding */
is_postgresql_auto_conf = false;
skip_file = true;
filesz += file_padding_len;
found_postgresql_auto_conf = true;
}
else
{
/*
@@ -1289,6 +1347,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
*/
in_tarhdr = true;
skip_file = false;
is_postgresql_auto_conf = false;
tarhdrsz = 0;
filesz = 0;
}
@@ -1614,7 +1673,7 @@ escape_quotes(const char *src)
}
/*
* Create a recovery.conf file in memory using a PQExpBuffer
* Create a configuration file in memory using a PQExpBuffer
*/
static void
GenerateRecoveryConf(PGconn *conn)
@@ -1638,8 +1697,6 @@ GenerateRecoveryConf(PGconn *conn)
disconnect_and_exit(1);
}
appendPQExpBufferStr(recoveryconfcontents, "standby_mode = 'on'\n");
initPQExpBuffer(&conninfo_buf);
for (option = connOptions; option && option->keyword; option++)
{
@@ -1698,8 +1755,9 @@ GenerateRecoveryConf(PGconn *conn)
/*
* Write a recovery.conf file into the directory specified in basedir,
* Write the configuration file into the directory specified in basedir,
* with the contents already collected in memory.
* Then write the signal file into the basedir also.
*/
static void
WriteRecoveryConf(void)
@@ -1707,12 +1765,12 @@ WriteRecoveryConf(void)
char filename[MAXPGPATH];
FILE *cf;
sprintf(filename, "%s/recovery.conf", basedir);
snprintf(filename, MAXPGPATH, "%s/%s", basedir, "postgresql.auto.conf");
cf = fopen(filename, "w");
cf = fopen(filename, "a");
if (cf == NULL)
{
fprintf(stderr, _("%s: could not create file \"%s\": %s\n"), progname, filename, strerror(errno));
fprintf(stderr, _("%s: could not open file \"%s\": %s\n"), progname, filename, strerror(errno));
disconnect_and_exit(1);
}
@@ -1725,6 +1783,16 @@ WriteRecoveryConf(void)
}
fclose(cf);
snprintf(filename, MAXPGPATH, "%s/%s", basedir, "standby.signal");
cf = fopen(filename, "w");
if (cf == NULL)
{
fprintf(stderr, _("%s: could not create file \"%s\": %s\n"), progname, filename, strerror(errno));
disconnect_and_exit(1);
}
fclose(cf);
}
@@ -1780,7 +1848,7 @@ BaseBackup(void)
}
/*
* Build contents of recovery.conf if requested
* Build contents of configuration file if requested
*/
if (writerecoveryconf)
GenerateRecoveryConf(conn);
@@ -2094,7 +2162,7 @@ BaseBackup(void)
#endif
}
/* Free the recovery.conf contents */
/* Free the configuration file contents */
destroyPQExpBuffer(recoveryconfcontents);
/*