@@ -620,23 +620,25 @@ SimpleLruWritePage(SlruCtl ctl, int slotno)
620620
621621
622622/*
623- * NEON: we do not want to include large pg_xact/multixact files in basebackup and prefer
624- * to download them on demand to reduce startup time.
625- * If SLRU segment is not found, we try to download it from page server
623+ * NEON: we do not want to include large pg_xact/multixact files in the
624+ * basebackup and prefer to download them on demand to reduce startup time.
625+ *
626+ * If SLRU segment is not found, we try to download it from the pageserver.
627+ *
628+ * Returns:
629+ * true if the file was successfully downloaded
630+ * false if the file was not found in pageserver
631+ * ereports if some other error happened
626632 */
627- static int
628- SimpleLruDownloadSegment (SlruCtl ctl , int pageno , char const * path )
633+ static bool
634+ SimpleLruDownloadSegment (SlruCtl ctl , int pageno , char const * path )
629635{
630- int segno ;
631- int fd = -1 ;
632- int n_blocks ;
633- char * buffer ;
634-
636+ int segno ;
635637 static SMgrRelationData dummy_smgr_rel = {0 };
636638
637639 /* If page is greater than latest written page, then do not try to download segment from server */
638640 if (ctl -> PagePrecedes (ctl -> shared -> latest_page_number , pageno ))
639- return -1 ;
641+ return false ;
640642
641643 if (!dummy_smgr_rel .smgr )
642644 {
@@ -645,45 +647,7 @@ SimpleLruDownloadSegment(SlruCtl ctl, int pageno, char const* path)
645647 }
646648 segno = pageno / SLRU_PAGES_PER_SEGMENT ;
647649
648- if (neon_use_communicator_worker ) {
649- buffer = NULL ;
650- } else {
651- buffer = palloc (BLCKSZ * SLRU_PAGES_PER_SEGMENT );
652- }
653-
654- n_blocks = smgr_read_slru_segment (& dummy_smgr_rel , path , segno , buffer );
655- if (n_blocks > 0 )
656- {
657- fd = OpenTransientFile (path , O_RDWR | O_CREAT | PG_BINARY );
658- if (fd < 0 )
659- {
660- slru_errcause = SLRU_OPEN_FAILED ;
661- slru_errno = errno ;
662- pfree (buffer );
663- return -1 ;
664- }
665-
666- if (!neon_use_communicator_worker ) {
667- errno = 0 ;
668- pgstat_report_wait_start (WAIT_EVENT_SLRU_WRITE );
669- if (pg_pwrite (fd , buffer , n_blocks * BLCKSZ , 0 ) != n_blocks * BLCKSZ )
670- {
671- pgstat_report_wait_end ();
672- /* if write didn't set errno, assume problem is no disk space */
673- if (errno == 0 )
674- errno = ENOSPC ;
675- slru_errcause = SLRU_WRITE_FAILED ;
676- slru_errno = errno ;
677-
678- CloseTransientFile (fd );
679- pfree (buffer );
680- return -1 ;
681- }
682- pgstat_report_wait_end ();
683- }
684- }
685- pfree (buffer );
686- return fd ;
650+ return smgr_read_slru_segment (& dummy_smgr_rel , path , segno );
687651}
688652
689653/*
@@ -702,29 +666,34 @@ SimpleLruDoesPhysicalPageExist(SlruCtl ctl, int pageno)
702666 int fd ;
703667 bool result ;
704668 off_t endpos ;
669+ bool attempted_download = false;
705670
706671 /* update the stats counter of checked pages */
707672 pgstat_count_slru_page_exists (ctl -> shared -> slru_stats_idx );
708673
709674 SlruFileName (ctl , path , segno );
710675
676+ retry_after_download :
711677 fd = OpenTransientFile (path , O_RDONLY | PG_BINARY );
712678 if (fd < 0 )
713679 {
714- /* expected: file doesn't exist */
715- if (errno == ENOENT )
680+ if (errno == ENOENT && !attempted_download )
716681 {
717- fd = SimpleLruDownloadSegment (ctl , pageno , path );
718- if (fd < 0 )
719- return false;
720- }
721- else
722- {
723- /* report error normally */
724- slru_errcause = SLRU_OPEN_FAILED ;
725- slru_errno = errno ;
726- SlruReportIOError (ctl , pageno , 0 );
682+ /* Try to download the file from the pageserver */
683+ attempted_download = true;
684+ if (SimpleLruDownloadSegment (ctl , pageno , path ))
685+ goto retry_after_download ;
686+ errno = ENOENT ;
727687 }
688+
689+ /* expected: file doesn't exist */
690+ if (errno == ENOENT )
691+ return false;
692+
693+ /* report error normally */
694+ slru_errcause = SLRU_OPEN_FAILED ;
695+ slru_errno = errno ;
696+ SlruReportIOError (ctl , pageno , 0 );
728697 }
729698
730699 if ((endpos = lseek (fd , 0 , SEEK_END )) < 0 )
@@ -765,6 +734,7 @@ SlruPhysicalReadPage(SlruCtl ctl, int pageno, int slotno)
765734 off_t offset = rpageno * BLCKSZ ;
766735 char path [MAXPGPATH ];
767736 int fd ;
737+ bool attempted_download = false;
768738
769739 SlruFileName (ctl , path , segno );
770740
@@ -775,33 +745,31 @@ SlruPhysicalReadPage(SlruCtl ctl, int pageno, int slotno)
775745 * SlruPhysicalWritePage). Hence, if we are InRecovery, allow the case
776746 * where the file doesn't exist, and return zeroes instead.
777747 */
748+ retry_after_download :
778749 fd = OpenTransientFile (path , O_RDONLY | PG_BINARY );
779750 if (fd < 0 )
780751 {
781- if (errno != ENOENT )
752+ if (errno == ENOENT && !attempted_download )
753+ {
754+ /* Try to download the file from the pageserver */
755+ attempted_download = true;
756+ if (SimpleLruDownloadSegment (ctl , pageno , path ))
757+ goto retry_after_download ;
758+ errno = ENOENT ;
759+ }
760+
761+ if (errno != ENOENT || !InRecovery )
782762 {
783763 slru_errcause = SLRU_OPEN_FAILED ;
784764 slru_errno = errno ;
785765 return false;
786766 }
787- fd = SimpleLruDownloadSegment (ctl , pageno , path );
788- if (fd < 0 )
789- {
790- if (!InRecovery )
791- {
792- slru_errcause = SLRU_OPEN_FAILED ;
793- slru_errno = errno ;
794- return false;
795- }
796- else
797- {
798- ereport (LOG ,
799- (errmsg ("file \"%s\" doesn't exist, reading as zeroes" ,
800- path )));
801- MemSet (shared -> page_buffer [slotno ], 0 , BLCKSZ );
802- return true;
803- }
804- }
767+
768+ ereport (LOG ,
769+ (errmsg ("file \"%s\" doesn't exist, reading as zeroes" ,
770+ path )));
771+ MemSet (shared -> page_buffer [slotno ], 0 , BLCKSZ );
772+ return true;
805773 }
806774
807775 errno = 0 ;
0 commit comments