Skip to content

Commit 2b2010d

Browse files
committed
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
1 parent 4134489 commit 2b2010d

File tree

1 file changed

+18
-5
lines changed
  • src/backend/storage/smgr

1 file changed

+18
-5
lines changed

src/backend/storage/smgr/md.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,10 +1074,8 @@ mdsync(void)
10741074
* The bitmap manipulations are slightly tricky, because we can call
10751075
* AbsorbFsyncRequests() inside the loop and that could result in
10761076
* bms_add_member() modifying and even re-palloc'ing the bitmapsets.
1077-
* This is okay because we unlink each bitmapset from the hashtable
1078-
* entry before scanning it. That means that any incoming fsync
1079-
* requests will be processed now if they reach the table before we
1080-
* begin to scan their fork.
1077+
* So we detach it, but if we fail we'll merge it with any new
1078+
* requests that have arrived in the meantime.
10811079
*/
10821080
for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
10831081
{
@@ -1087,7 +1085,8 @@ mdsync(void)
10871085
entry->requests[forknum] = NULL;
10881086
entry->canceled[forknum] = false;
10891087

1090-
while ((segno = bms_first_member(requests)) >= 0)
1088+
segno = -1;
1089+
while ((segno = bms_next_member(requests, segno)) >= 0)
10911090
{
10921091
int failures;
10931092

@@ -1166,6 +1165,7 @@ mdsync(void)
11661165
longest = elapsed;
11671166
total_elapsed += elapsed;
11681167
processed++;
1168+
requests = bms_del_member(requests, segno);
11691169
if (log_checkpoints)
11701170
elog(DEBUG1, "checkpoint sync: number=%d file=%s time=%.3f msec",
11711171
processed,
@@ -1194,10 +1194,23 @@ mdsync(void)
11941194
*/
11951195
if (!FILE_POSSIBLY_DELETED(errno) ||
11961196
failures > 0)
1197+
{
1198+
Bitmapset *new_requests;
1199+
1200+
/*
1201+
* We need to merge these unsatisfied requests with
1202+
* any others that have arrived since we started.
1203+
*/
1204+
new_requests = entry->requests[forknum];
1205+
entry->requests[forknum] =
1206+
bms_join(new_requests, requests);
1207+
1208+
errno = save_errno;
11971209
ereport(ERROR,
11981210
(errcode_for_file_access(),
11991211
errmsg("could not fsync file \"%s\": %m",
12001212
path)));
1213+
}
12011214
else
12021215
ereport(DEBUG1,
12031216
(errcode_for_file_access(),

0 commit comments

Comments
 (0)