Skip site navigation (1) Skip section navigation (2)

Patch to reduce WAL log space usage

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: pgsql-patches(at)postgreSQL(dot)org
Subject: Patch to reduce WAL log space usage
Date: 2001-06-06 17:29:22
Message-ID: 3098.991848562@sss.pgh.pa.us (view raw or flat)
Thread:
Lists: pgsql-patches
Per recent discussions in pghackers, I have tweaked the WAL code so that
each checkpoint truncates the log at the prior checkpoint's redo point,
not its undo point.  (There is no point in keeping the undo information
until we have UNDO support, which doesn't seem to be imminent.)  This
should reduce disk space usage very considerably in the presence of
long-running transactions.

Since I'm not sure if or how soon there will be a 7.1.3 release,
I'm posting the patch here in case people want to apply it locally.

Note: the diff also ensures that out-of-disk-space failures in WAL
logfile creation will be reported correctly.

			regards, tom lane


*** src/backend/access/transam/xlog.c~	Thu Apr  5 12:55:21 2001
--- src/backend/access/transam/xlog.c	Wed Jun  6 13:14:38 2001
***************
*** 1068,1076 ****
--- 1068,1082 ----
  
  		/* 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,1328 ****
--- 1329,1335 ----
  	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,1338 ****
  			 * space
  			 */
  			unlink(tmppath);
! 			errno = save_errno;
  
  			elog(STOP, "ZeroFill(%s) failed: %m", tmppath);
  		}
--- 1339,1346 ----
  			 * space
  			 */
  			unlink(tmppath);
! 			/* 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,1994 ****
--- 1995,2008 ----
  		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,2092 ****
--- 2099,2112 ----
  	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,2231 ****
--- 2244,2257 ----
  	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,2830 ****
  		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.
  	 */
  	if (ControlFile->checkPointCopy.undo.xrecoff != 0 &&
  		XLByteLT(ControlFile->checkPointCopy.undo,
  				 ControlFile->checkPointCopy.redo))
  		XLByteToSeg(ControlFile->checkPointCopy.undo, _logId, _logSeg);
  	else
  		XLByteToSeg(ControlFile->checkPointCopy.redo, _logId, _logSeg);
  
  	/*
--- 2842,2863 ----
  		elog(STOP, "XLog concurrent activity while data base is shutting down");
  
  	/*
! 	 * 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);
  
  	/*

pgsql-patches by date

Next:From: Tom LaneDate: 2001-06-06 17:46:14
Subject: Re: YA readline 4.2 patch
Previous:From: Jason TishlerDate: 2001-06-06 16:02:05
Subject: YA readline 4.2 patch

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group