mirror of
https://github.com/postgres/postgres.git
synced 2025-07-11 10:01:57 +03:00
Fix minor problems with non-exclusive backup cleanup.
The previous coding imagined that it could call before_shmem_exit() when a non-exclusive backup began and then remove the previously-added handler by calling cancel_before_shmem_exit() when that backup ended. However, this only works provided that nothing else in the system has registered a before_shmem_exit() hook in the interim, because cancel_before_shmem_exit() is documented to remove a callback only if it is the latest callback registered. It also only works if nothing can ERROR out between the time that sessionBackupState is reset and the time that cancel_before_shmem_exit(), which doesn't seem to be strictly true. To fix, leave the handler installed for the lifetime of the session, arrange to install it just once, and teach it to quietly do nothing if there isn't a non-exclusive backup in process. This is a bug, but for now I'm not going to back-patch, because the consequences are minor. It's possible to cause a spurious warning to be generated, but that doesn't really matter. It's also possible to trigger an assertion failure, but production builds shouldn't have assertions enabled. Patch by me, reviewed by Kyotaro Horiguchi, Michael Paquier (who preferred a different approach, but got outvoted), Fujii Masao, and Tom Lane, and with comments by various others. Discussion: http://postgr.es/m/CA+TgmobMjnyBfNhGTKQEDbqXYE3_rXWpc4CM63fhyerNCes3mA@mail.gmail.com
This commit is contained in:
@ -65,7 +65,6 @@ static int64 _tarWriteDir(const char *pathbuf, int basepathlen, struct stat *sta
|
||||
bool sizeonly);
|
||||
static void send_int8_string(StringInfoData *buf, int64 intval);
|
||||
static void SendBackupHeader(List *tablespaces);
|
||||
static void base_backup_cleanup(int code, Datum arg);
|
||||
static void perform_base_backup(basebackup_options *opt);
|
||||
static void parse_basebackup_options(List *options, basebackup_options *opt);
|
||||
static void SendXlogRecPtrResult(XLogRecPtr ptr, TimeLineID tli);
|
||||
@ -216,17 +215,6 @@ static const char *const noChecksumFiles[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Called when ERROR or FATAL happens in perform_base_backup() after
|
||||
* we have started the backup - make sure we end it!
|
||||
*/
|
||||
static void
|
||||
base_backup_cleanup(int code, Datum arg)
|
||||
{
|
||||
do_pg_abort_backup();
|
||||
}
|
||||
|
||||
/*
|
||||
* Actually do a base backup for the specified tablespaces.
|
||||
*
|
||||
@ -265,7 +253,7 @@ perform_base_backup(basebackup_options *opt)
|
||||
* do_pg_stop_backup() should be inside the error cleanup block!
|
||||
*/
|
||||
|
||||
PG_ENSURE_ERROR_CLEANUP(base_backup_cleanup, (Datum) 0);
|
||||
PG_ENSURE_ERROR_CLEANUP(do_pg_abort_backup, BoolGetDatum(false));
|
||||
{
|
||||
ListCell *lc;
|
||||
tablespaceinfo *ti;
|
||||
@ -374,7 +362,7 @@ perform_base_backup(basebackup_options *opt)
|
||||
|
||||
endptr = do_pg_stop_backup(labelfile->data, !opt->nowait, &endtli);
|
||||
}
|
||||
PG_END_ENSURE_ERROR_CLEANUP(base_backup_cleanup, (Datum) 0);
|
||||
PG_END_ENSURE_ERROR_CLEANUP(do_pg_abort_backup, BoolGetDatum(false));
|
||||
|
||||
|
||||
if (opt->includewal)
|
||||
|
Reference in New Issue
Block a user