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

Commit 1a07862

Browse files
committed
Fix possible page corruption by ALTER TABLE .. SET TABLESPACE.
If a zeroed page is present in the heap, ALTER TABLE .. SET TABLESPACE will set the LSN and TLI while copying it, which is wrong, and heap_xlog_newpage() will do the same thing during replay, so the corruption propagates to any standby. Note, however, that the bug can't be demonstrated unless archiving is enabled, since in that case we skip WAL logging altogether, and the LSN/TLI are not set. Back-patch to 8.0; prior releases do not have tablespaces. Analysis and patch by Jeff Davis. Adjustments for back-branches and minor wordsmithing by me.
1 parent 04e17ba commit 1a07862

File tree

1 file changed

+20
-5
lines changed

1 file changed

+20
-5
lines changed

src/backend/access/heap/heapam.c

+20-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.292 2010/07/06 19:18:55 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.293 2010/07/29 16:14:36 rhaas Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -4079,8 +4079,15 @@ log_newpage(RelFileNode *rnode, ForkNumber forkNum, BlockNumber blkno,
40794079

40804080
recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_NEWPAGE, rdata);
40814081

4082-
PageSetLSN(page, recptr);
4083-
PageSetTLI(page, ThisTimeLineID);
4082+
/*
4083+
* The page may be uninitialized. If so, we can't set the LSN
4084+
* and TLI because that would corrupt the page.
4085+
*/
4086+
if (!PageIsNew(page))
4087+
{
4088+
PageSetLSN(page, recptr);
4089+
PageSetTLI(page, ThisTimeLineID);
4090+
}
40844091

40854092
END_CRIT_SECTION();
40864093

@@ -4266,8 +4273,16 @@ heap_xlog_newpage(XLogRecPtr lsn, XLogRecord *record)
42664273
Assert(record->xl_len == SizeOfHeapNewpage + BLCKSZ);
42674274
memcpy(page, (char *) xlrec + SizeOfHeapNewpage, BLCKSZ);
42684275

4269-
PageSetLSN(page, lsn);
4270-
PageSetTLI(page, ThisTimeLineID);
4276+
/*
4277+
* The page may be uninitialized. If so, we can't set the LSN
4278+
* and TLI because that would corrupt the page.
4279+
*/
4280+
if (!PageIsNew(page))
4281+
{
4282+
PageSetLSN(page, lsn);
4283+
PageSetTLI(page, ThisTimeLineID);
4284+
}
4285+
42714286
MarkBufferDirty(buffer);
42724287
UnlockReleaseBuffer(buffer);
42734288
}

0 commit comments

Comments
 (0)