In a case of a corrupted database, I saw an error message like
Could not read from file ...: Success.
from the SLRU module. This is because it checks that it reads or writes
exactly BLCKSZ, and else goes to the error path. The attached patch
gives a different error message in this case.
Because of the structure of this code, we don't have the information to
do the usual "read %d of %zu", but at least this is better than
reporting a "success" error.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
From 680651938e30b5208a73b9d76813a5880af4ab54 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Tue, 18 Jun 2019 14:27:53 +0200
Subject: [PATCH 1/2] Better error messages for short reads/writes in SLRU
This avoids getting a
Could not read from file ...: Success.
for a short read or write (since errno is not set in that case).
Instead, report a more specific error messages.
---
src/backend/access/transam/slru.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/backend/access/transam/slru.c
b/src/backend/access/transam/slru.c
index 2dbc65b125..315c0612e6 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -923,15 +923,19 @@ SlruReportIOError(SlruCtl ctl, int pageno, TransactionId
xid)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not access status of
transaction %u", xid),
- errdetail("Could not read from file
\"%s\" at offset %u: %m.",
- path, offset)));
+ errno == 0
+ ? errdetail("Short read from file
\"%s\" at offset %u.", path, offset)
+ : errdetail("Could not read from file
\"%s\" at offset %u: %m.",
+ path,
offset)));
break;
case SLRU_WRITE_FAILED:
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not access status of
transaction %u", xid),
- errdetail("Could not write to file
\"%s\" at offset %u: %m.",
- path, offset)));
+ errno == 0
+ ? errdetail("Short write to file
\"%s\" at offset %u.", path, offset)
+ : errdetail("Could not write to file
\"%s\" at offset %u: %m.",
+ path,
offset)));
break;
case SLRU_FSYNC_FAILED:
ereport(data_sync_elevel(ERROR),
--
2.22.0
From 9d6d381993701fc696466e822d58289c480c358f Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Tue, 18 Jun 2019 14:29:31 +0200
Subject: [PATCH 2/2] Use consistent style for checking return from system
calls
Use
if (something() < 0)
error ...
instead of just
if (something)
error ...
The latter is not incorrect, but it's a bit confusing and not the
common style.
---
src/backend/access/transam/slru.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/backend/access/transam/slru.c
b/src/backend/access/transam/slru.c
index 315c0612e6..dab5b6ffa0 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -697,7 +697,7 @@ SlruPhysicalReadPage(SlruCtl ctl, int pageno, int slotno)
}
pgstat_report_wait_end();
- if (CloseTransientFile(fd))
+ if (CloseTransientFile(fd) < 0)
{
slru_errcause = SLRU_CLOSE_FAILED;
slru_errno = errno;
@@ -869,7 +869,7 @@ SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno,
SlruFlush fdata)
if (!fdata)
{
pgstat_report_wait_start(WAIT_EVENT_SLRU_SYNC);
- if (ctl->do_fsync && pg_fsync(fd))
+ if (ctl->do_fsync && pg_fsync(fd) < 0)
{
pgstat_report_wait_end();
slru_errcause = SLRU_FSYNC_FAILED;
@@ -879,7 +879,7 @@ SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno,
SlruFlush fdata)
}
pgstat_report_wait_end();
- if (CloseTransientFile(fd))
+ if (CloseTransientFile(fd) < 0)
{
slru_errcause = SLRU_CLOSE_FAILED;
slru_errno = errno;
@@ -1150,7 +1150,7 @@ SimpleLruFlush(SlruCtl ctl, bool allow_redirtied)
for (i = 0; i < fdata.num_files; i++)
{
pgstat_report_wait_start(WAIT_EVENT_SLRU_FLUSH_SYNC);
- if (ctl->do_fsync && pg_fsync(fdata.fd[i]))
+ if (ctl->do_fsync && pg_fsync(fdata.fd[i]) < 0)
{
slru_errcause = SLRU_FSYNC_FAILED;
slru_errno = errno;
@@ -1159,7 +1159,7 @@ SimpleLruFlush(SlruCtl ctl, bool allow_redirtied)
}
pgstat_report_wait_end();
- if (CloseTransientFile(fdata.fd[i]))
+ if (CloseTransientFile(fdata.fd[i]) < 0)
{
slru_errcause = SLRU_CLOSE_FAILED;
slru_errno = errno;
--
2.22.0