Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0ffe11a

Browse files
committed
Widen xl_len field of XLogRecord header to 32 bits, so that we'll have
a more tolerable limit on the number of subtransactions or deleted filesin COMMIT and ABORT records. Buy back the extra space by eliminating thexl_xact_prev field, which isn't being used for anything and is ratherunlikely ever to be used for anything.This does not force initdb, but you do need to do pg_resetxlog if youwant to upgrade an existing 8.0 installation without initdb.
1 parentb6b71b8 commit0ffe11a

File tree

4 files changed

+68
-71
lines changed

4 files changed

+68
-71
lines changed

‎src/backend/access/transam/xlog.c

Lines changed: 61 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2004, 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.166 2004/08/2905:06:40 momjian Exp $
10+
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.167 2004/08/2916:34:47 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -409,6 +409,10 @@ static uint32 readOff = 0;
409409
/* Buffer for currently read page (BLCKSZ bytes) */
410410
staticchar*readBuf=NULL;
411411

412+
/* Buffer for current ReadRecord result (expandable) */
413+
staticchar*readRecordBuf=NULL;
414+
staticuint32readRecordBufSize=0;
415+
412416
/* State information for XLOG reading */
413417
staticXLogRecPtrReadRecPtr;
414418
staticXLogRecPtrEndRecPtr;
@@ -440,11 +444,9 @@ static bool RestoreArchivedFile(char *path, const char *xlogfname,
440444
constchar*recovername,off_texpectedSize);
441445
staticvoidPreallocXlogFiles(XLogRecPtrendptr);
442446
staticvoidMoveOfflineLogs(uint32log,uint32seg,XLogRecPtrendptr);
443-
staticXLogRecord*ReadRecord(XLogRecPtr*RecPtr,intemode,char*buffer);
447+
staticXLogRecord*ReadRecord(XLogRecPtr*RecPtr,intemode);
444448
staticboolValidXLOGHeader(XLogPageHeaderhdr,intemode);
445-
staticXLogRecord*ReadCheckpointRecord(XLogRecPtrRecPtr,
446-
intwhichChkpt,
447-
char*buffer);
449+
staticXLogRecord*ReadCheckpointRecord(XLogRecPtrRecPtr,intwhichChkpt);
448450
staticList*readTimeLineHistory(TimeLineIDtargetTLI);
449451
staticboolexistsTimeLineHistory(TimeLineIDprobeTLI);
450452
staticTimeLineIDfindNewestTimeLine(TimeLineIDstartTLI);
@@ -627,7 +629,7 @@ begin:;
627629
* may not be true forever. If you need to remove the len == 0 check,
628630
* also remove the check for xl_len == 0 in ReadRecord, below.
629631
*/
630-
if (len==0||len>MAXLOGRECSZ)
632+
if (len==0)
631633
elog(PANIC,"invalid xlog record length %u",len);
632634

633635
START_CRIT_SECTION();
@@ -745,14 +747,6 @@ begin:;
745747
/* Insert record header */
746748

747749
record->xl_prev=Insert->PrevRecord;
748-
if (no_tran)
749-
{
750-
record->xl_xact_prev.xlogid=0;
751-
record->xl_xact_prev.xrecoff=0;
752-
}
753-
else
754-
record->xl_xact_prev=MyLastRecPtr;
755-
756750
record->xl_xid=GetCurrentTransactionId();
757751
record->xl_len=len;/* doesn't include backup blocks */
758752
record->xl_info=info;
@@ -2316,14 +2310,14 @@ RecordIsValid(XLogRecord *record, XLogRecPtr recptr, int emode)
23162310
* If no valid record is available, returns NULL, or fails if emode is PANIC.
23172311
* (emode must be either PANIC or LOG.)
23182312
*
2319-
* buffer is a workspace at least _INTL_MAXLOGRECSZ bytes long. It is needed
2320-
* to reassemble a record that crosses block boundaries. Note that on
2321-
* successful return, the returned record pointer always points at buffer.
2313+
* The record is copied into readRecordBuf, so that on successful return,
2314+
* the returned record pointer always points there.
23222315
*/
23232316
staticXLogRecord*
2324-
ReadRecord(XLogRecPtr*RecPtr,intemode,char*buffer)
2317+
ReadRecord(XLogRecPtr*RecPtr,intemode)
23252318
{
23262319
XLogRecord*record;
2320+
char*buffer;
23272321
XLogRecPtrtmpRecPtr=EndRecPtr;
23282322
boolrandAccess= false;
23292323
uint32len,
@@ -2467,6 +2461,13 @@ got_record:;
24672461
RecPtr->xlogid,RecPtr->xrecoff)));
24682462
gotonext_record_is_invalid;
24692463
}
2464+
if (record->xl_rmid>RM_MAX_ID)
2465+
{
2466+
ereport(emode,
2467+
(errmsg("invalid resource manager ID %u at %X/%X",
2468+
record->xl_rmid,RecPtr->xlogid,RecPtr->xrecoff)));
2469+
gotonext_record_is_invalid;
2470+
}
24702471

24712472
/*
24722473
* Compute total length of record including any appended backup
@@ -2481,24 +2482,34 @@ got_record:;
24812482
}
24822483

24832484
/*
2484-
* Make sure it will fit in buffer (currently, it is mechanically
2485-
* impossible for this test to fail, but it seems like a good idea
2486-
* anyway).
2485+
* Allocate or enlarge readRecordBuf as needed. To avoid useless
2486+
* small increases, round its size to a multiple of BLCKSZ, and make
2487+
* sure it's at least 4*BLCKSZ to start with. (That is enough for
2488+
* all "normal" records, but very large commit or abort records might
2489+
* need more space.)
24872490
*/
2488-
if (total_len>_INTL_MAXLOGRECSZ)
2489-
{
2490-
ereport(emode,
2491-
(errmsg("record length %u at %X/%X too long",
2492-
total_len,RecPtr->xlogid,RecPtr->xrecoff)));
2493-
gotonext_record_is_invalid;
2494-
}
2495-
if (record->xl_rmid>RM_MAX_ID)
2491+
if (total_len>readRecordBufSize)
24962492
{
2497-
ereport(emode,
2498-
(errmsg("invalid resource manager ID %u at %X/%X",
2499-
record->xl_rmid,RecPtr->xlogid,RecPtr->xrecoff)));
2500-
gotonext_record_is_invalid;
2493+
uint32newSize=total_len;
2494+
2495+
newSize+=BLCKSZ- (newSize %BLCKSZ);
2496+
newSize=Max(newSize,4*BLCKSZ);
2497+
if (readRecordBuf)
2498+
free(readRecordBuf);
2499+
readRecordBuf= (char*)malloc(newSize);
2500+
if (!readRecordBuf)
2501+
{
2502+
readRecordBufSize=0;
2503+
/* We treat this as a "bogus data" condition */
2504+
ereport(emode,
2505+
(errmsg("record length %u at %X/%X too long",
2506+
total_len,RecPtr->xlogid,RecPtr->xrecoff)));
2507+
gotonext_record_is_invalid;
2508+
}
2509+
readRecordBufSize=newSize;
25012510
}
2511+
2512+
buffer=readRecordBuf;
25022513
nextRecord=NULL;
25032514
len=BLCKSZ-RecPtr->xrecoff %BLCKSZ;
25042515
if (total_len>len)
@@ -3481,8 +3492,6 @@ BootStrapXLOG(void)
34813492
record= (XLogRecord*) ((char*)page+SizeOfXLogLongPHD);
34823493
record->xl_prev.xlogid=0;
34833494
record->xl_prev.xrecoff=0;
3484-
record->xl_xact_prev.xlogid=0;
3485-
record->xl_xact_prev.xrecoff=0;
34863495
record->xl_xid=InvalidTransactionId;
34873496
record->xl_len=sizeof(checkPoint);
34883497
record->xl_info=XLOG_CHECKPOINT_SHUTDOWN;
@@ -3981,12 +3990,8 @@ StartupXLOG(void)
39813990
uint32endLogId;
39823991
uint32endLogSeg;
39833992
XLogRecord*record;
3984-
char*buffer;
39853993
uint32freespace;
39863994

3987-
/* Use malloc() to ensure record buffer is MAXALIGNED */
3988-
buffer= (char*)malloc(_INTL_MAXLOGRECSZ);
3989-
39903995
CritSectionCount++;
39913996

39923997
/*
@@ -4063,7 +4068,7 @@ StartupXLOG(void)
40634068
* from the checkpoint it identifies, rather than using
40644069
* pg_control.
40654070
*/
4066-
record=ReadCheckpointRecord(checkPointLoc,0,buffer);
4071+
record=ReadCheckpointRecord(checkPointLoc,0);
40674072
if (record!=NULL)
40684073
{
40694074
ereport(LOG,
@@ -4085,7 +4090,7 @@ StartupXLOG(void)
40854090
* according to pg_control is broken, try the next-to-last one.
40864091
*/
40874092
checkPointLoc=ControlFile->checkPoint;
4088-
record=ReadCheckpointRecord(checkPointLoc,1,buffer);
4093+
record=ReadCheckpointRecord(checkPointLoc,1);
40894094
if (record!=NULL)
40904095
{
40914096
ereport(LOG,
@@ -4095,7 +4100,7 @@ StartupXLOG(void)
40954100
else
40964101
{
40974102
checkPointLoc=ControlFile->prevCheckPoint;
4098-
record=ReadCheckpointRecord(checkPointLoc,2,buffer);
4103+
record=ReadCheckpointRecord(checkPointLoc,2);
40994104
if (record!=NULL)
41004105
{
41014106
ereport(LOG,
@@ -4198,12 +4203,12 @@ StartupXLOG(void)
41984203
if (XLByteLT(checkPoint.redo,RecPtr))
41994204
{
42004205
/* back up to find the record */
4201-
record=ReadRecord(&(checkPoint.redo),PANIC,buffer);
4206+
record=ReadRecord(&(checkPoint.redo),PANIC);
42024207
}
42034208
else
42044209
{
42054210
/* just have to read next record after CheckPoint */
4206-
record=ReadRecord(NULL,LOG,buffer);
4211+
record=ReadRecord(NULL,LOG);
42074212
}
42084213

42094214
if (record!=NULL)
@@ -4263,7 +4268,7 @@ StartupXLOG(void)
42634268

42644269
LastRec=ReadRecPtr;
42654270

4266-
record=ReadRecord(NULL,LOG,buffer);
4271+
record=ReadRecord(NULL,LOG);
42674272
}while (record!=NULL&&recoveryContinue);
42684273

42694274
/*
@@ -4287,7 +4292,7 @@ StartupXLOG(void)
42874292
* Re-fetch the last valid or last applied record, so we can identify
42884293
* the exact endpoint of what we consider the valid portion of WAL.
42894294
*/
4290-
record=ReadRecord(&LastRec,PANIC,buffer);
4295+
record=ReadRecord(&LastRec,PANIC);
42914296
EndOfLog=EndRecPtr;
42924297
XLByteToPrevSeg(EndOfLog,endLogId,endLogSeg);
42934298

@@ -4404,7 +4409,7 @@ StartupXLOG(void)
44044409
RecPtr.xlogid,RecPtr.xrecoff)));
44054410
do
44064411
{
4407-
record=ReadRecord(&RecPtr,PANIC,buffer);
4412+
record=ReadRecord(&RecPtr,PANIC);
44084413
if (TransactionIdIsValid(record->xl_xid)&&
44094414
!TransactionIdDidCommit(record->xl_xid))
44104415
RmgrTable[record->xl_rmid].rm_undo(EndRecPtr,record);
@@ -4498,8 +4503,12 @@ StartupXLOG(void)
44984503
free(readBuf);
44994504
readBuf=NULL;
45004505
}
4501-
4502-
free(buffer);
4506+
if (readRecordBuf)
4507+
{
4508+
free(readRecordBuf);
4509+
readRecordBuf=NULL;
4510+
readRecordBufSize=0;
4511+
}
45034512
}
45044513

45054514
/*
@@ -4509,9 +4518,7 @@ StartupXLOG(void)
45094518
* 1 for "primary", 2 for "secondary", 0 for "other" (backup_label)
45104519
*/
45114520
staticXLogRecord*
4512-
ReadCheckpointRecord(XLogRecPtrRecPtr,
4513-
intwhichChkpt,
4514-
char*buffer)
4521+
ReadCheckpointRecord(XLogRecPtrRecPtr,intwhichChkpt)
45154522
{
45164523
XLogRecord*record;
45174524

@@ -4535,7 +4542,7 @@ ReadCheckpointRecord(XLogRecPtr RecPtr,
45354542
returnNULL;
45364543
}
45374544

4538-
record=ReadRecord(&RecPtr,LOG,buffer);
4545+
record=ReadRecord(&RecPtr,LOG);
45394546

45404547
if (record==NULL)
45414548
{
@@ -5080,9 +5087,8 @@ xlog_outrec(char *buf, XLogRecord *record)
50805087
intbkpb;
50815088
inti;
50825089

5083-
sprintf(buf+strlen(buf),"prev %X/%X;xprev %X/%X;xid %u",
5090+
sprintf(buf+strlen(buf),"prev %X/%X; xid %u",
50845091
record->xl_prev.xlogid,record->xl_prev.xrecoff,
5085-
record->xl_xact_prev.xlogid,record->xl_xact_prev.xrecoff,
50865092
record->xl_xid);
50875093

50885094
for (i=0,bkpb=0;i<XLR_MAX_BKP_BLOCKS;i++)

‎src/bin/pg_resetxlog/pg_resetxlog.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
2424
* Portions Copyright (c) 1994, Regents of the University of California
2525
*
26-
* $PostgreSQL: pgsql/src/bin/pg_resetxlog/pg_resetxlog.c,v 1.23 2004/08/2905:06:54 momjian Exp $
26+
* $PostgreSQL: pgsql/src/bin/pg_resetxlog/pg_resetxlog.c,v 1.24 2004/08/2916:34:48 tgl Exp $
2727
*
2828
*-------------------------------------------------------------------------
2929
*/
@@ -645,8 +645,6 @@ WriteEmptyXLOG(void)
645645
record= (XLogRecord*) ((char*)page+SizeOfXLogLongPHD);
646646
record->xl_prev.xlogid=0;
647647
record->xl_prev.xrecoff=0;
648-
record->xl_xact_prev.xlogid=0;
649-
record->xl_xact_prev.xrecoff=0;
650648
record->xl_xid=InvalidTransactionId;
651649
record->xl_len=sizeof(CheckPoint);
652650
record->xl_info=XLOG_CHECKPOINT_SHUTDOWN;

‎src/include/access/xlog.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.57 2004/08/2905:06:55 momjian Exp $
9+
* $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.58 2004/08/2916:34:48 tgl Exp $
1010
*/
1111
#ifndefXLOG_H
1212
#defineXLOG_H
@@ -35,18 +35,18 @@ typedef struct XLogRecord
3535
{
3636
crc64xl_crc;/* CRC for this record */
3737
XLogRecPtrxl_prev;/* ptr to previous record in log */
38-
XLogRecPtrxl_xact_prev;/* ptr to previous record of this xact */
3938
TransactionIdxl_xid;/* xact id */
40-
uint16xl_len;/* total len of rmgr data */
39+
uint32xl_len;/* total len of rmgr data */
4140
uint8xl_info;/* flag bits, see below */
4241
RmgrIdxl_rmid;/* resource manager for this record */
4342

43+
/* Depending on MAXALIGN, there are either 2 or 6 wasted bytes here */
44+
4445
/* ACTUAL LOG DATA FOLLOWS AT END OF STRUCT */
4546

4647
}XLogRecord;
4748

4849
#defineSizeOfXLogRecordMAXALIGN(sizeof(XLogRecord))
49-
#defineMAXLOGRECSZ65535/* the most that'll fit in xl_len */
5050

5151
#defineXLogRecGetData(record)((char*) (record) + SizeOfXLogRecord)
5252

‎src/include/access/xlog_internal.h

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
1212
* Portions Copyright (c) 1994, Regents of the University of California
1313
*
14-
* $PostgreSQL: pgsql/src/include/access/xlog_internal.h,v 1.4 2004/08/2905:06:55 momjian Exp $
14+
* $PostgreSQL: pgsql/src/include/access/xlog_internal.h,v 1.5 2004/08/2916:34:48 tgl Exp $
1515
*/
1616
#ifndefXLOG_INTERNAL_H
1717
#defineXLOG_INTERNAL_H
@@ -58,7 +58,7 @@ typedef struct XLogContRecord
5858
/*
5959
* Each page of XLOG file has a header like this:
6060
*/
61-
#defineXLOG_PAGE_MAGIC0xD05B/* can be used as WAL version indicator */
61+
#defineXLOG_PAGE_MAGIC0xD05C/* can be used as WAL version indicator */
6262

6363
typedefstructXLogPageHeaderData
6464
{
@@ -203,13 +203,6 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader;
203203

204204
externcharXLogDir[MAXPGPATH];
205205

206-
/*
207-
* _INTL_MAXLOGRECSZ: max space needed for a record including header and
208-
* any backup-block data.
209-
*/
210-
#define_INTL_MAXLOGRECSZ(SizeOfXLogRecord + MAXLOGRECSZ + \
211-
XLR_MAX_BKP_BLOCKS * (sizeof(BkpBlock) + BLCKSZ))
212-
213206

214207
/*
215208
* Method table for resource managers.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp