8000 Fix possible page corruption by ALTER TABLE .. SET TABLESPACE. · danielcode/postgres@76a106f · GitHub
[go: up one dir, main page]

Skip to content

Commit 76a106f

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 7c294bf commit 76a106f

File tree

2 files changed

+21
-6
lines changed

2 files changed

+21
-6
lines changed

src/backend/access/heap/heapam.c

Lines changed: 11 additions & 3 deletions
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.200.2.3 2006/11/17 18:00:25 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.200.2.4 2010/07/29 16:15:33 rhaas Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -2740,8 +2740,16 @@ heap_xlog_newpage(XLogRecPtr lsn, XLogRecord *record)
27402740
Assert(record->xl_len == SizeOfHeapNewpage + BLCKSZ);
27412741
memcpy(page, (char *) xlrec + SizeOfHeapNewpage, BLCKSZ);
27422742

2743-
PageSetLSN(page, lsn);
2744-
PageSetTLI(page, ThisTimeLineID);
2743+
/*
2744+
* The page may be uninitialized. If so, we can't set the LSN
2745+
* and TLI because that would corrupt the page.
2746+
*/
2747+
if (!PageIsNew(page))
2748+
{
2749+
PageSetLSN(page, lsn);
2750+
PageSetTLI(page, ThisTimeLineID);
2751+
}
2752+
27452753
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
27462754
WriteBuffer(buffer);
27472755
}

src/backend/commands/tablecmds.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.174.2.10 2010/07/01 14:11:03 rhaas Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.174.2.11 2010/07/29 16:15:33 rhaas Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -5893,8 +5893,15 @@ copy_relation_data(Relation rel, SMgrRelation dst)
58935893

58945894
recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_NEWPAGE, rdata);
58955895

5896-
PageSetLSN(page, recptr);
5897-
PageSetTLI(page, ThisTimeLineID);
5896+
/*
5897+
* The page may be uninitialized. If so, we can't set the LSN
5898+
* and TLI because that would corrupt the page.
5899+
*/
5900+
if (!PageIsNew(page))
5901+
{
5902+
PageSetLSN(page, recptr);
5903+
PageSetTLI(page, ThisTimeLineID);
5904+
}
58985905

58995906
END_CRIT_SECTION();
59005907
}

0 commit comments

Comments
 (0)
0