@@ -540,7 +540,7 @@ compress_and_backup_page(pgFile *file, BlockNumber blknum,
540
540
* backup with special header.
541
541
*/
542
542
void
543
- backup_data_file_new (ConnectionArgs * conn_arg , pgFile * file ,
543
+ backup_data_file (ConnectionArgs * conn_arg , pgFile * file ,
544
544
const char * from_fullpath , const char * to_fullpath ,
545
545
XLogRecPtr prev_backup_start_lsn , BackupMode backup_mode ,
546
546
CompressAlg calg , int clevel , uint32 checksum_version ,
@@ -698,335 +698,6 @@ backup_data_file_new(ConnectionArgs* conn_arg, pgFile *file,
698
698
pg_free (headers );
699
699
}
700
700
701
- /*
702
- * Backup data file in the from_root directory to the to_root directory with
703
- * same relative path. If prev_backup_start_lsn is not NULL, only pages with
704
- * higher lsn will be copied.
705
- * Not just copy file, but read it block by block (use bitmap in case of
706
- * incremental backup), validate checksum, optionally compress and write to
707
- * backup with special header.
708
- */
709
- void
710
- backup_data_file (ConnectionArgs * conn_arg , pgFile * file ,
711
- const char * from_fullpath , const char * to_fullpath ,
712
- XLogRecPtr prev_backup_start_lsn , BackupMode backup_mode ,
713
- CompressAlg calg , int clevel , uint32 checksum_version ,
714
- int ptrack_version_num , const char * ptrack_schema , bool missing_ok )
715
- {
716
- FILE * in = NULL ;
717
- FILE * out = NULL ;
718
- BlockNumber blknum = 0 ;
719
- BlockNumber nblocks = 0 ; /* number of blocks in source file */
720
- BlockNumber n_blocks_skipped = 0 ;
721
- int rc ;
722
- char curr_page [BLCKSZ ];
723
- bool use_pagemap ;
724
- datapagemap_iterator_t * iter = NULL ;
725
-
726
- /* headers */
727
- int hdr_num = -1 ;
728
- BackupPageHeader2 * headers = NULL ;
729
-
730
- /* stdio buffers */
731
- char * in_buf = NULL ;
732
- char * out_buf = NULL ;
733
-
734
- /* sanity */
735
- if (file -> size % BLCKSZ != 0 )
736
- elog (WARNING , "File: \"%s\", invalid file size %zu" , from_fullpath , file -> size );
737
-
738
- /*
739
- * Compute expected number of blocks in the file.
740
- * NOTE This is a normal situation, if the file size has changed
741
- * since the moment we computed it.
742
- */
743
- nblocks = file -> size /BLCKSZ ;
744
-
745
- /* set n_blocks for a file */
746
- file -> n_blocks = nblocks ;
747
-
748
- /*
749
- * Skip unchanged file only if it exists in previous backup.
750
- * This way we can correctly handle null-sized files which are
751
- * not tracked by pagemap and thus always marked as unchanged.
752
- */
753
- if ((backup_mode == BACKUP_MODE_DIFF_PAGE ||
754
- backup_mode == BACKUP_MODE_DIFF_PTRACK ) &&
755
- file -> pagemap .bitmapsize == PageBitmapIsEmpty &&
756
- file -> exists_in_prev && !file -> pagemap_isabsent )
757
- {
758
- /*
759
- * There are no changed blocks since last backup. We want to make
760
- * incremental backup, so we should exit.
761
- */
762
- file -> write_size = BYTES_INVALID ;
763
- return ;
764
- }
765
-
766
- /* reset size summary */
767
- file -> read_size = 0 ;
768
- file -> write_size = 0 ;
769
- file -> uncompressed_size = 0 ;
770
- INIT_FILE_CRC32 (true, file -> crc );
771
-
772
- /*
773
- * Read each page, verify checksum and write it to backup.
774
- * If page map is empty or file is not present in previous backup
775
- * backup all pages of the relation.
776
- *
777
- * In PTRACK 1.x there was a problem
778
- * of data files with missing _ptrack map.
779
- * Such files should be fully copied.
780
- */
781
-
782
- if (file -> pagemap .bitmapsize == PageBitmapIsEmpty ||
783
- file -> pagemap_isabsent || !file -> exists_in_prev ||
784
- !file -> pagemap .bitmap )
785
- use_pagemap = false;
786
- else
787
- use_pagemap = true;
788
-
789
- /* Remote mode */
790
- if (fio_is_remote (FIO_DB_HOST ))
791
- {
792
- char * errmsg = NULL ;
793
- BlockNumber err_blknum = 0 ;
794
-
795
- int rc = fio_send_pages (to_fullpath , from_fullpath , file ,
796
- /* send prev backup START_LSN */
797
- backup_mode == BACKUP_MODE_DIFF_DELTA &&
798
- file -> exists_in_prev ? prev_backup_start_lsn : InvalidXLogRecPtr ,
799
- calg , clevel , checksum_version ,
800
- /* send pagemap if any */
801
- use_pagemap ? & file -> pagemap : NULL ,
802
- /* variables for error reporting */
803
- & err_blknum , & errmsg , & headers );
804
-
805
- /* check for errors */
806
- if (rc == FILE_MISSING )
807
- {
808
- elog (LOG , "File \"%s\" is not found" , from_fullpath );
809
- file -> write_size = FILE_NOT_FOUND ;
810
- goto cleanup ;
811
- }
812
-
813
- else if (rc == WRITE_FAILED )
814
- elog (ERROR , "Cannot write block %u of \"%s\": %s" ,
815
- err_blknum , to_fullpath , strerror (errno ));
816
-
817
- else if (rc == PAGE_CORRUPTION )
818
- {
819
- if (errmsg )
820
- elog (ERROR , "Corruption detected in file \"%s\", block %u: %s" ,
821
- from_fullpath , err_blknum , errmsg );
822
- else
823
- elog (ERROR , "Corruption detected in file \"%s\", block %u" ,
824
- from_fullpath , err_blknum );
825
- }
826
- /* OPEN_FAILED and READ_FAILED */
827
- else if (rc == OPEN_FAILED )
828
- {
829
- if (errmsg )
830
- elog (ERROR , "%s" , errmsg );
831
- else
832
- elog (ERROR , "Failed to open for reading remote file \"%s\"" , from_fullpath );
833
- }
834
- else if (rc == READ_FAILED )
835
- {
836
- if (errmsg )
837
- elog (ERROR , "%s" , errmsg );
838
- else
839
- elog (ERROR , "Failed to read from remote file \"%s\"" , from_fullpath );
840
- }
841
-
842
- file -> read_size = rc * BLCKSZ ;
843
- pg_free (errmsg );
844
-
845
- }
846
- /* Local mode */
847
- else
848
- {
849
- uint cur_pos_out = 0 ;
850
- /* open source file for read */
851
- in = fopen (from_fullpath , PG_BINARY_R );
852
- if (in == NULL )
853
- {
854
- /*
855
- * If file is not found, this is not en error.
856
- * It could have been deleted by concurrent postgres transaction.
857
- */
858
- if (errno == ENOENT )
859
- {
860
- if (missing_ok )
861
- {
862
- elog (LOG , "File \"%s\" is not found" , from_fullpath );
863
- file -> write_size = FILE_NOT_FOUND ;
864
- goto cleanup ;
865
- }
866
- else
867
- elog (ERROR , "File \"%s\" is not found" , from_fullpath );
868
- }
869
-
870
- /* In all other cases throw an error */
871
- elog (ERROR , "Cannot open file \"%s\": %s" ,
872
- from_fullpath , strerror (errno ));
873
- }
874
-
875
- /* Enable stdio buffering for local input file,
876
- * unless the pagemap is involved, which
877
- * imply a lot of random access.
878
- */
879
-
880
- if (use_pagemap )
881
- {
882
- iter = datapagemap_iterate (& file -> pagemap );
883
- datapagemap_next (iter , & blknum ); /* set first block */
884
-
885
- setvbuf (in , NULL , _IONBF , BUFSIZ );
886
- }
887
- else
888
- {
889
- in_buf = pgut_malloc (STDIO_BUFSIZE );
890
- setvbuf (in , in_buf , _IOFBF , STDIO_BUFSIZE );
891
- }
892
-
893
- while (blknum < nblocks )
894
- {
895
- PageState page_st ;
896
- rc = prepare_page (conn_arg , file , prev_backup_start_lsn ,
897
- blknum , in , backup_mode , curr_page ,
898
- true, checksum_version ,
899
- ptrack_version_num , ptrack_schema ,
900
- from_fullpath , & page_st );
901
-
902
- if (rc == PageIsTruncated )
903
- break ;
904
-
905
- /* TODO: remove */
906
- else if (rc == SkipCurrentPage )
907
- n_blocks_skipped ++ ;
908
-
909
- else if (rc == PageIsOk )
910
- {
911
-
912
- /* open local backup file for write */
913
- if (!out )
914
- out = open_local_file_rw (to_fullpath , & out_buf , STDIO_BUFSIZE );
915
-
916
- hdr_num ++ ;
917
-
918
- if (!headers )
919
- headers = (BackupPageHeader2 * ) pgut_malloc (sizeof (BackupPageHeader2 ));
920
- else
921
- headers = (BackupPageHeader2 * ) pgut_realloc (headers , (hdr_num + 1 ) * sizeof (BackupPageHeader2 ));
922
-
923
- headers [hdr_num ].block = blknum ;
924
- headers [hdr_num ].lsn = page_st .lsn ;
925
- headers [hdr_num ].checksum = page_st .checksum ;
926
- headers [hdr_num ].pos = cur_pos_out ; /* optimize */
927
-
928
- headers [hdr_num ].compressed_size = compress_and_backup_page (file , blknum , in , out , & (file -> crc ),
929
- rc , curr_page , calg , clevel ,
930
- from_fullpath , to_fullpath );
931
-
932
- file -> n_headers = hdr_num + 1 ;
933
-
934
- cur_pos_out += headers [hdr_num ].compressed_size ;
935
- }
936
- /* TODO: handle PageIsCorrupted, currently it is done in prepare_page */
937
- else
938
- Assert (false);
939
-
940
-
941
- file -> read_size += BLCKSZ ;
942
-
943
- /* next block */
944
- if (use_pagemap )
945
- {
946
- /* exit if pagemap is exhausted */
947
- if (!datapagemap_next (iter , & blknum ))
948
- break ;
949
- }
950
- else
951
- blknum ++ ;
952
- }
953
- }
954
-
955
- pg_free (file -> pagemap .bitmap );
956
- pg_free (iter );
957
-
958
- /* refresh n_blocks for FULL and DELTA */
959
- if (backup_mode == BACKUP_MODE_FULL ||
960
- backup_mode == BACKUP_MODE_DIFF_DELTA )
961
- file -> n_blocks = file -> read_size / BLCKSZ ;
962
-
963
- /* Determine that file didn`t changed in case of incremental backup */
964
- if (backup_mode != BACKUP_MODE_FULL &&
965
- file -> exists_in_prev &&
966
- file -> write_size == 0 &&
967
- file -> n_blocks > 0 )
968
- {
969
- file -> write_size = BYTES_INVALID ;
970
- }
971
-
972
- cleanup :
973
- /* finish CRC calculation */
974
- FIN_FILE_CRC32 (true, file -> crc );
975
-
976
- /* close local input file */
977
- if (in && fclose (in ))
978
- elog (ERROR , "Cannot close the source file \"%s\": %s" ,
979
- to_fullpath , strerror (errno ));
980
-
981
- /* close local output file */
982
- if (out && fclose (out ))
983
- elog (ERROR , "Cannot close the backup file \"%s\": %s" ,
984
- to_fullpath , strerror (errno ));
985
-
986
- pg_free (in_buf );
987
- pg_free (out_buf );
988
-
989
- /* handle hdr */
990
- /* TODO: move in separate function */
991
- if (headers && file -> n_headers > 0 )
992
- {
993
- size_t hdr_size ;
994
- char to_fullpath_hdr [MAXPGPATH ];
995
-
996
- snprintf (to_fullpath_hdr , MAXPGPATH , "%s_hdr" , to_fullpath );
997
-
998
- out = fopen (to_fullpath_hdr , PG_BINARY_W );
999
- if (out == NULL )
1000
- elog (ERROR , "Cannot open header file \"%s\": %s" ,
1001
- to_fullpath , strerror (errno ));
1002
-
1003
- /* update file permission */
1004
- if (chmod (to_fullpath_hdr , FILE_PERMISSION ) == -1 )
1005
- elog (ERROR , "Cannot change mode of \"%s\": %s" , to_fullpath ,
1006
- strerror (errno ));
1007
-
1008
- hdr_size = file -> n_headers * sizeof (BackupPageHeader2 );
1009
-
1010
- // elog(INFO, "Size: %lu, aligh: %lu", hdr_size, MAXALIGN(hdr_size));
1011
- // elog(INFO, "checksum: %u, lsn: %lu", headers[file->n_headers-1].checksum, headers[file->n_headers-1].lsn);
1012
- // elog(INFO, "POS: %u", headers[file->n_headers-1].pos);
1013
- // elog(INFO, "blknum: %u", headers[file->n_headers-1].block);
1014
- // elog(INFO, "size: %u", headers[file->n_headers-1].compressed_size);
1015
-
1016
- if (fwrite (headers , 1 , hdr_size , out ) != hdr_size )
1017
- elog (ERROR , "Cannot write to file \"%s\": %s" , to_fullpath_hdr , strerror (errno ));
1018
-
1019
- if (fclose (out ))
1020
- elog (ERROR , "Cannot close file \"%s\": %s" , to_fullpath_hdr , strerror (errno ));
1021
-
1022
- /* TODO: fsync */
1023
-
1024
- // elog(INFO, "n_headers: %u", file->n_headers);
1025
- }
1026
-
1027
- pg_free (headers );
1028
- }
1029
-
1030
701
/*
1031
702
* Backup non data file
1032
703
* We do not apply compression to this file.
0 commit comments