|
58 | 58 | #include "pgstat.h"
|
59 | 59 | #include "storage/fd.h"
|
60 | 60 | #include "storage/shmem.h"
|
| 61 | +#include "storage/smgr.h" |
61 | 62 |
|
62 | 63 | #define SlruFileName(ctl, path, seg) \
|
63 | 64 | snprintf(path, MAXPGPATH, "%s/%04X", (ctl)->Dir, seg)
|
@@ -616,6 +617,66 @@ SimpleLruWritePage(SlruCtl ctl, int slotno)
|
616 | 617 | SlruInternalWritePage(ctl, slotno, NULL);
|
617 | 618 | }
|
618 | 619 |
|
| 620 | + |
| 621 | +/* |
| 622 | + * NEON: we do not want to include large pg_xact/multixact files in basebackup and prefer |
| 623 | + * to download them on demand to reduce startup time. |
| 624 | + * If SLRU segment is not found, we try to download it from page server |
| 625 | + */ |
| 626 | +static int |
| 627 | +SimpleLruDownloadSegment(SlruCtl ctl, int pageno, char const* path) |
| 628 | +{ |
| 629 | + int segno; |
| 630 | + int fd = -1; |
| 631 | + int n_blocks; |
| 632 | + char* buffer; |
| 633 | + |
| 634 | + static SMgrRelationData dummy_smgr_rel = {0}; |
| 635 | + |
| 636 | + /* If page is greater than latest written page, then do not try to download segment from server */ |
| 637 | + if (ctl->PagePrecedes(ctl->shared->latest_page_number, pageno)) |
| 638 | + return -1; |
| 639 | + |
| 640 | + if (!dummy_smgr_rel.smgr) |
| 641 | + { |
| 642 | + RelFileNode rnode = {0}; |
| 643 | + dummy_smgr_rel.smgr = smgr(InvalidBackendId, rnode); |
| 644 | + } |
| 645 | + segno = pageno / SLRU_PAGES_PER_SEGMENT; |
| 646 | + |
| 647 | + buffer = palloc(BLCKSZ * SLRU_PAGES_PER_SEGMENT); |
| 648 | + n_blocks = smgr_read_slru_segment(&dummy_smgr_rel, path, segno, buffer); |
| 649 | + if (n_blocks > 0) |
| 650 | + { |
| 651 | + fd = OpenTransientFile(path, O_RDWR | O_CREAT | PG_BINARY); |
| 652 | + if (fd < 0) |
| 653 | + { |
| 654 | + slru_errcause = SLRU_OPEN_FAILED; |
| 655 | + slru_errno = errno; |
| 656 | + pfree(buffer); |
| 657 | + return -1; |
| 658 | + } |
| 659 | + errno = 0; |
| 660 | + pgstat_report_wait_start(WAIT_EVENT_SLRU_WRITE); |
| 661 | + if (pg_pwrite(fd, buffer, n_blocks*BLCKSZ, 0) != n_blocks*BLCKSZ) |
| 662 | + { |
| 663 | + pgstat_report_wait_end(); |
| 664 | + /* if write didn't set errno, assume problem is no disk space */ |
| 665 | + if (errno == 0) |
| 666 | + errno = ENOSPC; |
| 667 | + slru_errcause = SLRU_WRITE_FAILED; |
| 668 | + slru_errno = errno; |
| 669 | + |
| 670 | + CloseTransientFile(fd); |
| 671 | + pfree(buffer); |
| 672 | + return -1; |
| 673 | + } |
| 674 | + pgstat_report_wait_end(); |
| 675 | + } |
| 676 | + pfree(buffer); |
| 677 | + return fd; |
| 678 | +} |
| 679 | + |
619 | 680 | /*
|
620 | 681 | * Return whether the given page exists on disk.
|
621 | 682 | *
|
@@ -643,12 +704,18 @@ SimpleLruDoesPhysicalPageExist(SlruCtl ctl, int pageno)
|
643 | 704 | {
|
644 | 705 | /* expected: file doesn't exist */
|
645 | 706 | if (errno == ENOENT)
|
646 |
| - return false; |
647 |
| - |
648 |
| - /* report error normally */ |
649 |
| - slru_errcause = SLRU_OPEN_FAILED; |
650 |
| - slru_errno = errno; |
651 |
| - SlruReportIOError(ctl, pageno, 0); |
| 707 | + { |
| 708 | + fd = SimpleLruDownloadSegment(ctl, pageno, path); |
| 709 | + if (fd < 0) |
| 710 | + return false; |
| 711 | + } |
| 712 | + else |
| 713 | + { |
| 714 | + /* report error normally */ |
| 715 | + slru_errcause = SLRU_OPEN_FAILED; |
| 716 | + slru_errno = errno; |
| 717 | + SlruReportIOError(ctl, pageno, 0); |
| 718 | + } |
652 | 719 | }
|
653 | 720 |
|
654 | 721 | if ((endpos = lseek(fd, 0, SEEK_END)) < 0)
|
@@ -702,18 +769,30 @@ SlruPhysicalReadPage(SlruCtl ctl, int pageno, int slotno)
|
702 | 769 | fd = OpenTransientFile(path, O_RDONLY | PG_BINARY);
|
703 | 770 | if (fd < 0)
|
704 | 771 | {
|
705 |
| - if (errno != ENOENT || !InRecovery) |
| 772 | + if (errno != ENOENT) |
706 | 773 | {
|
707 | 774 | slru_errcause = SLRU_OPEN_FAILED;
|
708 | 775 | slru_errno = errno;
|
709 | 776 | return false;
|
710 | 777 | }
|
711 |
| - |
712 |
| - ereport(LOG, |
713 |
| - (errmsg("file \"%s\" doesn't exist, reading as zeroes", |
714 |
| - path))); |
715 |
| - MemSet(shared->page_buffer[slotno], 0, BLCKSZ); |
716 |
| - return true; |
| 778 | + fd = SimpleLruDownloadSegment(ctl, pageno, path); |
| 779 | + if (fd < 0) |
| 780 | + { |
| 781 | + if (!InRecovery) |
| 782 | + { |
| 783 | + slru_errcause = SLRU_OPEN_FAILED; |
| 784 | + slru_errno = errno; |
| 785 | + return false; |
| 786 | + } |
| 787 | + else |
| 788 | + { |
| 789 | + ereport(LOG, |
| 790 | + (errmsg("file \"%s\" doesn't exist, reading as zeroes", |
| 791 | + path))); |
| 792 | + MemSet(shared->page_buffer[slotno], 0, BLCKSZ); |
| 793 | + return true; |
| 794 | + } |
| 795 | + } |
717 | 796 | }
|
718 | 797 |
|
719 | 798 | errno = 0;
|
|
0 commit comments