Skip to content

Commit 2811776

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 5b16a35 commit 2811776

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

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

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

0 commit comments

Comments
 (0)