Skip to content

Commit a34152b

Browse files
committed
Try get page again when checksum is fail.
1 parent 356ebd3 commit a34152b

File tree

1 file changed

+85
-36
lines changed

1 file changed

+85
-36
lines changed

data.c

Lines changed: 85 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ backup_data_file(const char *from_root, const char *to_root,
112112
/* confirm server version */
113113
check_server_version();
114114

115+
115116
/*
116117
* Read each page and write the page excluding hole. If it has been
117118
* 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,
129130
XLogRecPtr page_lsn;
130131
int upper_offset;
131132
int upper_length;
133+
int try_checksum = 100;
132134

133135
header.block = blknum;
134136

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)
141138
{
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+
}
147172
}
148173

149-
file->read_size += read_len;
150-
151174
/* if the page has not been modified since last backup, skip it */
152175
if (lsn && !XLogRecPtrIsInvalid(page_lsn) && page_lsn < *lsn)
153176
continue;
154177

178+
file->read_size += read_len;
179+
180+
155181
upper_offset = header.hole_offset + header.hole_length;
156182
upper_length = BLCKSZ - upper_offset;
157183

@@ -186,32 +212,55 @@ backup_data_file(const char *from_root, const char *to_root,
186212
int upper_offset;
187213
int upper_length;
188214
int ret;
215+
int try_checksum = 100;
189216

190217
offset = blknum * BLCKSZ;
191-
if (offset > 0)
218+
while(try_checksum)
192219
{
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 unsigned int) 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 unsigned int) 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+
}
215264
}
216265

217266
/* if the page has not been modified since last backup, skip it */

0 commit comments

Comments
 (0)