22
22
#include <common/pg_lzcompress.h>
23
23
#include <zlib.h>
24
24
25
+ /* Implementation of zlib compression method */
25
26
static size_t zlib_compress (void * dst , size_t dst_size , void const * src , size_t src_size )
26
27
{
27
28
uLongf compressed_size = dst_size ;
28
29
int rc = compress2 (dst , & compressed_size , src , src_size , compress_level );
29
30
return rc == Z_OK ? compressed_size : rc ;
30
31
}
31
32
33
+ /* Implementation of zlib compression method */
32
34
static size_t zlib_decompress (void * dst , size_t dst_size , void const * src , size_t src_size )
33
35
{
34
36
uLongf dest_len = dst_size ;
35
37
int rc = uncompress (dst , & dest_len , src , src_size );
36
38
return rc == Z_OK ? dest_len : rc ;
37
39
}
38
40
41
+ /*
42
+ * Compresses source into dest using algorithm. Returns the number of bytes
43
+ * written in the destination buffer, or -1 if compression fails.
44
+ */
39
45
static size_t
40
46
do_compress (void * dst , size_t dst_size , void const * src , size_t src_size , CompressAlg alg )
41
47
{
@@ -53,6 +59,10 @@ do_compress(void* dst, size_t dst_size, void const* src, size_t src_size, Compre
53
59
return -1 ;
54
60
}
55
61
62
+ /*
63
+ * Decompresses source into dest using algorithm. Returns the number of bytes
64
+ * decompressed in the destination buffer, or -1 if decompression fails.
65
+ */
56
66
static size_t
57
67
do_decompress (void * dst , size_t dst_size , void const * src , size_t src_size , CompressAlg alg )
58
68
{
@@ -70,8 +80,10 @@ do_decompress(void* dst, size_t dst_size, void const* src, size_t src_size, Comp
70
80
return -1 ;
71
81
}
72
82
73
-
74
-
83
+ /*
84
+ * When copying datafiles to backup we validate and compress them block
85
+ * by block. Thus special header is required for each data block.
86
+ */
75
87
typedef struct BackupPageHeader
76
88
{
77
89
BlockNumber block ; /* block number */
@@ -125,6 +137,11 @@ backup_data_page(pgFile *file, XLogRecPtr prev_backup_start_lsn,
125
137
header .block = blknum ;
126
138
offset = blknum * BLCKSZ ;
127
139
140
+ /*
141
+ * Read the page and verify its header and checksum.
142
+ * Under high write load it's possible that we've read partly
143
+ * flushed page, so try several times befor throwing an error.
144
+ */
128
145
while (try_checksum -- )
129
146
{
130
147
if (fseek (in , offset , SEEK_SET ) != 0 )
@@ -223,12 +240,14 @@ backup_data_page(pgFile *file, XLogRecPtr prev_backup_start_lsn,
223
240
Assert (header .compressed_size <= BLCKSZ );
224
241
write_buffer_size = sizeof (header );
225
242
243
+ /* The page was successfully compressed */
226
244
if (header .compressed_size > 0 )
227
245
{
228
246
memcpy (write_buffer , & header , sizeof (header ));
229
247
memcpy (write_buffer + sizeof (header ), compressed_page .data , header .compressed_size );
230
248
write_buffer_size += MAXALIGN (header .compressed_size );
231
249
}
250
+ /* The page compression failed. Write it as is. */
232
251
else
233
252
{
234
253
header .compressed_size = BLCKSZ ;
@@ -324,8 +343,7 @@ backup_data_file(const char *from_root, const char *to_root,
324
343
325
344
/*
326
345
* Read each page, verify checksum and write it to backup.
327
- * If page map is not empty we scan only changed blocks, otherwise
328
- * backup all pages of the relation.
346
+ * If page map is empty backup all pages of the relation.
329
347
*/
330
348
if (file -> pagemap .bitmapsize == 0 )
331
349
{
@@ -336,6 +354,7 @@ backup_data_file(const char *from_root, const char *to_root,
336
354
n_blocks_read ++ ;
337
355
}
338
356
}
357
+ /* If page map is not empty we scan only changed blocks, */
339
358
else
340
359
{
341
360
datapagemap_iterator_t * iter ;
@@ -371,7 +390,7 @@ backup_data_file(const char *from_root, const char *to_root,
371
390
FIN_CRC32C (file -> crc );
372
391
373
392
/*
374
- * If we have pagemap then file can't be a zero size.
393
+ * If we have pagemap then file in the backup can't be a zero size.
375
394
* Otherwise, we will clear the last file.
376
395
*/
377
396
if (n_blocks_read != 0 && n_blocks_read == n_blocks_skipped )
@@ -411,7 +430,7 @@ restore_data_file(const char *from_root,
411
430
412
431
/*
413
432
* Open backup file for write. We use "r+" at first to overwrite only
414
- * modified pages for differential restore. If the file is not exists ,
433
+ * modified pages for differential restore. If the file does not exist ,
415
434
* re-open it with "w" to create an empty file.
416
435
*/
417
436
join_path_components (to_path , to_root , file -> path + strlen (from_root ) + 1 );
@@ -745,136 +764,6 @@ copy_wal_file(const char *from_path, const char *to_path)
745
764
fclose (in );
746
765
}
747
766
748
- /*
749
- * Save part of the file into backup.
750
- * skip_size - size of the file in previous backup. We can skip it
751
- * and copy just remaining part of the file
752
- */
753
- bool
754
- copy_file_partly (const char * from_root , const char * to_root ,
755
- pgFile * file , size_t skip_size )
756
- {
757
- char to_path [MAXPGPATH ];
758
- FILE * in ;
759
- FILE * out ;
760
- size_t read_len = 0 ;
761
- int errno_tmp ;
762
- struct stat st ;
763
- char buf [BLCKSZ ];
764
-
765
- /* reset size summary */
766
- file -> read_size = 0 ;
767
- file -> write_size = 0 ;
768
-
769
- /* open backup mode file for read */
770
- in = fopen (file -> path , "r" );
771
- if (in == NULL )
772
- {
773
- /* maybe deleted, it's not error */
774
- if (errno == ENOENT )
775
- return false;
776
-
777
- elog (ERROR , "cannot open source file \"%s\": %s" , file -> path ,
778
- strerror (errno ));
779
- }
780
-
781
- /* open backup file for write */
782
- join_path_components (to_path , to_root , file -> path + strlen (from_root ) + 1 );
783
-
784
- out = fopen (to_path , "w" );
785
- if (out == NULL )
786
- {
787
- int errno_tmp = errno ;
788
- fclose (in );
789
- elog (ERROR , "cannot open destination file \"%s\": %s" ,
790
- to_path , strerror (errno_tmp ));
791
- }
792
-
793
- /* stat source file to change mode of destination file */
794
- if (fstat (fileno (in ), & st ) == -1 )
795
- {
796
- fclose (in );
797
- fclose (out );
798
- elog (ERROR , "cannot stat \"%s\": %s" , file -> path ,
799
- strerror (errno ));
800
- }
801
-
802
- if (fseek (in , skip_size , SEEK_SET ) < 0 )
803
- elog (ERROR , "cannot seek %lu of \"%s\": %s" ,
804
- skip_size , file -> path , strerror (errno ));
805
-
806
- /*
807
- * copy content
808
- * NOTE: Now CRC is not computed for compressed files now.
809
- */
810
- for (;;)
811
- {
812
- if ((read_len = fread (buf , 1 , sizeof (buf ), in )) != sizeof (buf ))
813
- break ;
814
-
815
- if (fwrite (buf , 1 , read_len , out ) != read_len )
816
- {
817
- errno_tmp = errno ;
818
- /* oops */
819
- fclose (in );
820
- fclose (out );
821
- elog (ERROR , "cannot write to \"%s\": %s" , to_path ,
822
- strerror (errno_tmp ));
823
- }
824
-
825
- file -> write_size += sizeof (buf );
826
- file -> read_size += sizeof (buf );
827
- }
828
-
829
- errno_tmp = errno ;
830
- if (!feof (in ))
831
- {
832
- fclose (in );
833
- fclose (out );
834
- elog (ERROR , "cannot read backup mode file \"%s\": %s" ,
835
- file -> path , strerror (errno_tmp ));
836
- }
837
-
838
- /* copy odd part. */
839
- if (read_len > 0 )
840
- {
841
- if (fwrite (buf , 1 , read_len , out ) != read_len )
842
- {
843
- errno_tmp = errno ;
844
- /* oops */
845
- fclose (in );
846
- fclose (out );
847
- elog (ERROR , "cannot write to \"%s\": %s" , to_path ,
848
- strerror (errno_tmp ));
849
- }
850
-
851
- file -> write_size += read_len ;
852
- file -> read_size += read_len ;
853
- }
854
-
855
- /* update file permission */
856
- if (chmod (to_path , st .st_mode ) == -1 )
857
- {
858
- errno_tmp = errno ;
859
- fclose (in );
860
- fclose (out );
861
- elog (ERROR , "cannot change mode of \"%s\": %s" , to_path ,
862
- strerror (errno_tmp ));
863
- }
864
-
865
- /* add meta information needed for recovery */
866
- file -> is_partial_copy = true;
867
-
868
- if (fflush (out ) != 0 ||
869
- fsync (fileno (out )) != 0 ||
870
- fclose (out ))
871
- elog (ERROR , "cannot write \"%s\": %s" , to_path , strerror (errno ));
872
- fclose (in );
873
-
874
- return true;
875
- }
876
-
877
-
878
767
/*
879
768
* Calculate checksum of various files which are not copied from PGDATA,
880
769
* but created in process of backup, such as stream XLOG files,
0 commit comments