Наблюдение за использованием процессорного времени на SQLсервере



Наблюдение за использованием процессорного времени на SQL-сервере

В последнем примере этой главы DBI будет выводить обновляемую раз в минуту строку состояния, содержащую информацию об использовании процессорного времени на SQL-сервере. Чтобы сделать задачу более интересной, можно из одного и того же сценария одновременно наблюдать за двумя серверами. Комментарий к сценарию последует позже:

use DBI:

Ssyadmin = "sa':

print "Пароль администратора Sybase:

chomp($sypw = <STDltJ>) Smsadmin = "sa";

print "Пароль администратора базы данных MS-SOL' ";

chomp($mspw = <STDIN>);

ft соединяемся с сервером Sybase

Ssydbh = DBI->connect("dbi:Sybase:server=SYBASE",Ssyadmin.Ssypw);

die "Невозмржно соединиться с сервером

Sybase: $D8I::errstr\n" unless (defined Ssydbh);

# включаем параметр ChopBlanks, чтобы удалить концевые пробелы из столбцов

$sydbh->{ChopBlanks} = 1;

п

соединяемся с сервером MS-SOL (очень здорово, что мы можем

# использовать для этого OBD::Sybase! )

Smsdbh = DBI->connect("dbi:Sybase:server=MSSQL",Smsadmin,Smspw);

die "Невозможно соединиться с сервером mssql: $DBI::errstr\n" unless (defined Smsdbh);



# включаем параметр ChopBlanks, чтобы удалить концевые пробелы $msdbh->{ChopBlanks} = 1;

$1=1; # выключаем буферизацию вывода STOOUT

и инициализируем обработчик сигнала с тем, чтобы можно было

# корректно завершиться $SIG{INT} = suu (Sbyebye = 1;};

и бесконечный цикл, который завершится при установке

ft нашего флага прерывания while (1) {

last if (Sbyebye);

и запускаем хранимую процедуру sp_monitor Ssystn = $sydbh->prepare(q{sp_monitor» or

die "Невозможно подготовить sy sp_monitor:".$sydbh->errstr."\n";

$systh->execute or

die "Невозможно выполнить sy sp_monitor;".$sydbh->errstr."\n";

цикл для получения нужных нам строк, и мы знаем, что у нас есть все, что нужно, когда мы

# получаем информацию

cpu_busy wbile($href = $systh->fetchrow_hasnref or

$systh->{syb^more_results}) {

К есть то, что нужно, перестаем спрашивать

last if (defined $href->{cpu_busy}); ! $systh->firush;

ft заменяем все, кроме %, значениями, которые мы

в получили

for (keys %{$href}) <

$nref->{$_} =" s/. '-(\d+%)/\V; }

# собираем все нужные нам данные в одну строку

$info - "Sybase: (". $nref-Xcpu_busy}. "

CPU), ". "(".$href->{io_busy}." 10), ". "(".$href->{idle}." idle) ";

отлично, тпг.ерь сделаем то же самое и для другого сервера

(MS-SQL)

Smssth = $msdbh->prepare(q{sp_monitor}) or

die "Невозможно подготовить ms spjnonitor;".

$o)sdoh->errstr. "\л': $Disstb->execute or

die "Невозможно выполнить ms spjronitor:".

$nsdbn->errstr."\n": while($href = $mssth->

fetchrow^hashref or $mssth->{syb_more_results})

{

# есть то, что нужно, перестаем спрашивать

last if (defined $href->{cpu_busy»:

}

$mssth->finish;

# заменяем все, кроме % for (keys %{$href» {

Sirifo .= "MSSQL: (" . $href->{' cpu_busy'}." CPU), ".

"C'.$href->{'io_busy'}." 10), ".

"(".$riref->{'idle'}." idle)"; print " "x78,"\r"; print $info,"\r";

sleep(5) unless (Sbyebye); }

# попадаем сюда, только если мы прервали цикл

$sydbh->disconnect;

$msdbh->disconnect;

Сценарий выводит эту строку на экран и обновляет ее каждые пять секунд:

Sybase: (33% CPU), (33% 10), (0% idle) MSSQL: (0% CPU), (0%!0), (100% idle)

Основу данной программы составляет хранимая процедура

sp_mon:tor,

существующая как на Sybase-, так и на MS-SQL-сервере.

Вывод sp_mo-nitor выглядит примерно так:

last_run current_run seconds

Аид 3 1998 12:05АМ Аид 3 1998 12:05АМ 1

cpu_busy io_busy idle

0(0)-0% 0(0)-0% 40335(0)^0%

packets^received packets_sent packet_errors

1648(0) 1635(0) 0(0)

total_read total_write total_errors connections

391(0) 180(0) 0(0) 11(0)

К сожалению, sp_monitor показывает непереносимую особенность Sybase, которая прекочевала к MS-SQL: множественные наборы результатов. Каждая из строк возвращается в виде отдельного результата. Модуль DBD: : Sybase справляется с этим, устанавливая специальный атрибут команды. Вот как возникла эта проверка:

while($href = $systh->fetchrow_hashref or

$systh->{syb_more_results}) {

и вот почему следовало выйти из цикла до того, как были замечены нужные поля:

# есть то, что нужно, перестаем спрашивать

last if (defined $href->{cpu_busy});

Сама программа будет выполняться в вечном цикле до тех пор, пока не получит сигнал прерывания (наиболее вероятно, что это будет нажатие клавиш <Ctrl>+<C> пользователем). Получив такой сигнал, мы делаем самую безопасную вещь из тех, что можно сделать с обработчиком сигнала, и устанавливаем флаг возврата. Подобную технологию рекомендуют использовать на страницах perlipc для безопасной обработки сигналов. После получения сигнала INT будет установлен соответствующий флаг, который выбросит нас из цикла на следующей итерации. Получение этого сигнала позволяет программе «деликатно» закрыть дескрипторы баз данных, перед тем как сбросить «этот бренный шум».

Эта небольшая программа всего лишь затронула возможности наблюдения за состоянием сервера, доступные нам. Было бы несложно, взяв полученные от sp_monitor результаты, построить график, чтобы получить более наглядное представление о том, как используется сервер. Но... оставим заботы об украшательстве читателю.



Содержание раздела