Skip to content

Commit 33b7366

Browse files
df7cbmartinmarques
authored andcommitted
Query all sequences per DB in parallel for action=sequence
action=sequence used to open a new session for every sequence checked, which could be very slow. Fix by creating a single SQL statement using UNION ALL to query all sequences at once.
1 parent d7ed399 commit 33b7366

File tree

3 files changed

+28
-9
lines changed

3 files changed

+28
-9
lines changed

check_postgres.pl

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7325,23 +7325,26 @@ sub check_sequence {
73257325
my %seqinfo;
73267326
my %seqperf;
73277327
my $multidb = @{$info->{db}} > 1 ? "$db->{dbname}." : '';
7328-
for my $r (@{$db->{slurp}}) {
7328+
my @seq_sql;
7329+
for my $r (@{$db->{slurp}}) { # for each sequence, create SQL command to inspect it
73297330
my ($schema, $seq, $seqname, $typename) = @$r{qw/ nspname seqname safename typname /};
73307331
next if skip_item($seq);
73317332
my $maxValue = $typename eq 'int2' ? $MAXINT2 : $typename eq 'int4' ? $MAXINT4 : $MAXINT8;
7332-
$SQL = qq{
7333-
SELECT last_value, slots, used, ROUND(used/slots*100) AS percent,
7333+
my $seqname_l = $seqname;
7334+
$seqname_l =~ s/'/''/g; # SQL literal quoting (name is already identifier-quoted)
7335+
push @seq_sql, qq{
7336+
SELECT '$seqname_l' AS seqname, last_value, slots, used, ROUND(used/slots*100) AS percent,
73347337
CASE WHEN slots < used THEN 0 ELSE slots - used END AS numleft
73357338
FROM (
73367339
SELECT last_value,
73377340
CEIL((LEAST(max_value, $maxValue)-min_value::numeric+1)/increment_by::NUMERIC) AS slots,
73387341
CEIL((last_value-min_value::numeric+1)/increment_by::NUMERIC) AS used
73397342
FROM $seqname) foo
73407343
};
7341-
7342-
my $seqinfo = run_command($SQL, { target => $db });
7343-
my $r2 = $seqinfo->{db}[0]{slurp}[0];
7344-
my ($last, $slots, $used, $percent, $left) = @$r2{qw/ last_value slots used percent numleft / };
7344+
}
7345+
my $seqinfo = run_command(join("\nUNION ALL\n", @seq_sql), { target => $db }); # execute all SQL commands at once
7346+
for my $r2 (@{$seqinfo->{db}[0]{slurp}}) { # now look at all results
7347+
my ($seqname, $last, $slots, $used, $percent, $left) = @$r2{qw/ seqname last_value slots used percent numleft / };
73457348
if (! defined $last) {
73467349
ndie msg('seq-die', $seqname);
73477350
}
@@ -9876,6 +9879,8 @@ =head1 HISTORY
98769879
98779880
Declare POD encoding to be utf8. (Christoph Berg)
98789881
9882+
Query all sequences per DB in parallel for action=sequence. (Christoph Berg)
9883+
98799884
=item B<Version 2.21.0> September 24, 2013
98809885
98819886
Fix issue with SQL steps in check_pgagent_jobs for sql steps which perform deletes

t/02_sequence.t

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use 5.006;
66
use strict;
77
use warnings;
88
use Data::Dumper;
9-
use Test::More tests => 10;
9+
use Test::More tests => 12;
1010
use lib 't','.';
1111
use CP_Testing;
1212

@@ -45,6 +45,7 @@ if ($ver < 80100) {
4545
my $seqname = 'cp_test_sequence';
4646
$cp->drop_sequence_if_exists($seqname);
4747
$cp->drop_sequence_if_exists("${seqname}2");
48+
$cp->drop_sequence_if_exists("${seqname}'\"evil");
4849

4950
$t=qq{$S works when no sequences exist};
5051
like ($cp->run(''), qr{OK:.+No sequences found}, $t);
@@ -83,4 +84,16 @@ like ($cp->run('--critical=22%'), qr{CRITICAL:.+public.cp_test_sequence=33% \(ca
8384
$t=qq{$S returns correct information with MRTG output};
8485
is ($cp->run('--critical=22% --output=mrtg'), "33\n0\n\npublic.cp_test_sequence\n", $t);
8586

87+
# create second sequence
88+
$dbh->do("CREATE SEQUENCE ${seqname}2");
89+
$dbh->commit();
90+
$t=qq{$S returns correct information for two sequences};
91+
like ($cp->run(''), qr{OK:.+public.cp_test_sequence=33% .* \| .*${seqname}=33%.*${seqname}2=0%}, $t);
92+
93+
# test SQL quoting
94+
$dbh->do(qq{CREATE SEQUENCE "${seqname}'""evil"});
95+
$dbh->commit();
96+
$t=qq{$S handles SQL quoting};
97+
like ($cp->run(''), qr{OK:.+'public."${seqname}''""evil"'}, $t); # extra " and ' because name is both identifier+literal quoted
98+
8699
exit;

t/CP_Testing.pm

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,8 @@ sub drop_sequence_if_exists {
700700
$SQL = q{SELECT count(*) FROM pg_class WHERE relkind = 'S' AND relname = } . $dbh->quote($name);
701701
my $count = $dbh->selectall_arrayref($SQL)->[0][0];
702702
if ($count) {
703-
$dbh->do("DROP SEQUENCE $name");
703+
$name =~ s/"/""/g;
704+
$dbh->do("DROP SEQUENCE \"$name\"");
704705
$dbh->commit();
705706
}
706707
return;

0 commit comments

Comments
 (0)