Split pg_start_backup() and pg_stop_backup() into two pieces
Move the actual functionality into a separate function that's easier to call internally, and change the SQL-callable function to be a wrapper calling this. Also create a pg_abort_backup() function, only callable internally, that does only the most vital parts of pg_stop_backup(), making it safe(r) to call from error handlers.
This commit is contained in:
parent
ca63029eac
commit
4448917d51
|
@ -8308,6 +8308,21 @@ pg_start_backup(PG_FUNCTION_ARGS)
|
||||||
text *backupid = PG_GETARG_TEXT_P(0);
|
text *backupid = PG_GETARG_TEXT_P(0);
|
||||||
bool fast = PG_GETARG_BOOL(1);
|
bool fast = PG_GETARG_BOOL(1);
|
||||||
char *backupidstr;
|
char *backupidstr;
|
||||||
|
XLogRecPtr startpoint;
|
||||||
|
char startxlogstr[MAXFNAMELEN];
|
||||||
|
|
||||||
|
backupidstr = text_to_cstring(backupid);
|
||||||
|
|
||||||
|
startpoint = do_pg_start_backup(backupidstr, fast);
|
||||||
|
|
||||||
|
snprintf(startxlogstr, sizeof(startxlogstr), "%X/%X",
|
||||||
|
startpoint.xlogid, startpoint.xrecoff);
|
||||||
|
PG_RETURN_TEXT_P(cstring_to_text(startxlogstr));
|
||||||
|
}
|
||||||
|
|
||||||
|
XLogRecPtr
|
||||||
|
do_pg_start_backup(const char *backupidstr, bool fast)
|
||||||
|
{
|
||||||
XLogRecPtr checkpointloc;
|
XLogRecPtr checkpointloc;
|
||||||
XLogRecPtr startpoint;
|
XLogRecPtr startpoint;
|
||||||
pg_time_t stamp_time;
|
pg_time_t stamp_time;
|
||||||
|
@ -8335,8 +8350,6 @@ pg_start_backup(PG_FUNCTION_ARGS)
|
||||||
errmsg("WAL level not sufficient for making an online backup"),
|
errmsg("WAL level not sufficient for making an online backup"),
|
||||||
errhint("wal_level must be set to \"archive\" or \"hot_standby\" at server start.")));
|
errhint("wal_level must be set to \"archive\" or \"hot_standby\" at server start.")));
|
||||||
|
|
||||||
backupidstr = text_to_cstring(backupid);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mark backup active in shared memory. We must do full-page WAL writes
|
* Mark backup active in shared memory. We must do full-page WAL writes
|
||||||
* during an on-line backup even if not doing so at other times, because
|
* during an on-line backup even if not doing so at other times, because
|
||||||
|
@ -8459,9 +8472,7 @@ pg_start_backup(PG_FUNCTION_ARGS)
|
||||||
/*
|
/*
|
||||||
* We're done. As a convenience, return the starting WAL location.
|
* We're done. As a convenience, return the starting WAL location.
|
||||||
*/
|
*/
|
||||||
snprintf(xlogfilename, sizeof(xlogfilename), "%X/%X",
|
return startpoint;
|
||||||
startpoint.xlogid, startpoint.xrecoff);
|
|
||||||
PG_RETURN_TEXT_P(cstring_to_text(xlogfilename));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Error cleanup callback for pg_start_backup */
|
/* Error cleanup callback for pg_start_backup */
|
||||||
|
@ -8489,6 +8500,19 @@ pg_start_backup_callback(int code, Datum arg)
|
||||||
*/
|
*/
|
||||||
Datum
|
Datum
|
||||||
pg_stop_backup(PG_FUNCTION_ARGS)
|
pg_stop_backup(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
XLogRecPtr stoppoint;
|
||||||
|
char stopxlogstr[MAXFNAMELEN];
|
||||||
|
|
||||||
|
stoppoint = do_pg_stop_backup();
|
||||||
|
|
||||||
|
snprintf(stopxlogstr, sizeof(stopxlogstr), "%X/%X",
|
||||||
|
stoppoint.xlogid, stoppoint.xrecoff);
|
||||||
|
PG_RETURN_TEXT_P(cstring_to_text(stopxlogstr));
|
||||||
|
}
|
||||||
|
|
||||||
|
XLogRecPtr
|
||||||
|
do_pg_stop_backup(void)
|
||||||
{
|
{
|
||||||
XLogRecPtr startpoint;
|
XLogRecPtr startpoint;
|
||||||
XLogRecPtr stoppoint;
|
XLogRecPtr stoppoint;
|
||||||
|
@ -8699,9 +8723,35 @@ pg_stop_backup(PG_FUNCTION_ARGS)
|
||||||
/*
|
/*
|
||||||
* We're done. As a convenience, return the ending WAL location.
|
* We're done. As a convenience, return the ending WAL location.
|
||||||
*/
|
*/
|
||||||
snprintf(stopxlogfilename, sizeof(stopxlogfilename), "%X/%X",
|
return stoppoint;
|
||||||
stoppoint.xlogid, stoppoint.xrecoff);
|
}
|
||||||
PG_RETURN_TEXT_P(cstring_to_text(stopxlogfilename));
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* do_pg_abort_backup: abort a running backup
|
||||||
|
*
|
||||||
|
* This does just the most basic steps of pg_stop_backup(), by taking the
|
||||||
|
* system out of backup mode, thus making it a lot more safe to call from
|
||||||
|
* an error handler.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
do_pg_abort_backup(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* OK to clear forcePageWrites
|
||||||
|
*/
|
||||||
|
LWLockAcquire(WALInsertLock, LW_EXCLUSIVE);
|
||||||
|
XLogCtl->Insert.forcePageWrites = false;
|
||||||
|
LWLockRelease(WALInsertLock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove backup label file
|
||||||
|
*/
|
||||||
|
if (unlink(BACKUP_LABEL_FILE) != 0)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode_for_file_access(),
|
||||||
|
errmsg("could not remove file \"%s\": %m",
|
||||||
|
BACKUP_LABEL_FILE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -312,4 +312,8 @@ extern void HandleStartupProcInterrupts(void);
|
||||||
extern void StartupProcessMain(void);
|
extern void StartupProcessMain(void);
|
||||||
extern void WakeupRecovery(void);
|
extern void WakeupRecovery(void);
|
||||||
|
|
||||||
|
extern XLogRecPtr do_pg_start_backup(const char *backupidstr, bool fast);
|
||||||
|
extern XLogRecPtr do_pg_stop_backup(void);
|
||||||
|
extern void do_pg_abort_backup(void);
|
||||||
|
|
||||||
#endif /* XLOG_H */
|
#endif /* XLOG_H */
|
||||||
|
|
Loading…
Reference in New Issue