1
0
mirror of https://github.com/postgrespro/pg_probackup.git synced 2025-01-24 11:46:31 +02:00

Do non-exclusive backup for PostgreSQL 9.6+

This commit is contained in:
Arthur Zakirov 2017-05-22 14:22:20 +03:00
parent 7a294ad0c9
commit 66d3e97e26

View File

@ -53,6 +53,13 @@ static int is_ptrack_enable = false;
/* Backup connection */ /* Backup connection */
static PGconn *backup_conn = NULL; static PGconn *backup_conn = NULL;
/* PostgreSQL server version from "backup_conn" */
static int server_version = 0;
static bool exclusive_backup = false;
/* Is pg_start_backup() was executed */
static bool backup_in_progress = false;
typedef struct typedef struct
{ {
const char *from_root; const char *from_root;
@ -159,7 +166,7 @@ do_backup_database(parray *backup_list)
* If backup_label does not exist in $PGDATA, stop taking backup. * If backup_label does not exist in $PGDATA, stop taking backup.
* NOTE. We can check it only on master, though. * NOTE. We can check it only on master, though.
*/ */
if(!from_replica) if (exclusive_backup)
{ {
char label_path[MAXPGPATH]; char label_path[MAXPGPATH];
join_path_components(label_path, pgdata, PG_BACKUP_LABEL_FILE); join_path_components(label_path, pgdata, PG_BACKUP_LABEL_FILE);
@ -399,13 +406,15 @@ do_backup(void)
backup_conn = pgut_connect(pgut_dbname); backup_conn = pgut_connect(pgut_dbname);
pgut_atexit_push(backup_disconnect, NULL); pgut_atexit_push(backup_disconnect, NULL);
/* Confirm that this server version is supported */
check_server_version();
/* Confirm data block size and xlog block size are compatible */ /* Confirm data block size and xlog block size are compatible */
confirm_block_size("block_size", BLCKSZ); confirm_block_size("block_size", BLCKSZ);
confirm_block_size("wal_block_size", XLOG_BLCKSZ); confirm_block_size("wal_block_size", XLOG_BLCKSZ);
from_replica = pg_is_in_recovery(); from_replica = pg_is_in_recovery();
/* Confirm that this server version is supported */
check_server_version();
current.checksum_version = get_data_checksum_version(true); current.checksum_version = get_data_checksum_version(true);
current.stream = stream_wal; current.stream = stream_wal;
@ -489,7 +498,6 @@ do_backup(void)
static void static void
check_server_version(void) check_server_version(void)
{ {
static int server_version = 0;
/* confirm server version */ /* confirm server version */
server_version = PQserverVersion(backup_conn); server_version = PQserverVersion(backup_conn);
@ -506,6 +514,9 @@ check_server_version(void)
server_version / 10000, server_version / 10000,
(server_version / 100) % 100, (server_version / 100) % 100,
server_version % 100, "9.6"); server_version % 100, "9.6");
/* Do exclusive backup only for PostgreSQL 9.5 */
exclusive_backup = server_version < 90600;
} }
/* /*
@ -581,7 +592,7 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup)
/* 2nd argument is 'fast'*/ /* 2nd argument is 'fast'*/
params[1] = smooth ? "false" : "true"; params[1] = smooth ? "false" : "true";
if (from_replica) if (!exclusive_backup)
res = pgut_execute(backup_conn, res = pgut_execute(backup_conn,
"SELECT pg_start_backup($1, $2, false)", "SELECT pg_start_backup($1, $2, false)",
2, 2,
@ -592,6 +603,8 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup)
2, 2,
params); params);
backup_in_progress = true;
/* Extract timeline and LSN from results of pg_start_backup() */ /* Extract timeline and LSN from results of pg_start_backup() */
XLogDataFromLSN(PQgetvalue(res, 0, 0), &xlogid, &xrecoff); XLogDataFromLSN(PQgetvalue(res, 0, 0), &xlogid, &xrecoff);
/* Calculate LSN */ /* Calculate LSN */
@ -629,13 +642,13 @@ pg_switch_wal(void)
NULL); NULL);
PQclear(res); PQclear(res);
#if PG_VERSION_NUM >= 100000 if (server_version >= 100000)
res = pgut_execute(backup_conn, "SELECT * FROM pg_switch_wal()", 0, res = pgut_execute(backup_conn, "SELECT * FROM pg_switch_wal()", 0,
NULL); NULL);
#else else
res = pgut_execute(backup_conn, "SELECT * FROM pg_switch_xlog()", 0, res = pgut_execute(backup_conn, "SELECT * FROM pg_switch_xlog()", 0,
NULL); NULL);
#endif
PQclear(res); PQclear(res);
} }
@ -891,12 +904,15 @@ pg_stop_backup(pgBackup *backup)
time_t recovery_time; time_t recovery_time;
TransactionId recovery_xid; TransactionId recovery_xid;
if (!backup_in_progress)
elog(FATAL, "backup is not in progress");
/* Remove annoying NOTICE messages generated by backend */ /* Remove annoying NOTICE messages generated by backend */
res = pgut_execute(backup_conn, "SET client_min_messages = warning;", res = pgut_execute(backup_conn, "SET client_min_messages = warning;",
0, NULL); 0, NULL);
PQclear(res); PQclear(res);
if (from_replica) if (!exclusive_backup)
/* /*
* Stop the non-exclusive backup. Besides stop_lsn it returns from * Stop the non-exclusive backup. Besides stop_lsn it returns from
* pg_stop_backup(false) copy of the backup label and tablespace map * pg_stop_backup(false) copy of the backup label and tablespace map
@ -914,13 +930,15 @@ pg_stop_backup(pgBackup *backup)
" FROM pg_stop_backup()", " FROM pg_stop_backup()",
0, NULL); 0, NULL);
backup_in_progress = false;
/* Extract timeline and LSN from results of pg_stop_backup() */ /* Extract timeline and LSN from results of pg_stop_backup() */
XLogDataFromLSN(PQgetvalue(res, 0, 0), &xlogid, &xrecoff); XLogDataFromLSN(PQgetvalue(res, 0, 0), &xlogid, &xrecoff);
/* Calculate LSN */ /* Calculate LSN */
stop_backup_lsn = (XLogRecPtr) ((uint64) xlogid << 32) | xrecoff; stop_backup_lsn = (XLogRecPtr) ((uint64) xlogid << 32) | xrecoff;
/* Write backup_label and tablespace_map for backup from replica */ /* Write backup_label and tablespace_map for backup from replica */
if (from_replica) if (!exclusive_backup)
{ {
char path[MAXPGPATH]; char path[MAXPGPATH];
char backup_label[MAXPGPATH]; char backup_label[MAXPGPATH];
@ -1081,8 +1099,6 @@ fileExists(const char *path)
static void static void
backup_cleanup(bool fatal, void *userdata) backup_cleanup(bool fatal, void *userdata)
{ {
char path[MAXPGPATH];
/* /*
* Update status of backup in BACKUP_CONTROL_FILE to ERROR. * Update status of backup in BACKUP_CONTROL_FILE to ERROR.
* end_time != 0 means backup finished * end_time != 0 means backup finished
@ -1096,13 +1112,11 @@ backup_cleanup(bool fatal, void *userdata)
} }
/* /*
* If backup_label exists in $PGDATA, notify stop of backup to PostgreSQL * If backup is in progress, notify stop of backup to PostgreSQL
* TODO Do we need this?
*/ */
join_path_components(path, pgdata, PG_BACKUP_LABEL_FILE); if (backup_in_progress)
if (fileExists(path))
{ {
elog(LOG, "%s exists, stop backup", PG_BACKUP_LABEL_FILE); elog(LOG, "backup in progress, stop backup");
pg_stop_backup(NULL); /* don't care stop_lsn on error case */ pg_stop_backup(NULL); /* don't care stop_lsn on error case */
} }
} }