File Coverage

blib/lib/Pgtools/Kill.pm
Criterion Covered Total %
statement 49 86 56.9
branch 9 20 45.0
condition 8 15 53.3
subroutine 10 13 76.9
pod 0 4 0.0
total 76 138 55.0


line stmt bran cond sub pod time code
1             package Pgtools::Kill;
2 1     1   38876 use strict;
  1         2  
  1         25  
3 1     1   4 use warnings;
  1         1  
  1         22  
4 1     1   758 use DateTime;
  1         75733  
  1         47  
5 1     1   580 use DateTime::Format::Strptime;
  1         20753  
  1         5  
6 1     1   120 use DBI;
  1         1  
  1         36  
7              
8 1     1   376 use Pgtools;
  1         10  
  1         21  
9 1     1   289 use Pgtools::Connection;
  1         2  
  1         3  
10 1     1   349 use Pgtools::Query;
  1         2  
  1         4  
11 1     1   23 use parent qw(Class::Accessor);
  1         2  
  1         2  
12             __PACKAGE__->mk_accessors(qw(help ignore_match_query ignore_match_state kill match_query match_state print run_time version));
13              
14             our ($now, $qt) ;
15             our $qt_format = DateTime::Format::Strptime->new(
16             pattern => '%Y-%m-%d %H:%M:%S.%N'
17             );
18             our $start_time = DateTime->now( time_zone => 'Asia/Tokyo' );
19              
20             sub exec {
21 0     0 0 0 my ($self, $arg) = @_;
22 0         0 my $default = {
23             "host" => "localhost",
24             "port" => "5432",
25             "user" => "postgres",
26             "password" => "",
27             "database" => "postgres"
28             };
29              
30 0         0 my $db = Pgtools::Connection->new($default);
31 0         0 $db->set_args($arg);
32 0         0 $db->create_connection();
33              
34             # return hash reference
35 0         0 my $queries = &search_queries($self, $db);
36              
37 0 0 0     0 if($self->print and !$self->kill) {
38 0         0 &print_query($queries);
39             }
40 0 0       0 if($self->kill){
41 0         0 &kill_queries($db, $self, $queries);
42 0         0 print "Killed matched queries!\n";
43             }
44              
45 0         0 $db->dbh->disconnect;
46             }
47              
48             sub kill_queries {
49 0     0 0 0 my ($db, $self, $queries) = @_;
50 0         0 my ($sth, $now);
51              
52 0         0 foreach my $pid (keys(%$queries)) {
53 0         0 $sth = $db->dbh->prepare("SELECT pg_terminate_backend(".$pid.");");
54 0         0 $now = DateTime->now( time_zone => 'local' );
55 0         0 $sth->execute();
56 0 0       0 if($self->print) {
57 0         0 print "-------------------------------\n";
58 0         0 print "Killed-pid: ".$pid."\n";
59 0         0 print "At : ".$now->strftime('%Y/%m/%d %H:%M:%S')."\n";
60 0         0 print "Query : ".$queries->{$pid}->{query}."\n";
61             }
62             }
63             }
64              
65             sub search_queries {
66 3     3 0 18230 my ($self, $db) = @_;
67 3         4 my @pids;
68 3         4 my $queries = {};
69              
70 3         19 my $sth = $db->dbh->prepare("
71             SELECT
72             datname,
73             pid,
74             query_start,
75             state,
76             query
77             FROM
78             pg_stat_activity
79             WHERE
80             pid <> pg_backend_pid()
81             ");
82 3         582 $sth->execute();
83              
84 3         166 while (my $hash_ref = $sth->fetchrow_hashref) {
85 9         432 my %row = %$hash_ref;
86 9 50       36 if($db->database ne $row{datname}) {
87 0         0 next;
88             }
89 9 100 100     311 if($self->match_state ne '' and $row{state} ne $self->match_state) {
90 4         69 next;
91             }
92 5 100 66     68 if($self->match_query ne '' and $row{query} !~ /$self->{match_query}/im ) {
93 1         13 next;
94             }
95 4 50 33     58 if($self->ignore_match_state ne '' and $row{state} eq $self->ignore_match_state) {
96 0         0 next;
97             }
98 4 100 66     32 if($self->ignore_match_query ne '' and $row{query} =~ /$self->{ignore_match_query}/im ) {
99 1         21 next;
100             }
101 3 50       21 if($self->run_time != 0) {
102 0         0 $qt = $qt_format->parse_datetime($row{query_start});
103 0         0 $qt->set_time_zone('local');
104 0         0 my $diff = $start_time->epoch() - $qt->epoch();
105 0 0       0 if($diff < $self->run_time) {
106 0         0 next;
107             }
108             }
109              
110             my $tmp = {
111             "datname" => $row{datname},
112             "pid" => $row{pid},
113             "query_start" => $row{query_start},
114             "state" => $row{state},
115             "query" => $row{query}
116 3         27 };
117 3         15 my $q = Pgtools::Query->new($tmp);
118 3         23 $queries = {%{$queries}, $row{pid} => $q};
  3         24  
119             }
120 3         89 $sth->finish;
121              
122 3         50 return $queries;
123             }
124              
125             sub print_query {
126 0     0 0   my $queries = shift @_;
127 0           foreach my $q (keys(%$queries)) {
128 0           print "-------------------------------\n";
129 0           print "pid : ".$queries->{$q}->{pid}."\n";
130 0           print "start_time: ".$queries->{$q}->{query_start}."\n";
131 0           print "state : ".$queries->{$q}->{state}."\n";
132 0           print "query : ".$queries->{$q}->{query}."\n";
133             }
134             }
135              
136             1;