@@ -112,6 +112,7 @@ backup_data_file(const char *from_root, const char *to_root,
112
112
/* confirm server version */
113
113
check_server_version ();
114
114
115
+
115
116
/*
116
117
* Read each page and write the page excluding hole. If it has been
117
118
* determined that the page can be copied safely, but no page map
@@ -129,29 +130,54 @@ backup_data_file(const char *from_root, const char *to_root,
129
130
XLogRecPtr page_lsn ;
130
131
int upper_offset ;
131
132
int upper_length ;
133
+ int try_checksum = 100 ;
132
134
133
135
header .block = blknum ;
134
136
135
- /*
136
- * If an invalid data page was found, fallback to simple copy to ensure
137
- * all pages in the file don't have BackupPageHeader.
138
- */
139
- if (!parse_page (& page ,& page_lsn ,
140
- & header .hole_offset ,& header .hole_length ))
137
+ while (try_checksum )
141
138
{
142
- elog (LOG ,"%s fall back to simple copy" ,file -> path );
143
- fclose (in );
144
- fclose (out );
145
- file -> is_datafile = false;
146
- return copy_file (from_root ,to_root ,file );
139
+ /*
140
+ * If an invalid data page was found, fallback to simple copy to ensure
141
+ * all pages in the file don't have BackupPageHeader.
142
+ */
143
+ if (!parse_page (& page ,& page_lsn ,
144
+ & header .hole_offset ,& header .hole_length ))
145
+ {
146
+ elog (LOG ,"%s fall back to simple copy" ,file -> path );
147
+ fclose (in );
148
+ fclose (out );
149
+ file -> is_datafile = false;
150
+ return copy_file (from_root ,to_root ,file );
151
+ }
152
+
153
+ /* if the page has not been modified since last backup, skip it */
154
+ if (lsn && !XLogRecPtrIsInvalid (page_lsn )&& page_lsn < * lsn )
155
+ break ;
156
+
157
+ try_checksum -- ;
158
+ if (current .checksum_version &&
159
+ pg_checksum_page (page .data ,header .block )!= ((PageHeader )page .data )-> pd_checksum )
160
+ {
161
+ if (try_checksum )
162
+ {
163
+ elog (WARNING ,"File: %s blknum %u have wrong checksum, try again" ,file -> path ,blknum );
164
+ fseek (in ,- sizeof (page ),SEEK_CUR );
165
+ fread (& page ,1 ,sizeof (page ),in );
166
+ }
167
+ else
168
+ elog (ERROR ,"File: %s blknum %u have wrong checksum." ,file -> path ,blknum );
169
+ }else {
170
+ try_checksum = 0 ;
171
+ }
147
172
}
148
173
149
- file -> read_size += read_len ;
150
-
151
174
/* if the page has not been modified since last backup, skip it */
152
175
if (lsn && !XLogRecPtrIsInvalid (page_lsn )&& page_lsn < * lsn )
153
176
continue ;
154
177
178
+ file -> read_size += read_len ;
179
+
180
+
155
181
upper_offset = header .hole_offset + header .hole_length ;
156
182
upper_length = BLCKSZ - upper_offset ;
157
183
@@ -186,32 +212,55 @@ backup_data_file(const char *from_root, const char *to_root,
186
212
int upper_offset ;
187
213
int upper_length ;
188
214
int ret ;
215
+ int try_checksum = 100 ;
189
216
190
217
offset = blknum * BLCKSZ ;
191
- if ( offset > 0 )
218
+ while ( try_checksum )
192
219
{
193
- ret = fseek (in ,offset ,SEEK_SET );
194
- if (ret != 0 )
195
- elog (ERROR ,
196
- "Can't seek in file offset: %llu ret:%i\n" ,
197
- (long long unsignedint )offset ,ret );
198
- }
199
- read_len = fread (& page ,1 ,sizeof (page ),in );
200
-
201
- header .block = blknum ;
202
-
203
- /*
204
- * If an invalid data page was found, fallback to simple copy to ensure
205
- * all pages in the file don't have BackupPageHeader.
206
- */
207
- if (!parse_page (& page ,& page_lsn ,
208
- & header .hole_offset ,& header .hole_length ))
209
- {
210
- elog (LOG ,"%s fall back to simple copy" ,file -> path );
211
- fclose (in );
212
- fclose (out );
213
- file -> is_datafile = false;
214
- return copy_file (from_root ,to_root ,file );
220
+ if (offset > 0 )
221
+ {
222
+ ret = fseek (in ,offset ,SEEK_SET );
223
+ if (ret != 0 )
224
+ elog (ERROR ,
225
+ "Can't seek in file offset: %llu ret:%i\n" ,
226
+ (long long unsignedint )offset ,ret );
227
+ }
228
+ read_len = fread (& page ,1 ,sizeof (page ),in );
229
+
230
+ header .block = blknum ;
231
+
232
+ /*
233
+ * If an invalid data page was found, fallback to simple copy to ensure
234
+ * all pages in the file don't have BackupPageHeader.
235
+ */
236
+ if (!parse_page (& page ,& page_lsn ,
237
+ & header .hole_offset ,& header .hole_length ))
238
+ {
239
+ elog (LOG ,"%s fall back to simple copy" ,file -> path );
240
+ fclose (in );
241
+ fclose (out );
242
+ file -> is_datafile = false;
243
+ return copy_file (from_root ,to_root ,file );
244
+ }
245
+
246
+ /* if the page has not been modified since last backup, skip it */
247
+ if (lsn && !XLogRecPtrIsInvalid (page_lsn )&& page_lsn < * lsn )
248
+ break ;
249
+
250
+ try_checksum -- ;
251
+
252
+ if (current .checksum_version &&
253
+ pg_checksum_page (page .data ,header .block )!= ((PageHeader )page .data )-> pd_checksum )
254
+ {
255
+ if (try_checksum )
256
+ elog (WARNING ,"File: %s blknum %u have wrong checksum, try again" ,file -> path ,blknum );
257
+ else
258
+ elog (ERROR ,"File: %s blknum %u have wrong checksum." ,file -> path ,blknum );
259
+ }
260
+ else
261
+ {
262
+ try_checksum = 0 ;
263
+ }
215
264
}
216
265
217
266
/* if the page has not been modified since last backup, skip it */