File Coverage

blib/lib/Pgtools/Kill.pm
Criterion Covered Total %
statement 19 21 90.4
branch n/a
condition n/a
subroutine 7 7 100.0
pod n/a
total 26 28 92.8


line stmt bran cond sub pod time code
1             package Pgtools::Kill;
2 1     1   35672 use strict;
  1         1  
  1         23  
3 1     1   3 use warnings;
  1         0  
  1         18  
4 1     1   714 use DateTime;
  1         68736  
  1         31  
5 1     1   491 use DateTime::Format::Strptime;
  1         19036  
  1         4  
6 1     1   60 use DBI;
  1         1  
  1         28  
7              
8 1     1   296 use Pgtools;
  1         8  
  1         19  
9 1     1   265 use Pgtools::Connection;
  0            
  0            
10             use Pgtools::Query;
11             use parent qw(Class::Accessor);
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             my ($self, $arg) = @_;
22             my $default = {
23             "host" => "localhost",
24             "port" => "5432",
25             "user" => "postgres",
26             "password" => "",
27             "database" => "postgres"
28             };
29              
30             my $db = Pgtools::Connection->new($default);
31             $db->set_args($arg);
32             $db->create_connection();
33              
34             # return hash reference
35             my $queries = &search_queries($self, $db);
36              
37             if($self->print and !$self->kill) {
38             &print_query($queries);
39             }
40             if($self->kill){
41             &kill_queries($db, $self, $queries);
42             print "Killed matched queries!\n";
43             }
44              
45             $db->dbh->disconnect;
46             }
47              
48             sub kill_queries {
49             my ($db, $self, $queries) = @_;
50             my ($sth, $now);
51              
52             foreach my $pid (keys(%$queries)) {
53             $sth = $db->dbh->prepare("SELECT pg_terminate_backend(".$pid.");");
54             $now = DateTime->now( time_zone => 'local' );
55             $sth->execute();
56             if($self->print) {
57             print "-------------------------------\n";
58             print "Killed-pid: ".$pid."\n";
59             print "At : ".$now->strftime('%Y/%m/%d %H:%M:%S')."\n";
60             print "Query : ".$queries->{$pid}->{query}."\n";
61             }
62             }
63             }
64              
65             sub search_queries {
66             my ($self, $db) = @_;
67             my @pids;
68             my $queries = {};
69              
70             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             $sth->execute();
83              
84             while (my $hash_ref = $sth->fetchrow_hashref) {
85             my %row = %$hash_ref;
86             if($db->database ne $row{datname}) {
87             next;
88             }
89             if($self->match_state ne '' and $row{state} ne $self->match_state) {
90             next;
91             }
92             if($self->match_query ne '' and $row{query} !~ /$self->{match_query}/im ) {
93             next;
94             }
95             if($self->ignore_match_state ne '' and $row{state} eq $self->ignore_match_state) {
96             next;
97             }
98             if($self->ignore_match_query ne '' and $row{query} =~ /$self->{ignore_match_query}/im ) {
99             next;
100             }
101             if($self->run_time != 0) {
102             $qt = $qt_format->parse_datetime($row{query_start});
103             $qt->set_time_zone('local');
104             my $diff = $start_time->epoch() - $qt->epoch();
105             if($diff < $self->run_time) {
106             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             };
117             my $q = Pgtools::Query->new($tmp);
118             $queries = {%{$queries}, $row{pid} => $q};
119             }
120             $sth->finish;
121              
122             return $queries;
123             }
124              
125             sub print_query {
126             my $queries = shift @_;
127             foreach my $q (keys(%$queries)) {
128             print "-------------------------------\n";
129             print "pid : ".$queries->{$q}->{pid}."\n";
130             print "start_time: ".$queries->{$q}->{query_start}."\n";
131             print "state : ".$queries->{$q}->{state}."\n";
132             print "query : ".$queries->{$q}->{query}."\n";
133             }
134             }
135              
136             1;