Back-patch change to not keep WAL segments just for UNDO information.
authorTom Lane <[email protected]>
Wed, 6 Jun 2001 17:18:56 +0000 (17:18 +0000)
committerTom Lane <[email protected]>
Wed, 6 Jun 2001 17:18:56 +0000 (17:18 +0000)
src/backend/access/transam/xlog.c

index 4ef37f00fa768e49703232f2c0fb10a1fc28c599..9629e7402a315179cdcff29c19e8c3ad613b2e86 100644 (file)
@@ -1068,9 +1068,15 @@ XLogWrite(XLogwrtRqst WriteRqst)
 
                /* OK to write the page */
                from = XLogCtl->pages + Write->curridx * BLCKSZ;
+               errno = 0;
                if (write(openLogFile, from, BLCKSZ) != BLCKSZ)
+               {
+                       /* if write didn't set errno, assume problem is no disk space */
+                       if (errno == 0)
+                               errno = ENOSPC;
                        elog(STOP, "write(logfile %u seg %u off %u) failed: %m",
                                 openLogId, openLogSeg, openLogOff);
+               }
                openLogOff += BLCKSZ;
 
                /*
@@ -1323,6 +1329,7 @@ XLogFileInit(uint32 log, uint32 seg,
        MemSet(zbuffer, 0, sizeof(zbuffer));
        for (nbytes = 0; nbytes < XLogSegSize; nbytes += sizeof(zbuffer))
        {
+               errno = 0;
                if ((int) write(fd, zbuffer, sizeof(zbuffer)) != (int) sizeof(zbuffer))
                {
                        int                     save_errno = errno;
@@ -1332,7 +1339,8 @@ XLogFileInit(uint32 log, uint32 seg,
                         * space
                         */
                        unlink(tmppath);
-                       errno = save_errno;
+                       /* if write didn't set errno, assume problem is no disk space */
+                       errno = save_errno ? save_errno : ENOSPC;
 
                        elog(STOP, "ZeroFill(%s) failed: %m", tmppath);
                }
@@ -1987,8 +1995,14 @@ WriteControlFile(void)
                elog(STOP, "WriteControlFile failed to create control file (%s): %m",
                         ControlFilePath);
 
+       errno = 0;
        if (write(fd, buffer, BLCKSZ) != BLCKSZ)
+       {
+               /* if write didn't set errno, assume problem is no disk space */
+               if (errno == 0)
+                       errno = ENOSPC;
                elog(STOP, "WriteControlFile failed to write control file: %m");
+       }
 
        if (pg_fsync(fd) != 0)
                elog(STOP, "WriteControlFile failed to fsync control file: %m");
@@ -2085,8 +2099,14 @@ UpdateControlFile(void)
        if (fd < 0)
                elog(STOP, "open(\"%s\") failed: %m", ControlFilePath);
 
+       errno = 0;
        if (write(fd, ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData))
+       {
+               /* if write didn't set errno, assume problem is no disk space */
+               if (errno == 0)
+                       errno = ENOSPC;
                elog(STOP, "write(cntlfile) failed: %m");
+       }
 
        if (pg_fsync(fd) != 0)
                elog(STOP, "fsync(cntlfile) failed: %m");
@@ -2224,8 +2244,14 @@ BootStrapXLOG(void)
        use_existent = false;
        openLogFile = XLogFileInit(0, 0, &use_existent, false);
 
+       errno = 0;
        if (write(openLogFile, buffer, BLCKSZ) != BLCKSZ)
+       {
+               /* if write didn't set errno, assume problem is no disk space */
+               if (errno == 0)
+                       errno = ENOSPC;
                elog(STOP, "BootStrapXLOG failed to write logfile: %m");
+       }
 
        if (pg_fsync(openLogFile) != 0)
                elog(STOP, "BootStrapXLOG failed to fsync logfile: %m");
@@ -2816,15 +2842,22 @@ CreateCheckPoint(bool shutdown)
                elog(STOP, "XLog concurrent activity while data base is shutting down");
 
        /*
-        * Remember location of prior checkpoint's earliest info. Oldest item
-        * is redo or undo, whichever is older; but watch out for case that
-        * undo = 0.
+        * Select point at which we can truncate the log, which we base on the
+        * prior checkpoint's earliest info.
+        *
+        * With UNDO support: oldest item is redo or undo, whichever is older;
+        * but watch out for case that undo = 0.
+        *
+        * Without UNDO support: just use the redo pointer.  This allows xlog
+        * space to be freed much faster when there are long-running transactions.
         */
+#ifdef NOT_USED
        if (ControlFile->checkPointCopy.undo.xrecoff != 0 &&
                XLByteLT(ControlFile->checkPointCopy.undo,
                                 ControlFile->checkPointCopy.redo))
                XLByteToSeg(ControlFile->checkPointCopy.undo, _logId, _logSeg);
        else
+#endif
                XLByteToSeg(ControlFile->checkPointCopy.redo, _logId, _logSeg);
 
        /*