Skip to content

Commit 542e6f3

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 b81ef63 commit 542e6f3

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
@@ -1150,10 +1150,8 @@ mdsync(void)
11501150
* The bitmap manipulations are slightly tricky, because we can call
11511151
* AbsorbFsyncRequests() inside the loop and that could result in
11521152
* bms_add_member() modifying and even re-palloc'ing the bitmapsets.
1153-
* This is okay because we unlink each bitmapset from the hashtable
1154-
* entry before scanning it. That means that any incoming fsync
1155-
* requests will be processed now if they reach the table before we
1156-
* begin to scan their fork.
1153+
* So we detach it, but if we fail we'll merge it with any new
1154+
* requests that have arrived in the meantime.
11571155
*/
11581156
for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
11591157
{
@@ -1163,7 +1161,8 @@ mdsync(void)
11631161
entry->requests[forknum] = NULL;
11641162
entry->canceled[forknum] = false;
11651163

1166-
while ((segno = bms_first_member(requests)) >= 0)
1164+
segno = -1;
1165+
while ((segno = bms_next_member(requests, segno)) >= 0)
11671166
{
11681167
int failures;
11691168

@@ -1244,6 +1243,7 @@ mdsync(void)
12441243
longest = elapsed;
12451244
total_elapsed += elapsed;
12461245
processed++;
1246+
requests = bms_del_member(requests, segno);
12471247
if (log_checkpoints)
12481248
elog(DEBUG1, "checkpoint sync: number=%d file=%s time=%.3f msec",
12491249
processed,
@@ -1272,10 +1272,23 @@ mdsync(void)
12721272
*/
12731273
if (!FILE_POSSIBLY_DELETED(errno) ||
12741274
failures > 0)
1275+
{
1276+
Bitmapset *new_requests;
1277+
1278+
/*
1279+
* We need to merge these unsatisfied requests with
1280+
* any others that have arrived since we started.
1281+
*/
1282+
new_requests = entry->requests[forknum];
1283+
entry->requests[forknum] =
1284+
bms_join(new_requests, requests);
1285+
1286+
errno = save_errno;
12751287
ereport(ERROR,
12761288
(errcode_for_file_access(),
12771289
errmsg("could not fsync file \"%s\": %m",
12781290
path)));
1291+
}
12791292
else
12801293
ereport(DEBUG1,
12811294
(errcode_for_file_access(),

0 commit comments

Comments
 (0)