Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1173344

Browse files
committed
Adjust WAL code so that checkpoints truncate the xlog at the previous
checkpoint's redo pointer, not its undo pointer, per discussion in pghackers a few days ago. No point in hanging onto undo information until we have the ability to do something with it --- and this solves a rather large problem with log space for long-running transactions. Also, change all calls of write() to detect the case where write returned a count less than requested, but failed to set errno. Presume that this situation indicates ENOSPC, and give the appropriate error message, rather than a random message associated with the previous value of errno.
1 parent ce370ee commit 1173344

File tree

6 files changed

+76
-20
lines changed

6 files changed

+76
-20
lines changed

contrib/dbase/dbf.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,8 @@ int dbf_write_head(dbhead *dbh) {
155155
put_short(head.dbh_hlen, dbh->db_hlen);
156156
put_short(head.dbh_rlen, dbh->db_rlen);
157157

158-
if (write(dbh->db_fd, &head, sizeof(dbf_header)) == -1 ) {
158+
if (write(dbh->db_fd, &head, sizeof(dbf_header)) != sizeof(dbf_header))
159159
return DBF_ERROR;
160-
}
161160

162161
return 0;
163162
}
@@ -180,14 +179,12 @@ int dbf_put_fields(dbhead *dbh) {
180179
field.dbf_flen = dbh->db_fields[t].db_flen;
181180
field.dbf_dec = dbh->db_fields[t].db_dec;
182181

183-
if (write(dbh->db_fd, &field, sizeof(dbf_field)) == -1) {
182+
if (write(dbh->db_fd, &field, sizeof(dbf_field)) != sizeof(dbf_field))
184183
return DBF_ERROR;
185-
}
186184
}
187185

188-
if (write(dbh->db_fd, &end, 1) == -1) {
186+
if (write(dbh->db_fd, &end, 1) != 1)
189187
return DBF_ERROR;
190-
}
191188

192189
return 0;
193190
}
@@ -457,15 +454,13 @@ int dbf_put_record(dbhead *dbh, field *rec, u_long where) {
457454
idx += rec[t].db_flen;
458455
}
459456

460-
if (write(dbh->db_fd, data, dbh->db_rlen) == -1) {
457+
if (write(dbh->db_fd, data, dbh->db_rlen) != dbh->db_rlen)
461458
return DBF_ERROR;
462-
}
463459

464460
/* There's a 0x1A at the end of a dbf-file */
465461
if (where == dbh->db_records) {
466-
if (write(dbh->db_fd, &end, 1) == -1) {
462+
if (write(dbh->db_fd, &end, 1) != 1)
467463
return DBF_ERROR;
468-
}
469464
}
470465

471466
dbh->db_offset += dbh->db_rlen;

contrib/pg_resetxlog/pg_resetxlog.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
2424
* Portions Copyright (c) 1994, Regents of the University of California
2525
*
26-
* $Header: /cvsroot/pgsql/contrib/pg_resetxlog/Attic/pg_resetxlog.c,v 1.4 2001/05/30 14:18:18 momjian Exp $
26+
* $Header: /cvsroot/pgsql/contrib/pg_resetxlog/Attic/pg_resetxlog.c,v 1.5 2001/06/06 17:07:38 tgl Exp $
2727
*
2828
*-------------------------------------------------------------------------
2929
*/
@@ -772,8 +772,12 @@ RewriteControlFile(void)
772772
exit(1);
773773
}
774774

775+
errno = 0;
775776
if (write(fd, buffer, BLCKSZ) != BLCKSZ)
776777
{
778+
/* if write didn't set errno, assume problem is no disk space */
779+
if (errno == 0)
780+
errno = ENOSPC;
777781
perror("RewriteControlFile failed to write pg_control file");
778782
exit(1);
779783
}
@@ -884,8 +888,12 @@ WriteEmptyXLOG(void)
884888
exit(1);
885889
}
886890

891+
errno = 0;
887892
if (write(fd, buffer, BLCKSZ) != BLCKSZ)
888893
{
894+
/* if write didn't set errno, assume problem is no disk space */
895+
if (errno == 0)
896+
errno = ENOSPC;
889897
perror("WriteEmptyXLOG: failed to write xlog file");
890898
exit(1);
891899
}
@@ -894,8 +902,11 @@ WriteEmptyXLOG(void)
894902
memset(buffer, 0, BLCKSZ);
895903
for (nbytes = BLCKSZ; nbytes < XLogSegSize; nbytes += BLCKSZ)
896904
{
905+
errno = 0;
897906
if (write(fd, buffer, BLCKSZ) != BLCKSZ)
898907
{
908+
if (errno == 0)
909+
errno = ENOSPC;
899910
perror("WriteEmptyXLOG: failed to write xlog file");
900911
exit(1);
901912
}

src/backend/access/transam/xlog.c

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.68 2001/06/03 14:53:56 petere Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.69 2001/06/06 17:07:38 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -1068,9 +1068,15 @@ XLogWrite(XLogwrtRqst WriteRqst)
10681068

10691069
/* OK to write the page */
10701070
from = XLogCtl->pages + Write->curridx * BLCKSZ;
1071+
errno = 0;
10711072
if (write(openLogFile, from, BLCKSZ) != BLCKSZ)
1073+
{
1074+
/* if write didn't set errno, assume problem is no disk space */
1075+
if (errno == 0)
1076+
errno = ENOSPC;
10721077
elog(STOP, "write of log file %u, segment %u, offset %u failed: %m",
10731078
openLogId, openLogSeg, openLogOff);
1079+
}
10741080
openLogOff += BLCKSZ;
10751081

10761082
/*
@@ -1323,6 +1329,7 @@ XLogFileInit(uint32 log, uint32 seg,
13231329
MemSet(zbuffer, 0, sizeof(zbuffer));
13241330
for (nbytes = 0; nbytes < XLogSegSize; nbytes += sizeof(zbuffer))
13251331
{
1332+
errno = 0;
13261333
if ((int) write(fd, zbuffer, sizeof(zbuffer)) != (int) sizeof(zbuffer))
13271334
{
13281335
int save_errno = errno;
@@ -1332,7 +1339,8 @@ XLogFileInit(uint32 log, uint32 seg,
13321339
* space
13331340
*/
13341341
unlink(tmppath);
1335-
errno = save_errno;
1342+
/* if write didn't set errno, assume problem is no disk space */
1343+
errno = save_errno ? save_errno : ENOSPC;
13361344

13371345
elog(STOP, "ZeroFill failed to create or write %s: %m", tmppath);
13381346
}
@@ -1990,8 +1998,14 @@ WriteControlFile(void)
19901998
elog(STOP, "WriteControlFile: could not create control file (%s): %m",
19911999
ControlFilePath);
19922000

2001+
errno = 0;
19932002
if (write(fd, buffer, BLCKSZ) != BLCKSZ)
2003+
{
2004+
/* if write didn't set errno, assume problem is no disk space */
2005+
if (errno == 0)
2006+
errno = ENOSPC;
19942007
elog(STOP, "WriteControlFile: write to control file failed: %m");
2008+
}
19952009

19962010
if (pg_fsync(fd) != 0)
19972011
elog(STOP, "WriteControlFile: fsync of control file failed: %m");
@@ -2109,8 +2123,14 @@ UpdateControlFile(void)
21092123
if (fd < 0)
21102124
elog(STOP, "could not open control file (%s): %m", ControlFilePath);
21112125

2126+
errno = 0;
21122127
if (write(fd, ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData))
2128+
{
2129+
/* if write didn't set errno, assume problem is no disk space */
2130+
if (errno == 0)
2131+
errno = ENOSPC;
21132132
elog(STOP, "write to control file failed: %m");
2133+
}
21142134

21152135
if (pg_fsync(fd) != 0)
21162136
elog(STOP, "fsync of control file failed: %m");
@@ -2248,8 +2268,14 @@ BootStrapXLOG(void)
22482268
use_existent = false;
22492269
openLogFile = XLogFileInit(0, 0, &use_existent, false);
22502270

2271+
errno = 0;
22512272
if (write(openLogFile, buffer, BLCKSZ) != BLCKSZ)
2273+
{
2274+
/* if write didn't set errno, assume problem is no disk space */
2275+
if (errno == 0)
2276+
errno = ENOSPC;
22522277
elog(STOP, "BootStrapXLOG failed to write log file: %m");
2278+
}
22532279

22542280
if (pg_fsync(openLogFile) != 0)
22552281
elog(STOP, "BootStrapXLOG failed to fsync log file: %m");
@@ -2852,15 +2878,22 @@ CreateCheckPoint(bool shutdown)
28522878
elog(STOP, "concurrent transaction log activity while database system is shutting down");
28532879

28542880
/*
2855-
* Remember location of prior checkpoint's earliest info. Oldest item
2856-
* is redo or undo, whichever is older; but watch out for case that
2857-
* undo = 0.
2881+
* Select point at which we can truncate the log, which we base on the
2882+
* prior checkpoint's earliest info.
2883+
*
2884+
* With UNDO support: oldest item is redo or undo, whichever is older;
2885+
* but watch out for case that undo = 0.
2886+
*
2887+
* Without UNDO support: just use the redo pointer. This allows xlog
2888+
* space to be freed much faster when there are long-running transactions.
28582889
*/
2890+
#ifdef NOT_USED
28592891
if (ControlFile->checkPointCopy.undo.xrecoff != 0 &&
28602892
XLByteLT(ControlFile->checkPointCopy.undo,
28612893
ControlFile->checkPointCopy.redo))
28622894
XLByteToSeg(ControlFile->checkPointCopy.undo, _logId, _logSeg);
28632895
else
2896+
#endif
28642897
XLByteToSeg(ControlFile->checkPointCopy.redo, _logId, _logSeg);
28652898

28662899
/*

src/backend/storage/file/fd.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.79 2001/05/30 14:15:26 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.80 2001/06/06 17:07:46 tgl Exp $
1111
*
1212
* NOTES:
1313
*
@@ -865,7 +865,14 @@ FileWrite(File file, char *buffer, int amount)
865865
VfdCache[file].seekPos, amount, buffer));
866866

867867
FileAccess(file);
868+
869+
errno = 0;
868870
returnCode = write(VfdCache[file].fd, buffer, amount);
871+
872+
/* if write didn't set errno, assume problem is no disk space */
873+
if (returnCode != amount && errno == 0)
874+
errno = ENOSPC;
875+
869876
if (returnCode > 0)
870877
VfdCache[file].seekPos += returnCode;
871878
else

src/backend/storage/smgr/md.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.84 2001/05/10 20:38:49 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.85 2001/06/06 17:07:46 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -582,8 +582,12 @@ mdblindwrt(RelFileNode rnode,
582582
status = SM_SUCCESS;
583583

584584
/* write and optionally sync the block */
585+
errno = 0;
585586
if (write(fd, buffer, BLCKSZ) != BLCKSZ)
586587
{
588+
/* if write didn't set errno, assume problem is no disk space */
589+
if (errno == 0)
590+
errno = ENOSPC;
587591
elog(DEBUG, "mdblindwrt: write() failed: %m");
588592
status = SM_FAIL;
589593
}

src/backend/utils/init/miscinit.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.68 2001/06/01 20:27:41 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.69 2001/06/06 17:07:46 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -659,13 +659,15 @@ CreateLockFile(const char *filename, bool amPostmaster,
659659
snprintf(buffer, sizeof(buffer), "%d\n%s\n",
660660
amPostmaster ? (int) my_pid : -((int) my_pid),
661661
DataDir);
662+
errno = 0;
662663
if (write(fd, buffer, strlen(buffer)) != strlen(buffer))
663664
{
664665
int save_errno = errno;
665666

666667
close(fd);
667668
unlink(filename);
668-
errno = save_errno;
669+
/* if write didn't set errno, assume problem is no disk space */
670+
errno = save_errno ? save_errno : ENOSPC;
669671
elog(FATAL, "Can't write lock file %s: %m", filename);
670672
}
671673
close(fd);
@@ -794,9 +796,13 @@ RecordSharedMemoryInLockFile(IpcMemoryKey shmKey, IpcMemoryId shmId)
794796
* update should appear atomic to onlookers.
795797
*/
796798
len = strlen(buffer);
799+
errno = 0;
797800
if (lseek(fd, (off_t) 0, SEEK_SET) != 0 ||
798801
(int) write(fd, buffer, len) != len)
799802
{
803+
/* if write didn't set errno, assume problem is no disk space */
804+
if (errno == 0)
805+
errno = ENOSPC;
800806
elog(DEBUG, "Failed to write %s: %m", directoryLockFile);
801807
close(fd);
802808
return;

0 commit comments

Comments
 (0)