1
0
mirror of https://github.com/postgrespro/pg_probackup.git synced 2025-01-09 14:45:47 +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 */
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
{
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.
* NOTE. We can check it only on master, though.
*/
if(!from_replica)
if (exclusive_backup)
{
char label_path[MAXPGPATH];
join_path_components(label_path, pgdata, PG_BACKUP_LABEL_FILE);
@ -399,13 +406,15 @@ do_backup(void)
backup_conn = pgut_connect(pgut_dbname);
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_block_size("block_size", BLCKSZ);
confirm_block_size("wal_block_size", XLOG_BLCKSZ);
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.stream = stream_wal;
@ -489,7 +498,6 @@ do_backup(void)
static void
check_server_version(void)
{
static int server_version = 0;
/* confirm server version */
server_version = PQserverVersion(backup_conn);
@ -506,6 +514,9 @@ check_server_version(void)
server_version / 10000,
(server_version / 100) % 100,
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'*/
params[1] = smooth ? "false" : "true";
if (from_replica)
if (!exclusive_backup)
res = pgut_execute(backup_conn,
"SELECT pg_start_backup($1, $2, false)",
2,
@ -592,6 +603,8 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup)
2,
params);
backup_in_progress = true;
/* Extract timeline and LSN from results of pg_start_backup() */
XLogDataFromLSN(PQgetvalue(res, 0, 0), &xlogid, &xrecoff);
/* Calculate LSN */
@ -629,13 +642,13 @@ pg_switch_wal(void)
NULL);
PQclear(res);
#if PG_VERSION_NUM >= 100000
if (server_version >= 100000)
res = pgut_execute(backup_conn, "SELECT * FROM pg_switch_wal()", 0,
NULL);
#else
else
res = pgut_execute(backup_conn, "SELECT * FROM pg_switch_xlog()", 0,
NULL);
#endif
PQclear(res);
}
@ -891,12 +904,15 @@ pg_stop_backup(pgBackup *backup)
time_t recovery_time;
TransactionId recovery_xid;
if (!backup_in_progress)
elog(FATAL, "backup is not in progress");
/* Remove annoying NOTICE messages generated by backend */
res = pgut_execute(backup_conn, "SET client_min_messages = warning;",
0, NULL);
PQclear(res);
if (from_replica)
if (!exclusive_backup)
/*
* Stop the non-exclusive backup. Besides stop_lsn it returns from
* 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()",
0, NULL);
backup_in_progress = false;
/* Extract timeline and LSN from results of pg_stop_backup() */
XLogDataFromLSN(PQgetvalue(res, 0, 0), &xlogid, &xrecoff);
/* Calculate LSN */
stop_backup_lsn = (XLogRecPtr) ((uint64) xlogid << 32) | xrecoff;
/* Write backup_label and tablespace_map for backup from replica */
if (from_replica)
if (!exclusive_backup)
{
char path[MAXPGPATH];
char backup_label[MAXPGPATH];
@ -1081,8 +1099,6 @@ fileExists(const char *path)
static void
backup_cleanup(bool fatal, void *userdata)
{
char path[MAXPGPATH];
/*
* Update status of backup in BACKUP_CONTROL_FILE to ERROR.
* 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
* TODO Do we need this?
* If backup is in progress, notify stop of backup to PostgreSQL
*/
join_path_components(path, pgdata, PG_BACKUP_LABEL_FILE);
if (fileExists(path))
if (backup_in_progress)
{
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 */
}
}