File: //usr/share/perl5/DBMon/DB.pm
package DBMon::DB;
# класс базы данных
# объект этого класса держит коннект с базой и делает свои грязные дела по комманде
use strict;
use DBMon::Log qw(say);
use DBI;
sub connect
{
my $self = shift;
my $dsn = 'DBI:mysql:'.
($self->{host} eq 'localhost' ? '' : ';host='.$self->{host}.';port='.$self->{port}).
';mysql_read_default_file=/etc/mysql/my.cnf';
my $db = [$dsn, $self->{login}, $self->{pass}, {PrintError => 0, RaiseError => 0, AutoCommit => 1}];
my $timeout = 0;
my $config_err = 0;
$self->{conn} = 0;
eval
{
local $SIG{ALRM} = sub { $timeout = 1; return; };
alarm $self->{connection_timeout};
eval { $self->{DBH} = DBI->connect(@$db); };
$config_err = 1 if( $@ );
alarm 0;
};
if( $self->{DBH} )
{
if ($self->{showsth} = $self->{DBH}->prepare('show processlist;')) {
$self->{conn} = 1;
say "Connected to server \"$self->{name}\"", 'notice';
} else {
say "Can't prepare query at \"$self->{name}\": ".$!, 'warning';
}
}
else
{
my $Reason = $DBI::errstr;
if( $timeout )
{
$Reason = "time out (server may be down)";
}
if( $config_err )
{
$Reason = "config error (may be reason in /etc/my.cnf)";
}
say "Can't connect to \"$self->{name}\": $Reason", 'warning';
}
}
# возвращает результат show processlist в виде hashref
sub monitor
{
my $self = shift;
return 0 unless($self->{conn});
unless ($self->{showsth}->execute) {
say "Can't execute query at \"$self->{name}\": ".$DBI::errstr, 'warning';
return 0;
}
my @res = ();
while(my $i = $self->{showsth}->fetchrow_hashref)
{
push @res, $i;
}
return \@res;
}
# убиваем один процесс из базы
# параметр - id процесса
sub killproc
{
my $self = shift;
my $thread_id = shift;
return 0 unless( $self->{conn} );
if ($self->{DBH}->do("kill $thread_id")) {
return 1;
} else {
say "Can't kill query at \"$self->{name}\": ".$DBI::errstr, 'warning';
return 0;
}
}
sub new
{
my $proto = shift;
my $setting = shift;
my $class = ref $proto || $proto;
my $self = $setting;
$self = bless $self, $class;
$self->{conn} = 0;
return $self;
}
1;