Skip to content

Commit 1556cb2

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 74171f8 commit 1556cb2

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
@@ -1123,10 +1123,8 @@ mdsync(void)
11231123
* The bitmap manipulations are slightly tricky, because we can call
11241124
* AbsorbFsyncRequests() inside the loop and that could result in
11251125
* bms_add_member() modifying and even re-palloc'ing the bitmapsets.
1126-
* This is okay because we unlink each bitmapset from the hashtable
1127-
* entry before scanning it. That means that any incoming fsync
1128-
* requests will be processed now if they reach the table before we
1129-
* begin to scan their fork.
1126+
* So we detach it, but if we fail we'll merge it with any new
1127+
* requests that have arrived in the meantime.
11301128
*/
11311129
for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
11321130
{
@@ -1136,7 +1134,8 @@ mdsync(void)
11361134
entry->requests[forknum] = NULL;
11371135
entry->canceled[forknum] = false;
11381136

1139-
while ((segno = bms_first_member(requests)) >= 0)
1137+
segno = -1;
1138+
while ((segno = bms_next_member(requests, segno)) >= 0)
11401139
{
11411140
int failures;
11421141

@@ -1217,6 +1216,7 @@ mdsync(void)
12171216
longest = elapsed;
12181217
total_elapsed += elapsed;
12191218
processed++;
1219+
requests = bms_del_member(requests, segno);
12201220
if (log_checkpoints)
12211221
elog(DEBUG1, "checkpoint sync: number=%d file=%s time=%.3f msec",
12221222
processed,
@@ -1245,10 +1245,23 @@ mdsync(void)
12451245
*/
12461246
if (!FILE_POSSIBLY_DELETED(errno) ||
12471247
failures > 0)
1248+
{
1249+
Bitmapset *new_requests;
1250+
1251+
/*
1252+
* We need to merge these unsatisfied requests with
1253+
* any others that have arrived since we started.
1254+
*/
1255+
new_requests = entry->requests[forknum];
1256+
entry->requests[forknum] =
1257+
bms_join(new_requests, requests);
1258+
1259+
errno = save_errno;
12481260
ereport(ERROR,
12491261
(errcode_for_file_access(),
12501262
errmsg("could not fsync file \"%s\": %m",
12511263
path)));
1264+
}
12521265
else
12531266
ereport(DEBUG1,
12541267
(errcode_for_file_access(),

0 commit comments

Comments
 (0)