mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-08-27 00:37:19 +02:00
Don't forget about failed fsync() requests.
If fsync() fails, md.c must keep the request in its bitmap, so that future attempts will try again. Back-patch to all supported releases. Author: Thomas Munro Reviewed-by: Amit Kapila Reported-by: Andrew Gierth Discussion: https://postgr.es/m/87y3i1ia4w.fsf%40news-spur.riddles.org.uk
This commit is contained in:
parent
71b2951ccc
commit
a4d6d6a25c
@ -1148,10 +1148,8 @@ mdsync(void)
|
|||||||
* The bitmap manipulations are slightly tricky, because we can call
|
* The bitmap manipulations are slightly tricky, because we can call
|
||||||
* AbsorbFsyncRequests() inside the loop and that could result in
|
* AbsorbFsyncRequests() inside the loop and that could result in
|
||||||
* bms_add_member() modifying and even re-palloc'ing the bitmapsets.
|
* bms_add_member() modifying and even re-palloc'ing the bitmapsets.
|
||||||
* This is okay because we unlink each bitmapset from the hashtable
|
* So we detach it, but if we fail we'll merge it with any new
|
||||||
* entry before scanning it. That means that any incoming fsync
|
* requests that have arrived in the meantime.
|
||||||
* requests will be processed now if they reach the table before we
|
|
||||||
* begin to scan their fork.
|
|
||||||
*/
|
*/
|
||||||
for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
|
for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
|
||||||
{
|
{
|
||||||
@ -1161,7 +1159,8 @@ mdsync(void)
|
|||||||
entry->requests[forknum] = NULL;
|
entry->requests[forknum] = NULL;
|
||||||
entry->canceled[forknum] = false;
|
entry->canceled[forknum] = false;
|
||||||
|
|
||||||
while ((segno = bms_first_member(requests)) >= 0)
|
segno = -1;
|
||||||
|
while ((segno = bms_next_member(requests, segno)) >= 0)
|
||||||
{
|
{
|
||||||
int failures;
|
int failures;
|
||||||
|
|
||||||
@ -1242,6 +1241,7 @@ mdsync(void)
|
|||||||
longest = elapsed;
|
longest = elapsed;
|
||||||
total_elapsed += elapsed;
|
total_elapsed += elapsed;
|
||||||
processed++;
|
processed++;
|
||||||
|
requests = bms_del_member(requests, segno);
|
||||||
if (log_checkpoints)
|
if (log_checkpoints)
|
||||||
elog(DEBUG1, "checkpoint sync: number=%d file=%s time=%.3f msec",
|
elog(DEBUG1, "checkpoint sync: number=%d file=%s time=%.3f msec",
|
||||||
processed,
|
processed,
|
||||||
@ -1270,10 +1270,23 @@ mdsync(void)
|
|||||||
*/
|
*/
|
||||||
if (!FILE_POSSIBLY_DELETED(errno) ||
|
if (!FILE_POSSIBLY_DELETED(errno) ||
|
||||||
failures > 0)
|
failures > 0)
|
||||||
|
{
|
||||||
|
Bitmapset *new_requests;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need to merge these unsatisfied requests with
|
||||||
|
* any others that have arrived since we started.
|
||||||
|
*/
|
||||||
|
new_requests = entry->requests[forknum];
|
||||||
|
entry->requests[forknum] =
|
||||||
|
bms_join(new_requests, requests);
|
||||||
|
|
||||||
|
errno = save_errno;
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode_for_file_access(),
|
(errcode_for_file_access(),
|
||||||
errmsg("could not fsync file \"%s\": %m",
|
errmsg("could not fsync file \"%s\": %m",
|
||||||
path)));
|
path)));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ereport(DEBUG1,
|
ereport(DEBUG1,
|
||||||
(errcode_for_file_access(),
|
(errcode_for_file_access(),
|
||||||
|
Loading…
Reference in New Issue
Block a user