Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cf8dc9e

Browse files
Fix checksums for CLUSTER, VACUUM FULL etc.
In CLUSTER, VACUUM FULL and ALTER TABLE SET TABLESPACE I erroneously set checksum before log_newpage, which sets the LSN and invalidates the checksum. So set checksum immediately *after* log_newpage. Bug report Fujii Masao, Fix and patch by Jeff Davis
1 parent 7844608 commit cf8dc9e

File tree

2 files changed

+17
-5
lines changed

2 files changed

+17
-5
lines changed

src/backend/access/heap/rewriteheap.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,14 +273,15 @@ end_heap_rewrite(RewriteState state)
273273
/* Write the last page, if any */
274274
if (state->rs_buffer_valid)
275275
{
276-
PageSetChecksumInplace(state->rs_buffer, state->rs_blockno);
277-
278276
if (state->rs_use_wal)
279277
log_newpage(&state->rs_new_rel->rd_node,
280278
MAIN_FORKNUM,
281279
state->rs_blockno,
282280
state->rs_buffer);
283281
RelationOpenSmgr(state->rs_new_rel);
282+
283+
PageSetChecksumInplace(state->rs_buffer, state->rs_blockno);
284+
284285
smgrextend(state->rs_new_rel->rd_smgr, MAIN_FORKNUM, state->rs_blockno,
285286
(char *) state->rs_buffer, true);
286287
}
@@ -616,8 +617,6 @@ raw_heap_insert(RewriteState state, HeapTuple tup)
616617
{
617618
/* Doesn't fit, so write out the existing page */
618619

619-
PageSetChecksumInplace(page, state->rs_blockno);
620-
621620
/* XLOG stuff */
622621
if (state->rs_use_wal)
623622
log_newpage(&state->rs_new_rel->rd_node,
@@ -632,6 +631,9 @@ raw_heap_insert(RewriteState state, HeapTuple tup)
632631
* end_heap_rewrite.
633632
*/
634633
RelationOpenSmgr(state->rs_new_rel);
634+
635+
PageSetChecksumInplace(page, state->rs_blockno);
636+
635637
smgrextend(state->rs_new_rel->rd_smgr, MAIN_FORKNUM,
636638
state->rs_blockno, (char *) page, true);
637639

src/backend/commands/tablecmds.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include "commands/tablespace.h"
5252
#include "commands/trigger.h"
5353
#include "commands/typecmds.h"
54+
#include "common/relpath.h"
5455
#include "executor/executor.h"
5556
#include "foreign/foreign.h"
5657
#include "miscadmin.h"
@@ -8902,12 +8903,21 @@ copy_relation_data(SMgrRelation src, SMgrRelation dst,
89028903

89038904
smgrread(src, forkNum, blkno, buf);
89048905

8905-
PageSetChecksumInplace(page, blkno);
8906+
if (!PageIsVerified(page, blkno))
8907+
ereport(ERROR,
8908+
(errcode(ERRCODE_DATA_CORRUPTED),
8909+
errmsg("invalid page in block %u of relation %s",
8910+
blkno,
8911+
relpathbackend(src->smgr_rnode.node,
8912+
src->smgr_rnode.backend,
8913+
forkNum))));
89068914

89078915
/* XLOG stuff */
89088916
if (use_wal)
89098917
log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page);
89108918

8919+
PageSetChecksumInplace(page, blkno);
8920+
89118921
/*
89128922
* Now write the page. We say isTemp = true even if it's not a temp
89138923
* rel, because there's no need for smgr to schedule an fsync for this

0 commit comments

Comments
 (0)