]> granicus.if.org Git - postgresql/commitdiff
Improve tuplestore's error messages for I/O failures.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 12 Jun 2014 22:59:06 +0000 (18:59 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 12 Jun 2014 22:59:14 +0000 (18:59 -0400)
We should report the errno when we get a failure from functions like
BufFileWrite.  "ERROR: write failed" is unreasonably taciturn for a
case that's well within the realm of possibility; I've seen it a
couple times in the buildfarm recently, in situations that were
probably out-of-disk-space, but it'd be good to see the errno
to confirm it.

I think this code was originally written without assuming that
the buffile.c functions would return useful errno; but most other
callers *are* assuming that, and a quick look at the buffile code
gives no reason to suppose otherwise.

Also, a couple of the old messages were phrased on the assumption
that a short read might indicate a logic bug in tuplestore itself;
but that code's pretty well tested by now, so a filesystem-level
problem seems much more likely.

src/backend/utils/sort/logtape.c
src/backend/utils/sort/tuplestore.c

index 106b917f72fc367c5377ec6d8b7555c4cf7e8227..62726c7a63ace1c0b3c420025c33c9849fca43ca 100644 (file)
@@ -208,11 +208,9 @@ ltsWriteBlock(LogicalTapeSet *lts, long blocknum, void *buffer)
        if (BufFileSeekBlock(lts->pfile, blocknum) != 0 ||
                BufFileWrite(lts->pfile, buffer, BLCKSZ) != BLCKSZ)
                ereport(ERROR,
-               /* XXX is it okay to assume errno is correct? */
                                (errcode_for_file_access(),
                                 errmsg("could not write block %ld of temporary file: %m",
-                                               blocknum),
-                                errhint("Perhaps out of disk space?")));
+                                               blocknum)));
 }
 
 /*
@@ -227,7 +225,6 @@ ltsReadBlock(LogicalTapeSet *lts, long blocknum, void *buffer)
        if (BufFileSeekBlock(lts->pfile, blocknum) != 0 ||
                BufFileRead(lts->pfile, buffer, BLCKSZ) != BLCKSZ)
                ereport(ERROR,
-               /* XXX is it okay to assume errno is correct? */
                                (errcode_for_file_access(),
                                 errmsg("could not read block %ld of temporary file: %m",
                                                blocknum)));
index 8b968a8b62f9eda3c7ca690a5efe8ac1aedcbb84..1d6fe869944d90bbca7db424bc788377b355bd41 100644 (file)
@@ -501,7 +501,9 @@ tuplestore_select_read_pointer(Tuplestorestate *state, int ptr)
                                                                state->writepos_file,
                                                                state->writepos_offset,
                                                                SEEK_SET) != 0)
-                                       elog(ERROR, "tuplestore seek failed");
+                                       ereport(ERROR,
+                                                       (errcode_for_file_access(),
+                                                        errmsg("could not seek in tuplestore temporary file: %m")));
                        }
                        else
                        {
@@ -509,7 +511,9 @@ tuplestore_select_read_pointer(Tuplestorestate *state, int ptr)
                                                                readptr->file,
                                                                readptr->offset,
                                                                SEEK_SET) != 0)
-                                       elog(ERROR, "tuplestore seek failed");
+                                       ereport(ERROR,
+                                                       (errcode_for_file_access(),
+                                                        errmsg("could not seek in tuplestore temporary file: %m")));
                        }
                        break;
                default:
@@ -834,7 +838,9 @@ tuplestore_puttuple_common(Tuplestorestate *state, void *tuple)
                        if (BufFileSeek(state->myfile,
                                                        state->writepos_file, state->writepos_offset,
                                                        SEEK_SET) != 0)
-                               elog(ERROR, "tuplestore seek to EOF failed");
+                               ereport(ERROR,
+                                               (errcode_for_file_access(),
+                                errmsg("could not seek in tuplestore temporary file: %m")));
                        state->status = TSS_WRITEFILE;
 
                        /*
@@ -936,7 +942,9 @@ tuplestore_gettuple(Tuplestorestate *state, bool forward,
                                if (BufFileSeek(state->myfile,
                                                                readptr->file, readptr->offset,
                                                                SEEK_SET) != 0)
-                                       elog(ERROR, "tuplestore seek failed");
+                                       ereport(ERROR,
+                                                       (errcode_for_file_access(),
+                                                        errmsg("could not seek in tuplestore temporary file: %m")));
                        state->status = TSS_READFILE;
                        /* FALL THRU into READFILE case */
 
@@ -998,7 +1006,9 @@ tuplestore_gettuple(Tuplestorestate *state, bool forward,
                                        if (BufFileSeek(state->myfile, 0,
                                                                        -(long) (tuplen + sizeof(unsigned int)),
                                                                        SEEK_CUR) != 0)
-                                               elog(ERROR, "bogus tuple length in backward scan");
+                                               ereport(ERROR,
+                                                               (errcode_for_file_access(),
+                                                                errmsg("could not seek in tuplestore temporary file: %m")));
                                        Assert(!state->truncated);
                                        return NULL;
                                }
@@ -1013,7 +1023,9 @@ tuplestore_gettuple(Tuplestorestate *state, bool forward,
                        if (BufFileSeek(state->myfile, 0,
                                                        -(long) tuplen,
                                                        SEEK_CUR) != 0)
-                               elog(ERROR, "bogus tuple length in backward scan");
+                               ereport(ERROR,
+                                               (errcode_for_file_access(),
+                                errmsg("could not seek in tuplestore temporary file: %m")));
                        tup = READTUP(state, tuplen);
                        return tup;
 
@@ -1213,7 +1225,9 @@ tuplestore_rescan(Tuplestorestate *state)
                case TSS_READFILE:
                        readptr->eof_reached = false;
                        if (BufFileSeek(state->myfile, 0, 0L, SEEK_SET) != 0)
-                               elog(ERROR, "tuplestore seek to start failed");
+                               ereport(ERROR,
+                                               (errcode_for_file_access(),
+                                errmsg("could not seek in tuplestore temporary file: %m")));
                        break;
                default:
                        elog(ERROR, "invalid tuplestore state");
@@ -1276,14 +1290,18 @@ tuplestore_copy_read_pointer(Tuplestorestate *state,
                                                                        state->writepos_file,
                                                                        state->writepos_offset,
                                                                        SEEK_SET) != 0)
-                                               elog(ERROR, "tuplestore seek failed");
+                                               ereport(ERROR,
+                                                               (errcode_for_file_access(),
+                                                                errmsg("could not seek in tuplestore temporary file: %m")));
                                }
                                else
                                {
                                        if (BufFileSeek(state->myfile,
                                                                        dptr->file, dptr->offset,
                                                                        SEEK_SET) != 0)
-                                               elog(ERROR, "tuplestore seek failed");
+                                               ereport(ERROR,
+                                                               (errcode_for_file_access(),
+                                                                errmsg("could not seek in tuplestore temporary file: %m")));
                                }
                        }
                        else if (srcptr == state->activeptr)
@@ -1427,10 +1445,10 @@ getlen(Tuplestorestate *state, bool eofOK)
        nbytes = BufFileRead(state->myfile, (void *) &len, sizeof(len));
        if (nbytes == sizeof(len))
                return len;
-       if (nbytes != 0)
-               elog(ERROR, "unexpected end of tape");
-       if (!eofOK)
-               elog(ERROR, "unexpected end of data");
+       if (nbytes != 0 || !eofOK)
+               ereport(ERROR,
+                               (errcode_for_file_access(),
+                          errmsg("could not read from tuplestore temporary file: %m")));
        return 0;
 }
 
@@ -1469,14 +1487,20 @@ writetup_heap(Tuplestorestate *state, void *tup)
 
        if (BufFileWrite(state->myfile, (void *) &tuplen,
                                         sizeof(tuplen)) != sizeof(tuplen))
-               elog(ERROR, "write failed");
+               ereport(ERROR,
+                               (errcode_for_file_access(),
+                                errmsg("could not write to tuplestore temporary file: %m")));
        if (BufFileWrite(state->myfile, (void *) tupbody,
                                         tupbodylen) != (size_t) tupbodylen)
-               elog(ERROR, "write failed");
+               ereport(ERROR,
+                               (errcode_for_file_access(),
+                                errmsg("could not write to tuplestore temporary file: %m")));
        if (state->backward)            /* need trailing length word? */
                if (BufFileWrite(state->myfile, (void *) &tuplen,
                                                 sizeof(tuplen)) != sizeof(tuplen))
-                       elog(ERROR, "write failed");
+                       ereport(ERROR,
+                                       (errcode_for_file_access(),
+                               errmsg("could not write to tuplestore temporary file: %m")));
 
        FREEMEM(state, GetMemoryChunkSpace(tuple));
        heap_free_minimal_tuple(tuple);
@@ -1495,10 +1519,14 @@ readtup_heap(Tuplestorestate *state, unsigned int len)
        tuple->t_len = tuplen;
        if (BufFileRead(state->myfile, (void *) tupbody,
                                        tupbodylen) != (size_t) tupbodylen)
-               elog(ERROR, "unexpected end of data");
+               ereport(ERROR,
+                               (errcode_for_file_access(),
+                          errmsg("could not read from tuplestore temporary file: %m")));
        if (state->backward)            /* need trailing length word? */
                if (BufFileRead(state->myfile, (void *) &tuplen,
                                                sizeof(tuplen)) != sizeof(tuplen))
-                       elog(ERROR, "unexpected end of data");
+                       ereport(ERROR,
+                                       (errcode_for_file_access(),
+                          errmsg("could not read from tuplestore temporary file: %m")));
        return (void *) tuple;
 }