@@ -202,6 +202,9 @@ package check_postgres;
202
202
' opt-psql-nofind' => q{ Could not find a suitable psql executable} ,
203
203
' opt-psql-nover' => q{ Could not determine psql version} ,
204
204
' opt-psql-restrict' => q{ Cannot use the --PGBINDIR or --PSQL option when NO_PSQL_OPTION is on} ,
205
+ ' partman-premake-ok' => q{ All premade partitions are present} ,
206
+ ' partman-conf-tbl' => q{ misconfigured in partman.part_config} ,
207
+ ' partman-conf-mis' => q{ missing table in partman.part_config} ,
205
208
' pgagent-jobs-ok' => q{ No failed jobs} ,
206
209
' pgbouncer-pool' => q{ Pool=$1 $2=$3} ,
207
210
' pgb-backends-mrtg' => q{ DB=$1 Max connections=$2} ,
@@ -1899,6 +1902,7 @@ package check_postgres;
1899
1902
new_version_cp => [0, ' Checks if a newer version of check_postgres.pl is available.' ],
1900
1903
new_version_pg => [0, ' Checks if a newer version of Postgres is available.' ],
1901
1904
new_version_tnm => [0, ' Checks if a newer version of tail_n_mail is available.' ],
1905
+ partman_premake => [1, ' Checks if premake partitions are present.' ],
1902
1906
pgb_pool_cl_active => [1, ' Check the number of active clients in each pgbouncer pool.' ],
1903
1907
pgb_pool_cl_waiting => [1, ' Check the number of waiting clients in each pgbouncer pool.' ],
1904
1908
pgb_pool_sv_active => [1, ' Check the number of active server connections in each pgbouncer pool.' ],
@@ -2735,6 +2739,9 @@ sub finishup {
2735
2739
# # Make sure Slony is behaving
2736
2740
check_slony_status() if $action eq ' slony_status' ;
2737
2741
2742
+ # # Make sure Partman premake is working
2743
+ check_partman_premake() if $action eq ' partman_premake' ;
2744
+
2738
2745
# # Verify that the pgbouncer settings are what we think they should be
2739
2746
check_pgbouncer_checksum() if $action eq ' pgbouncer_checksum' ;
2740
2747
@@ -6525,6 +6532,171 @@ sub check_pgagent_jobs {
6525
6532
return ;
6526
6533
}
6527
6534
6535
+ sub check_partman_premake {
6536
+
6537
+ # # Checks if all premade partitions are present
6538
+ # # Monthly and daily interval only
6539
+ # # Supports: Nagios
6540
+
6541
+ my $msg = msg(' partman-premake-ok' );
6542
+ my $found = 0;
6543
+ my ($warning , $critical ) = validate_range
6544
+ ({
6545
+ type => ' integer' , # in days
6546
+ default_warning => ' 1' ,
6547
+ default_critical => ' 3' ,
6548
+ });
6549
+
6550
+ # check missing Config for range partitioned tables
6551
+
6552
+ my $SQL = q{
6553
+ SELECT
6554
+ current_database() AS database,
6555
+ c.relnamespace::regnamespace || '.' || c.relname AS parent_table
6556
+ FROM
6557
+ pg_class c
6558
+ JOIN pg_partitioned_table t ON t.partrelid = c.oid
6559
+ WHERE
6560
+ c.relkind = 'p'
6561
+ AND t.partstrat = 'r'
6562
+ AND NOT EXISTS (
6563
+ SELECT
6564
+ 1
6565
+ FROM
6566
+ partman.part_config
6567
+ WHERE
6568
+ parent_table = c.relnamespace::regnamespace || '.' || c.relname);
6569
+ } ;
6570
+
6571
+ my $info = run_command($SQL , {regex => qr [\w +] , emptyok => 1 } );
6572
+ my (@crit ,@warn ,@ok );
6573
+
6574
+ for $db (@{$info -> {db }}) {
6575
+ my ($maxage ,$maxdb ) = (0,' ' ); # # used by MRTG only
6576
+ ROW: for my $r (@{$db -> {slurp }}) {
6577
+ my ($dbname ,$parent_table ) = ($r -> {database },$r -> {parent_table });
6578
+ $found = 1 if ! $found ;
6579
+ next ROW if skip_item($dbname );
6580
+ $found = 2;
6581
+
6582
+ $msg = " $dbname =$parent_table " . msg(' partman-conf-mis' );
6583
+ push @crit => $msg ;
6584
+ };
6585
+ };
6586
+
6587
+ # check Config Errors
6588
+
6589
+ $SQL = q{
6590
+ SELECT
6591
+ current_database() as database,
6592
+ parent_table
6593
+ FROM (
6594
+ SELECT
6595
+ parent_table,
6596
+ retention,
6597
+ partition_interval,
6598
+ EXTRACT(EPOCH FROM retention::interval) / EXTRACT(EPOCH FROM partition_interval::interval) AS configured_partitions
6599
+ FROM
6600
+ partman.part_config) p
6601
+ WHERE
6602
+ configured_partitions < 1;
6603
+ } ;
6604
+
6605
+ $info = run_command($SQL , {regex => qr [\w +] , emptyok => 1 } );
6606
+
6607
+ for $db (@{$info -> {db }}) {
6608
+ my ($maxage ,$maxdb ) = (0,' ' ); # # used by MRTG only
6609
+ ROW: for my $r (@{$db -> {slurp }}) {
6610
+ my ($dbname ,$parent_table ) = ($r -> {database },$r -> {parent_table });
6611
+ $found = 1 if ! $found ;
6612
+ next ROW if skip_item($dbname );
6613
+ $found = 2;
6614
+
6615
+ $msg = " $dbname =$parent_table " . msg(' partman-conf-tbl' );
6616
+ push @warn => $msg ;
6617
+ };
6618
+ };
6619
+
6620
+
6621
+ $SQL = q{
6622
+ SELECT
6623
+ current_database() as database,
6624
+ a.parent_table,
6625
+ b.date - a.date::date AS missing_days
6626
+ FROM
6627
+ (
6628
+ SELECT parent_table, date
6629
+ FROM ( SELECT
6630
+ i.inhparent::regclass as parent_table,
6631
+ substring(pg_catalog.pg_get_expr(c.relpartbound, i.inhrelid)::text FROM '%TO __#"_{10}#"%' FOR '#') as date,
6632
+ rank() OVER (PARTITION BY i.inhparent ORDER BY pg_catalog.pg_get_expr(c.relpartbound, i.inhrelid) DESC)
6633
+ FROM pg_inherits i
6634
+ JOIN pg_class c ON c.oid = i.inhrelid
6635
+ WHERE c.relkind = 'r'
6636
+ AND pg_catalog.pg_get_expr(c.relpartbound, i.inhrelid) != 'DEFAULT') p
6637
+ WHERE
6638
+ p.rank = 1
6639
+ ) a
6640
+ JOIN
6641
+ (
6642
+ SELECT
6643
+ parent_table,
6644
+ (now() + premake * partition_interval::interval)::date
6645
+ FROM
6646
+ partman.part_config
6647
+ ) b
6648
+ ON
6649
+ a.parent_table::text = b.parent_table::text
6650
+ WHERE
6651
+ b.date - a.date::date > 0
6652
+ ORDER BY 3, 2 DESC
6653
+ } ;
6654
+
6655
+ $info = run_command($SQL , {regex => qr [\w +] , emptyok => 1 } );
6656
+
6657
+ for $db (@{$info -> {db }}) {
6658
+ my ($maxage ,$maxdb ) = (0,' ' ); # # used by MRTG only
6659
+ ROW: for my $r (@{$db -> {slurp }}) {
6660
+ my ($dbname ,$parent_table ,$missing_days ) = ($r -> {database },$r -> {parent_table },$r -> {missing_days });
6661
+ $found = 1 if ! $found ;
6662
+ next ROW if skip_item($dbname );
6663
+ $found = 2;
6664
+
6665
+ $msg = " $dbname =$parent_table ($missing_days )" ;
6666
+ print " $msg " ;
6667
+ $db -> {perf } .= sprintf ' %s=%sd;%s;%s' ,
6668
+ perfname($dbname ), $missing_days , $warning , $critical ;
6669
+ if (length $critical and $missing_days >= $critical ) {
6670
+ push @crit => $msg ;
6671
+ }
6672
+ elsif (length $warning and $missing_days >= $warning ) {
6673
+ push @warn => $msg ;
6674
+ }
6675
+ else {
6676
+ push @ok => $msg ;
6677
+ }
6678
+ }
6679
+ if (0 == $found ) {
6680
+ add_ok msg(' partman-premake-ok' );
6681
+ }
6682
+ elsif (1 == $found ) {
6683
+ add_unknown msg(' no-match-db' );
6684
+ }
6685
+ elsif (@crit ) {
6686
+ add_critical join ' ' => @crit ;
6687
+ }
6688
+ elsif (@warn ) {
6689
+ add_warning join ' ' => @warn ;
6690
+ }
6691
+ else {
6692
+ add_ok join ' ' => @ok ;
6693
+ }
6694
+ }
6695
+
6696
+ return ;
6697
+
6698
+ } # # end of check_partman_premake
6699
+
6528
6700
sub check_pgbouncer_checksum {
6529
6701
6530
6702
# # Verify the checksum of all pgbouncer settings
@@ -11028,12 +11200,15 @@ =head1 HISTORY
11028
11200
11029
11201
Add --role flag to explicitly set the role of the user after connecting (David Christensen)
11030
11202
11203
+ Add Partman premake check (Jens Wilke)
11204
+
11031
11205
Add to docs how to exclude all items in the 'pg_temp_nnn' per-session temporary schemas (Michael Banck)
11032
11206
11033
11207
Various fixes for the CI system (Emre Hasegeli)
11034
11208
11035
11209
Various improvements to the tests (Christoph Berg, Emre Hasegeli)
11036
11210
11211
+
11037
11212
=item B<Version 2.25.0 > Released February 3, 2020
11038
11213
11039
11214
Allow same_schema objects to be included or excluded with --object and --skipobject
0 commit comments