diff --git a/pageserver/src/repository.rs b/pageserver/src/repository.rs index ddcaabfa97..0881b5a61c 100644 --- a/pageserver/src/repository.rs +++ b/pageserver/src/repository.rs @@ -509,16 +509,16 @@ mod tests { // Create a relation on the timeline tline.init_valid_lsn(Lsn(1)); - tline.put_page_image(TEST_BUF(0), Lsn(2), TEST_IMG("foo blk 0 at 2"))?; - tline.put_page_image(TEST_BUF(0), Lsn(3), TEST_IMG("foo blk 0 at 3"))?; - tline.put_page_image(TEST_BUF(0), Lsn(4), TEST_IMG("foo blk 0 at 4"))?; + tline.put_page_image(TEST_BUF(0), Lsn(2), TEST_IMG("foo blk 0 at 2"), true)?; + tline.put_page_image(TEST_BUF(0), Lsn(3), TEST_IMG("foo blk 0 at 3"), true)?; + tline.put_page_image(TEST_BUF(0), Lsn(4), TEST_IMG("foo blk 0 at 4"), true)?; // Create another relation - let buftag2 = BufferTag { + let buftag2 = ObjectTag::RelationBuffer(BufferTag { rel: TESTREL_B, blknum: 0, - }; - tline.put_page_image(buftag2, Lsn(2), TEST_IMG("foobar blk 0 at 2"))?; + }); + tline.put_page_image(buftag2, Lsn(2), TEST_IMG("foobar blk 0 at 2"), true)?; tline.advance_last_valid_lsn(Lsn(4)); @@ -527,7 +527,7 @@ mod tests { repo.branch_timeline(timelineid, newtimelineid, Lsn(3))?; let newtline = repo.get_timeline(newtimelineid)?; - newtline.put_page_image(TEST_BUF(0), Lsn(4), TEST_IMG("bar blk 0 at 4"))?; + newtline.put_page_image(TEST_BUF(0), Lsn(4), TEST_IMG("bar blk 0 at 4"), true)?; newtline.advance_last_valid_lsn(Lsn(4)); // Check page contents on both branches diff --git a/pageserver/src/restore_local_repo.rs b/pageserver/src/restore_local_repo.rs index c3cdf273e2..ad5e7cb298 100644 --- a/pageserver/src/restore_local_repo.rs +++ b/pageserver/src/restore_local_repo.rs @@ -67,7 +67,13 @@ pub fn import_timeline_from_postgres_datadir( // These special files appear in the snapshot, but are not needed by the page server Some("pg_control") => { - import_nonrel_file(timeline, lsn, ObjectTag::ControlFile, &direntry.path())? + import_nonrel_file(timeline, lsn, ObjectTag::ControlFile, &direntry.path())?; + // Extract checkpoint record from pg_control and store is as separate object + let pg_control_bytes = + timeline.get_page_at_lsn_nowait(ObjectTag::ControlFile, lsn)?; + let pg_control = ControlFileData::decode(&pg_control_bytes)?; + let checkpoint_bytes = pg_control.checkPointCopy.encode(); + timeline.put_page_image(ObjectTag::Checkpoint, lsn, checkpoint_bytes, false)?; } Some("pg_filenode.map") => import_nonrel_file( timeline, @@ -294,14 +300,6 @@ pub fn import_timeline_wal(walpath: &Path, timeline: &dyn Timeline, startpoint: let checkpoint_bytes = timeline.get_page_at_lsn_nowait(ObjectTag::Checkpoint, startpoint)?; let mut checkpoint = CheckPoint::decode(&checkpoint_bytes)?; - // get_page_at_lsn_nowait returns pages with zeros when object is not found in the storage. - // nextXid can not be zero, so this check is used to detect situation when checkpoint record needs to be initialized. - if checkpoint.nextXid.value == 0 { - let pg_control_bytes = - timeline.get_page_at_lsn_nowait(ObjectTag::ControlFile, startpoint)?; - let pg_control = ControlFileData::decode(&pg_control_bytes)?; - checkpoint = pg_control.checkPointCopy; - } loop { // FIXME: assume postgresql tli 1 for now