@@ -540,7 +540,7 @@ compress_and_backup_page(pgFile *file, BlockNumber blknum,
540540 * backup with special header.
541541 */
542542void
543- backup_data_file_new (ConnectionArgs * conn_arg , pgFile * file ,
543+ backup_data_file (ConnectionArgs * conn_arg , pgFile * file ,
544544 const char * from_fullpath , const char * to_fullpath ,
545545 XLogRecPtr prev_backup_start_lsn , BackupMode backup_mode ,
546546 CompressAlg calg , int clevel , uint32 checksum_version ,
@@ -698,335 +698,6 @@ backup_data_file_new(ConnectionArgs* conn_arg, pgFile *file,
698698 pg_free (headers );
699699}
700700
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-
1030701/*
1031702 * Backup non data file
1032703 * We do not apply compression to this file.
0 commit comments