diff options
Diffstat (limited to 'src/bin/pg_basebackup/pg_basebackup.c')
-rw-r--r-- | src/bin/pg_basebackup/pg_basebackup.c | 148 |
1 files changed, 108 insertions, 40 deletions
diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c index d6fef38760e..af1c4de58f9 100644 --- a/src/bin/pg_basebackup/pg_basebackup.c +++ b/src/bin/pg_basebackup/pg_basebackup.c @@ -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; + + if (is_postgresql_auto_conf && writerecoveryconf) + { + /* replace tar header */ + char header[512]; - padding = ((filesz + 511) & ~511) - filesz; - filesz += padding; + 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); /* |