Retry short writes when flushing WAL.
We don't normally bother retrying when the number of bytes written by write() is short of what was requested. It is generally assumed that a write() to disk doesn't return short, unless you run out of disk space. While writing the WAL, however, it seems prudent to try a bit harder, because a failure leads to PANIC. The write() is also much larger than most write()s in the backend (up to wal_buffers), so there's more room for surprises. Also retry on EINTR. All signals used in the backend are flagged SA_RESTART nowadays, so it shouldn't happen, but better to be defensive.
This commit is contained in:
parent
129759d6a5
commit
79ce29c734
|
@ -1606,6 +1606,8 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible, bool xlog_switch)
|
||||||
{
|
{
|
||||||
char *from;
|
char *from;
|
||||||
Size nbytes;
|
Size nbytes;
|
||||||
|
Size nleft;
|
||||||
|
int written;
|
||||||
|
|
||||||
/* Need to seek in the file? */
|
/* Need to seek in the file? */
|
||||||
if (openLogOff != startoffset)
|
if (openLogOff != startoffset)
|
||||||
|
@ -1622,12 +1624,15 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible, bool xlog_switch)
|
||||||
/* OK to write the page(s) */
|
/* OK to write the page(s) */
|
||||||
from = XLogCtl->pages + startidx * (Size) XLOG_BLCKSZ;
|
from = XLogCtl->pages + startidx * (Size) XLOG_BLCKSZ;
|
||||||
nbytes = npages * (Size) XLOG_BLCKSZ;
|
nbytes = npages * (Size) XLOG_BLCKSZ;
|
||||||
errno = 0;
|
nleft = nbytes;
|
||||||
if (write(openLogFile, from, nbytes) != nbytes)
|
do
|
||||||
{
|
{
|
||||||
/* if write didn't set errno, assume no disk space */
|
errno = 0;
|
||||||
if (errno == 0)
|
written = write(openLogFile, from, nleft);
|
||||||
errno = ENOSPC;
|
if (written <= 0)
|
||||||
|
{
|
||||||
|
if (errno == EINTR)
|
||||||
|
continue;
|
||||||
ereport(PANIC,
|
ereport(PANIC,
|
||||||
(errcode_for_file_access(),
|
(errcode_for_file_access(),
|
||||||
errmsg("could not write to log file %s "
|
errmsg("could not write to log file %s "
|
||||||
|
@ -1635,6 +1640,9 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible, bool xlog_switch)
|
||||||
XLogFileNameP(ThisTimeLineID, openLogSegNo),
|
XLogFileNameP(ThisTimeLineID, openLogSegNo),
|
||||||
openLogOff, (unsigned long) nbytes)));
|
openLogOff, (unsigned long) nbytes)));
|
||||||
}
|
}
|
||||||
|
nleft -= written;
|
||||||
|
from += written;
|
||||||
|
} while (nleft > 0);
|
||||||
|
|
||||||
/* Update state for write */
|
/* Update state for write */
|
||||||
openLogOff += nbytes;
|
openLogOff += nbytes;
|
||||||
|
|
Loading…
Reference in New Issue