Довольно часто возникает такая ситуация, когда процесс MySQL грузит всю систему, а пока "залогинишся" на сервер, пройдет кучу времени, и нагрузка может уже упасть. По-этому сложно выловить пользователя злоупотребляющего MySQL ресурсами.
Для этого есть скрипт, код скрипта ниже. Вы должны запустить этот скрипт в фоновом режиме. Она свяжется с MySQL и будет оставатся на связи. Каждые 10 минут (по умолчанию), он будет проверять, чтобы убедиться, что пользователь не перешагнул планку нагрузки сервера. Вы можете изменить время / лимиты. Начиная с версии 0.2 скрипт обладает способностью убивать пользователськие подключения к MySQL, если они превышают установленный лимит. Все отчеты отправляются на емайл администратора.
#!/usr/bin/perl
# Version: 0.02
use DBI();
use Sys::Hostname;
#Sets the maximum concurrent connections per MySQL user.
my $max_concurrent_connections = '15';#Who to tell about this user... (email)my $warning_email = 'noc@localhost';#Kill Abuser's MySQL Connections (0 = no, 1 = yes)my $kill_user = '0';#MySQL polling in seconds (600 = 10 minutes)
my $check_interval = '600';###################################
####NO NEED TO EDIT BELOW HERE#####
###################################
#Set these if you wish to run the script as a diffrent mysql user.
my $mysqluser = '';my $mysqlpass = '';$hostname = hostname();
if ((!$mysqluser) or (!$mysqlpass)) {open(MYCNF,"/root/.my.cnf");
while(<MYCNF>) {chomp;
s/"//g;
if(/user/is) { (undef,$mysqluser) = split('=', $_, 2); } if(/pass/is) { (undef,$mysqlpass) = split('=', $_, 2); }}
close(MYCNF);
}
my $dbh = DBI->connect("DBI:mysql:host=localhost", "$mysqluser", "$mysqlpass", {'RaiseError' => 1});while(1) { unless ($dbh->ping) {$dbh->disconnect;
$dbh = DBI->connect("DBI:mysql:host=localhost", "$mysqluser", "$mysqlpass", {'RaiseError' => 1});my $rc = $dbh->ping;
unless ($dbh->ping) { print STDERR "Error, Could not reconnect to MySQLn";
exit;
}
}
undef $abusers;
undef %counter;
my $watch = $dbh->prepare("SHOW PROCESSLIST");$watch->execute();
while (my $ref = $watch->fetchrow_hashref()) { $counter{$ref->{'User'}} ++;}
foreach $key (keys %counter) { if($counter{$key} > $max_concurrent_connections) { $abusers .= "$key:$counter{$key}n";}
}
if($abusers){my $subject = "WatchMySQL: Warning $hostname has MySQL Abusersn";
my $msg = "The Following Users have exceeded there maximum MySQL concurrent users limitnn Below is a list of users as well as how many times they are connectednn";
open(SENDMAIL,"|/usr/sbin/sendmail -t");
print SENDMAIL "To: <$warning_email>n";
print SENDMAIL "From: WatchMySQL@$hostnamen";
print SENDMAIL "Subject: $subjectnn";
print SENDMAIL "$msg$abusers";
close(SENDMAIL);
}
if($kill_user == 1) { foreach ($abusers) {chomp;
($abuser_user,undef) = split(':', $_ , 2); my $watch = $dbh->prepare("SHOW PROCESSLIST");$watch->execute();
while (my $ref = $watch->fetchrow_hashref()) { if($ref->{'User'} eq $abuser_user) {print "Killed $abuser_usern";
$dbh->do("kill $ref->{'Id'}");}
}
}
}
sleep $check_interval;
}
Скачать скрипт: MySQL Watch
Комментариев нет:
Отправить комментарий