mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
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.
This commit is contained in:
parent
44b16a2cf5
commit
fb28d2604a
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.222.2.3 2008/12/16 16:26:21 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.222.2.4 2010/07/29 16:15:18 rhaas Exp $
|
||||
*
|
||||
*
|
||||
* INTERFACE ROUTINES
|
||||
@ -3393,8 +3393,16 @@ heap_xlog_newpage(XLogRecPtr lsn, XLogRecord *record)
|
||||
Assert(record->xl_len == SizeOfHeapNewpage + BLCKSZ);
|
||||
memcpy(page, (char *) xlrec + SizeOfHeapNewpage, BLCKSZ);
|
||||
|
||||
PageSetLSN(page, lsn);
|
||||
PageSetTLI(page, ThisTimeLineID);
|
||||
/*
|
||||
* The page may be uninitialized. If so, we can't set the LSN
|
||||
* and TLI because that would corrupt the page.
|
||||
*/
|
||||
if (!PageIsNew(page))
|
||||
{
|
||||
PageSetLSN(page, lsn);
|
||||
PageSetTLI(page, ThisTimeLineID);
|
||||
}
|
||||
|
||||
MarkBufferDirty(buffer);
|
||||
UnlockReleaseBuffer(buffer);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.206.2.9 2010/07/01 14:11:23 rhaas Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.206.2.10 2010/07/29 16:15:18 rhaas Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -6151,8 +6151,15 @@ copy_relation_data(Relation rel, SMgrRelation dst)
|
||||
|
||||
recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_NEWPAGE, rdata);
|
||||
|
||||
PageSetLSN(page, recptr);
|
||||
PageSetTLI(page, ThisTimeLineID);
|
||||
/*
|
||||
* The page may be uninitialized. If so, we can't set the LSN
|
||||
* and TLI because that would corrupt the page.
|
||||
*/
|
||||
if (!PageIsNew(page))
|
||||
{
|
||||
PageSetLSN(page, recptr);
|
||||
PageSetTLI(page, ThisTimeLineID);
|
||||
}
|
||||
|
||||
END_CRIT_SECTION();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user