Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4731d84

Browse files
committed
pg_controldata: Prevent division-by-zero errors
If the control file is corrupted and specifies the WAL segment sizeto be 0 bytes, calculating the latest checkpoint's REDO WAL filewill fail with a division-by-zero error. Show it as "???" instead.Also reword the warning message a bit and send it to stdout, like theother pre-existing warning messages.Add some tests for dealing with a corrupted pg_control file.Author: Nathan Bossart <bossartn@amazon.com>, tests by me
1 parent5616300 commit4731d84

File tree

2 files changed

+38
-9
lines changed

2 files changed

+38
-9
lines changed

‎src/bin/pg_controldata/pg_controldata.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ main(int argc, char *argv[])
9595
charmock_auth_nonce_str[MOCK_AUTH_NONCE_LEN*2+1];
9696
constchar*strftime_fmt="%c";
9797
constchar*progname;
98-
XLogSegNosegno;
9998
charxlogfilename[MAXFNAMELEN];
10099
intc;
101100
inti;
@@ -169,10 +168,11 @@ main(int argc, char *argv[])
169168
WalSegSz=ControlFile->xlog_seg_size;
170169

171170
if (!IsValidWalSegSize(WalSegSz))
172-
fprintf(stderr,
173-
_("WARNING: WAL segment size specified, %d bytes, is not a power of two between 1MB and 1GB.\n"
174-
"The file is corrupt and the results below are untrustworthy.\n"),
175-
WalSegSz);
171+
printf(_("WARNING: invalid WAL segment size\n"
172+
"The WAL segment size stored in the file, %d bytes, is not a power of two\n"
173+
"between 1 MB and 1 GB. The file is corrupt and the results below are\n"
174+
"untrustworthy.\n\n"),
175+
WalSegSz);
176176

177177
/*
178178
* This slightly-chintzy coding will work as long as the control file
@@ -193,10 +193,20 @@ main(int argc, char *argv[])
193193
/*
194194
* Calculate name of the WAL file containing the latest checkpoint's REDO
195195
* start point.
196+
*
197+
* A corrupted control file could report a WAL segment size of 0, and to
198+
* guard against division by zero, we need to treat that specially.
196199
*/
197-
XLByteToSeg(ControlFile->checkPointCopy.redo,segno,WalSegSz);
198-
XLogFileName(xlogfilename,ControlFile->checkPointCopy.ThisTimeLineID,
199-
segno,WalSegSz);
200+
if (WalSegSz!=0)
201+
{
202+
XLogSegNosegno;
203+
204+
XLByteToSeg(ControlFile->checkPointCopy.redo,segno,WalSegSz);
205+
XLogFileName(xlogfilename,ControlFile->checkPointCopy.ThisTimeLineID,
206+
segno,WalSegSz);
207+
}
208+
else
209+
strcpy(xlogfilename,_("???"));
200210

201211
/*
202212
* Format system_identifier and mock_authentication_nonce separately to

‎src/bin/pg_controldata/t/001_pg_controldata.pl

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
use warnings;
33
use PostgresNode;
44
use TestLib;
5-
use Test::Moretests=>13;
5+
use Test::Moretests=>17;
66

77
program_help_ok('pg_controldata');
88
program_version_ok('pg_controldata');
@@ -16,3 +16,22 @@
1616

1717
command_like(['pg_controldata',$node->data_dir ],
1818
qr/checkpoint/,'pg_controldata produces output');
19+
20+
21+
# check with a corrupted pg_control
22+
23+
my$pg_control =$node->data_dir .'/global/pg_control';
24+
my$size = (stat($pg_control))[7];
25+
26+
openmy$fh,'>',$pg_controlor BAIL_OUT($!);
27+
binmode$fh;
28+
# fill file with zeros
29+
print$fhpack("x[$size]");
30+
close$fh;
31+
32+
command_checks_all(['pg_controldata',$node->data_dir ],
33+
0,
34+
[qr/WARNING: Calculated CRC checksum does not match value stored in file/,
35+
qr/WARNING: invalid WAL segment size/ ],
36+
[qr/^$/ ],
37+
'pg_controldata with corrupted pg_control');

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp