mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-12 18:34:36 +08:00
Fix race condition if a file is removed while pg_basebackup is running.
If a relation file was removed when the server-side counterpart of pg_basebackup was just about to open it to send it to the client, you'd get a "could not open file" error. Fix that. Backpatch to 9.1, this goes back to when pg_basebackup was introduced.
This commit is contained in:
parent
d57a97343e
commit
36e4456d78
@ -44,8 +44,8 @@ typedef struct
|
|||||||
|
|
||||||
|
|
||||||
static int64 sendDir(char *path, int basepathlen, bool sizeonly);
|
static int64 sendDir(char *path, int basepathlen, bool sizeonly);
|
||||||
static void sendFile(char *readfilename, char *tarfilename,
|
static bool sendFile(char *readfilename, char *tarfilename,
|
||||||
struct stat * statbuf);
|
struct stat * statbuf, bool missing_ok);
|
||||||
static void sendFileWithContent(const char *filename, const char *content);
|
static void sendFileWithContent(const char *filename, const char *content);
|
||||||
static void _tarWriteHeader(const char *filename, const char *linktarget,
|
static void _tarWriteHeader(const char *filename, const char *linktarget,
|
||||||
struct stat * statbuf);
|
struct stat * statbuf);
|
||||||
@ -199,7 +199,7 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir)
|
|||||||
XLOG_CONTROL_FILE)));
|
XLOG_CONTROL_FILE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
sendFile(XLOG_CONTROL_FILE, XLOG_CONTROL_FILE, &statbuf);
|
sendFile(XLOG_CONTROL_FILE, XLOG_CONTROL_FILE, &statbuf, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -712,11 +712,18 @@ sendDir(char *path, int basepathlen, bool sizeonly)
|
|||||||
}
|
}
|
||||||
else if (S_ISREG(statbuf.st_mode))
|
else if (S_ISREG(statbuf.st_mode))
|
||||||
{
|
{
|
||||||
/* Add size, rounded up to 512byte block */
|
bool sent = false;
|
||||||
size += ((statbuf.st_size + 511) & ~511);
|
|
||||||
if (!sizeonly)
|
if (!sizeonly)
|
||||||
sendFile(pathbuf, pathbuf + basepathlen + 1, &statbuf);
|
sent = sendFile(pathbuf, pathbuf + basepathlen + 1, &statbuf,
|
||||||
size += 512; /* Size of the header of the file */
|
true);
|
||||||
|
|
||||||
|
if (sent || sizeonly)
|
||||||
|
{
|
||||||
|
/* Add size, rounded up to 512byte block */
|
||||||
|
size += ((statbuf.st_size + 511) & ~511);
|
||||||
|
size += 512; /* Size of the header of the file */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ereport(WARNING,
|
ereport(WARNING,
|
||||||
@ -776,9 +783,17 @@ _tarChecksum(char *header)
|
|||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Given the member, write the TAR header & send the file */
|
/*
|
||||||
static void
|
* Given the member, write the TAR header & send the file.
|
||||||
sendFile(char *readfilename, char *tarfilename, struct stat * statbuf)
|
*
|
||||||
|
* If 'missing_ok' is true, will not throw an error if the file is not found.
|
||||||
|
*
|
||||||
|
* Returns true if the file was successfully sent, false if 'missing_ok',
|
||||||
|
* and the file did not exist.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
sendFile(char *readfilename, char *tarfilename, struct stat *statbuf,
|
||||||
|
bool missing_ok)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char buf[TAR_SEND_SIZE];
|
char buf[TAR_SEND_SIZE];
|
||||||
@ -788,9 +803,13 @@ sendFile(char *readfilename, char *tarfilename, struct stat * statbuf)
|
|||||||
|
|
||||||
fp = AllocateFile(readfilename, "rb");
|
fp = AllocateFile(readfilename, "rb");
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
|
{
|
||||||
|
if (errno == ENOENT && missing_ok)
|
||||||
|
return false;
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode_for_file_access(),
|
(errcode_for_file_access(),
|
||||||
errmsg("could not open file \"%s\": %m", readfilename)));
|
errmsg("could not open file \"%s\": %m", readfilename)));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some compilers will throw a warning knowing this test can never be true
|
* Some compilers will throw a warning knowing this test can never be true
|
||||||
@ -844,6 +863,8 @@ sendFile(char *readfilename, char *tarfilename, struct stat * statbuf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
FreeFile(fp);
|
FreeFile(fp);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user