Skip to content

Commit 4a736a1

Browse files
committed
pgstat: Use correct lock level in pgstat_drop_all_entries().
Previously we didn't, which lead to an assertion failure when resetting partially loaded statistics. This was encountered on the buildfarm, for as-of-yet unknown reasons. Ttighten up a validity check when reading the stats file, verifying 'E' signals the end of the file (rather than just stopping reading). That's then used in a test appending to the stats file that crashed before the fix in pgstat_drop_all_entries(). Reported by buildfarm animals mylodon and kestrel, via Tom Lane. Discussion: https://postgr.es/m/1656446.1650043715@sss.pgh.pa.us
1 parent 9f4f0a0 commit 4a736a1

File tree

3 files changed

+33
-3
lines changed

3 files changed

+33
-3
lines changed

src/backend/utils/activity/pgstat.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1583,6 +1583,10 @@ pgstat_read_statsfile(void)
15831583
break;
15841584
}
15851585
case 'E':
1586+
/* check that 'E' actually signals end of file */
1587+
if (fgetc(fpin) != EOF)
1588+
goto error;
1589+
15861590
goto done;
15871591

15881592
default:

src/backend/utils/activity/pgstat_shmem.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,7 @@ pgstat_drop_all_entries(void)
878878
PgStatShared_HashEntry *ps;
879879
uint64 not_freed_count = 0;
880880

881-
dshash_seq_init(&hstat, pgStatLocal.shared_hash, false);
881+
dshash_seq_init(&hstat, pgStatLocal.shared_hash, true);
882882
while ((ps = dshash_seq_next(&hstat)) != NULL)
883883
{
884884
if (ps->dropped)

src/test/recovery/t/029_stats_restart.pl

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,23 @@
113113
$node->start;
114114

115115
# no stats present due to invalid stats file
116-
$sect = "invalid";
116+
$sect = "invalid_overwrite";
117+
is(have_stats('database', $dboid, 0), 'f', "$sect: db stats do not exist");
118+
is(have_stats('function', $dboid, $funcoid),
119+
'f', "$sect: function stats do not exist");
120+
is(have_stats('relation', $dboid, $tableoid),
121+
'f', "$sect: relation stats do not exist");
122+
123+
124+
## check invalid stats file starting with valid contents, but followed by
125+
## invalid content is handled.
126+
127+
trigger_funcrel_stat();
128+
$node->stop;
129+
append_file($og_stats, "XYZ");
130+
$node->start;
131+
132+
$sect = "invalid_append";
117133
is(have_stats('database', $dboid, 0), 'f', "$sect: db stats do not exist");
118134
is(have_stats('function', $dboid, $funcoid),
119135
'f', "$sect: function stats do not exist");
@@ -285,7 +301,17 @@ sub overwrite_file
285301
{
286302
my ($filename, $str) = @_;
287303
open my $fh, ">", $filename
288-
or die "could not write \"$filename\": $!";
304+
or die "could not overwrite \"$filename\": $!";
305+
print $fh $str;
306+
close $fh;
307+
return;
308+
}
309+
310+
sub append_file
311+
{
312+
my ($filename, $str) = @_;
313+
open my $fh, ">>", $filename
314+
or die "could not append to \"$filename\": $!";
289315
print $fh $str;
290316
close $fh;
291317
return;

0 commit comments

Comments
 (0)