77 * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
88 * Portions Copyright (c) 1994, Regents of the University of California
99 *
10- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.184 2005/04/13 18:54:56 tgl Exp $
10+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.185 2005/04/15 18:48:10 tgl Exp $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
@@ -444,8 +444,8 @@ static bool AdvanceXLInsertBuffer(void);
444444static void XLogWrite (XLogwrtRqst WriteRqst );
445445static int XLogFileInit (uint32 log , uint32 seg ,
446446 bool * use_existent , bool use_lock );
447- static bool InstallXLogFileSegment (uint32 log , uint32 seg , char * tmppath ,
448- bool find_free , int max_advance ,
447+ static bool InstallXLogFileSegment (uint32 * log , uint32 * seg , char * tmppath ,
448+ bool find_free , int * max_advance ,
449449 bool use_lock );
450450static int XLogFileOpen (uint32 log , uint32 seg );
451451static int XLogFileRead (uint32 log , uint32 seg , int emode );
@@ -1509,6 +1509,9 @@ XLogFileInit(uint32 log, uint32 seg,
15091509 char path [MAXPGPATH ];
15101510 char tmppath [MAXPGPATH ];
15111511 char zbuffer [BLCKSZ ];
1512+ uint32 installed_log ;
1513+ uint32 installed_seg ;
1514+ int max_advance ;
15121515 int fd ;
15131516 int nbytes ;
15141517
@@ -1601,8 +1604,11 @@ XLogFileInit(uint32 log, uint32 seg,
16011604 * else has created the file while we were filling ours: if so, use
16021605 * ours to pre-create a future log segment.
16031606 */
1604- if (!InstallXLogFileSegment (log , seg , tmppath ,
1605- * use_existent , XLOGfileslop ,
1607+ installed_log = log ;
1608+ installed_seg = seg ;
1609+ max_advance = XLOGfileslop ;
1610+ if (!InstallXLogFileSegment (& installed_log , & installed_seg , tmppath ,
1611+ * use_existent , & max_advance ,
16061612 use_lock ))
16071613 {
16081614 /* No need for any more future segments... */
@@ -1722,7 +1728,7 @@ XLogFileCopy(uint32 log, uint32 seg,
17221728 /*
17231729 * Now move the segment into place with its final name.
17241730 */
1725- if (!InstallXLogFileSegment (log , seg , tmppath , false, 0 , false))
1731+ if (!InstallXLogFileSegment (& log , & seg , tmppath , false, NULL , false))
17261732 elog (PANIC , "InstallXLogFileSegment should not have failed" );
17271733}
17281734
@@ -1732,17 +1738,20 @@ XLogFileCopy(uint32 log, uint32 seg,
17321738 * This is used both to install a newly-created segment (which has a temp
17331739 * filename while it's being created) and to recycle an old segment.
17341740 *
1735- * log, seg: identify segment to install as (or first possible target).
1741+ * *log, *seg: identify segment to install as (or first possible target).
1742+ * When find_free is TRUE, these are modified on return to indicate the
1743+ * actual installation location or last segment searched.
17361744 *
17371745 * tmppath: initial name of file to install. It will be renamed into place.
17381746 *
17391747 * find_free: if TRUE, install the new segment at the first empty log/seg
17401748 * number at or after the passed numbers. If FALSE, install the new segment
17411749 * exactly where specified, deleting any existing segment file there.
17421750 *
1743- * max_advance: maximum number of log/seg slots to advance past the starting
1744- * point. Fail if no free slot is found in this range. (Irrelevant if
1745- * find_free is FALSE.)
1751+ * *max_advance: maximum number of log/seg slots to advance past the starting
1752+ * point. Fail if no free slot is found in this range. On return, reduced
1753+ * by the number of slots skipped over. (Irrelevant, and may be NULL,
1754+ * when find_free is FALSE.)
17461755 *
17471756 * use_lock: if TRUE, acquire ControlFileLock while moving file into
17481757 * place. This should be TRUE except during bootstrap log creation. The
@@ -1752,14 +1761,14 @@ XLogFileCopy(uint32 log, uint32 seg,
17521761 * exceeding max_advance limit. (Any other kind of failure causes ereport().)
17531762 */
17541763static bool
1755- InstallXLogFileSegment (uint32 log , uint32 seg , char * tmppath ,
1756- bool find_free , int max_advance ,
1764+ InstallXLogFileSegment (uint32 * log , uint32 * seg , char * tmppath ,
1765+ bool find_free , int * max_advance ,
17571766 bool use_lock )
17581767{
17591768 char path [MAXPGPATH ];
17601769 struct stat stat_buf ;
17611770
1762- XLogFilePath (path , ThisTimeLineID , log , seg );
1771+ XLogFilePath (path , ThisTimeLineID , * log , * seg );
17631772
17641773 /*
17651774 * We want to be sure that only one process does this at a time.
@@ -1777,15 +1786,16 @@ InstallXLogFileSegment(uint32 log, uint32 seg, char *tmppath,
17771786 /* Find a free slot to put it in */
17781787 while (stat (path , & stat_buf ) == 0 )
17791788 {
1780- if (-- max_advance < 0 )
1789+ if (* max_advance <= 0 )
17811790 {
17821791 /* Failed to find a free slot within specified range */
17831792 if (use_lock )
17841793 LWLockRelease (ControlFileLock );
17851794 return false;
17861795 }
1787- NextLogSeg (log , seg );
1788- XLogFilePath (path , ThisTimeLineID , log , seg );
1796+ NextLogSeg (* log , * seg );
1797+ (* max_advance )-- ;
1798+ XLogFilePath (path , ThisTimeLineID , * log , * seg );
17891799 }
17901800 }
17911801
@@ -1799,14 +1809,14 @@ InstallXLogFileSegment(uint32 log, uint32 seg, char *tmppath,
17991809 ereport (PANIC ,
18001810 (errcode_for_file_access (),
18011811 errmsg ("could not link file \"%s\" to \"%s\" (initialization of log file %u, segment %u): %m" ,
1802- tmppath , path , log , seg )));
1812+ tmppath , path , * log , * seg )));
18031813 unlink (tmppath );
18041814#else
18051815 if (rename (tmppath , path ) < 0 )
18061816 ereport (PANIC ,
18071817 (errcode_for_file_access (),
18081818 errmsg ("could not rename file \"%s\" to \"%s\" (initialization of log file %u, segment %u): %m" ,
1809- tmppath , path , log , seg )));
1819+ tmppath , path , * log , * seg )));
18101820#endif
18111821
18121822 if (use_lock )
@@ -2129,6 +2139,7 @@ MoveOfflineLogs(uint32 log, uint32 seg, XLogRecPtr endptr,
21292139{
21302140 uint32 endlogId ;
21312141 uint32 endlogSeg ;
2142+ int max_advance ;
21322143 DIR * xldir ;
21332144 struct dirent * xlde ;
21342145 char lastoff [MAXFNAMELEN ];
@@ -2137,7 +2148,12 @@ MoveOfflineLogs(uint32 log, uint32 seg, XLogRecPtr endptr,
21372148 * nsegsremoved = 0 ;
21382149 * nsegsrecycled = 0 ;
21392150
2151+ /*
2152+ * Initialize info about where to try to recycle to. We allow recycling
2153+ * segments up to XLOGfileslop segments beyond the current XLOG location.
2154+ */
21402155 XLByteToPrevSeg (endptr , endlogId , endlogSeg );
2156+ max_advance = XLOGfileslop ;
21412157
21422158 xldir = AllocateDir (XLogDir );
21432159 if (xldir == NULL )
@@ -2179,12 +2195,10 @@ MoveOfflineLogs(uint32 log, uint32 seg, XLogRecPtr endptr,
21792195
21802196 /*
21812197 * Before deleting the file, see if it can be recycled as
2182- * a future log segment. We allow recycling segments up
2183- * to XLOGfileslop segments beyond the current XLOG
2184- * location.
2198+ * a future log segment.
21852199 */
2186- if (InstallXLogFileSegment (endlogId , endlogSeg , path ,
2187- true, XLOGfileslop ,
2200+ if (InstallXLogFileSegment (& endlogId , & endlogSeg , path ,
2201+ true, & max_advance ,
21882202 true))
21892203 {
21902204 ereport (DEBUG2 ,
0 commit comments