不停機處理oracle超過最大processes數故障

yzf01發表於2021-09-09


   在做oracle資料庫管理的時候,經常會有使用者遇到超過最大程式數的錯誤,表現為新的連線無法登入資料庫。一致提示超過最大的process數 。其實這個問題,如果使用者是測試環境,好解決。直接關閉資料庫或者直接kill掉所有的“LOCAL=NO”的程式。

   但是很多情況是,使用者無法接受停機,或者kill掉所有的遠端連線。基於以上情況,寫了如下指令碼

#!/usr/bin/perl

#write by wulei

#get the first parameter

$arg1="";

chomp($arg1);

while($arg1 eq "")

{

  print "please input your first parameter:";

  $arg1=<STDIN>;

  chomp($arg1);

  if($arg1 ne ""){

    @temp1=`ps -eo lstart,pid,args | grep '$arg1' | grep -v grep`;

    $process_count=`ps -eo lstart,pid,args | grep '$arg1' | grep -v grep | wc -l`;

    chomp($process_count);

    if($process_count eq "0")

    { 

      $arg1="";

      print "we got 0 processes,please retry!n";

      next;

    }

    print "We will kill $process_count(count) processesn";

    print "All the processes list below!!!!!!!!!!!!!!!!!n";

    print "#############################################################n";

    print @temp1;

  }

  chomp($arg1);

}

#get the second parameter

$arg2="";

chomp($arg2);

while($arg2 eq "")

{

print "n";

print "n";

print "############################################################n";

print "#[null] kill all the process we had got                    #n";

print "#[num ] kill the process start at before sysdate-number    #n";

print "if you want exit,enter 'ctrl+c'                            #n";

print "############################################################n";

print "please input your second parameter:";

$arg2=<STDIN>;

chomp($arg2);

if($arg2 eq "")

{

   print "Are you sure,to kill all the process above:[y/n]";

   $confirm=<STDIN>;

   chomp($confirm);

   if($confirm eq "Y" or $confirm eq "y")

   {

   #kill all the process ,we got it

   @result=`ps -eo pid,args | grep '$arg1' | grep -v grep`;

    print "Kill List !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!n";

    print "###################################################################n";

     foreach $result (@result)

     {

     @result1=split(/s+/,$result);

     chomp($result1[0]);

     if($result1[0] ne ""){

       #`kill -9 '$result1[0]'`;

       print $result1[0]." ".$result1[1]." ".$result1[2]."n";

       push(@kill_Queue,$result1[0]);

       }

     }

    $killQueueLen=@kill_Queue;

    print "###################################################################n";

    print "We will kill '$killQueueLen' processes!!n";

    print "Are you sure about kill the processes above?[y/n]";

    $yesorno=<STDIN>;

    chomp($yesorno);

    if($yesorno eq "Y" or $yesorno eq "y")

     {

    print "###################################################################n";

        foreach $kill_Queue (@kill_Queue)

        {

         print $kill_Queue;

         chomp($kill_Queue);

         if($kill_Queue ne "")

         {

          `kill -9 '$kill_Queue'`;

         }

        }

     }

    elsif($yesorno eq "N" or $yesorno eq "n")

     {

        @kill_Queue=();

        $arg2="";

        next;

     }

    else

     {

     print "###################################################################n";

     print "JUEST  Y   or   N!!!!n";

     print "###################################################################n";

     next;

   }

     print "OKn";

     exit;

    }

    elsif($confirm eq "N" or $confirm eq "n")

    {

    exit 0;

    }

    else

    {

      print "Please input [y/n]:";

      next;

    }

}

else

{

   if($arg2 =~ /^[+-]?d+$/)

   {

    @result=`ps -eo lstart,pid,args | grep $arg1 | grep -v grep`;

    my @kill_Queue="";

    print "killed listn";

    print "###################################################################n";

    foreach $result ( @result) 

    {

     if($result ne "")

      {

      @result1 =split(/s+/,$result);

      $time_start=$result1[1]." ".$result1[2]." ".$result1[3]." ".$result1[4];

      $format_time=`date -d '$time_start' '+%Y/%m/%d %T'`;

      chomp($format_time);

      $pro_st_time=`date +%s -d '$format_time'`;

      $a1=`date`;

      chomp($a1);

      chomp($pro_st_time);

      chomp($kill_time);

      $cur_time=`date +%s -d '$a1'`; 

      $kill_time=$cur_time-$arg2;

      if($pro_st_time > $kill_time)

      {

         print $result1[5]." ".$result1[6]." ".$result1[7]."n";

         push(@kill_Queue,$result1[5]);

      }

    }

    else

    {

    next;

    }

}

    $killQueueLen=@kill_Queue-1;

    print "###################################################################n";

    print "We will kill '$killQueueLen' processes!!n";

    print "Are you sure about kill the processes above?[y/n]";

    $yesorno=<STDIN>;

    chomp($yesorno);

    if($yesorno eq "Y" or $yesorno eq "y")

     {

        foreach $kill_Queue (@kill_Queue)

        {

         chomp($kill_Queue);

         if($kill_Queue ne "")

         {

          `kill -9 '$kill_Queue'`;

         }

        }

     }

    elsif($yesorno eq "N" or $yesorno eq "n")

     {

        $arg2="";

        next;

     }

   }

}

print "retry";

}

print "End of the scriptn";

print "================================================================n";

    指令碼的基本功能就是,可以資料要過濾的程式例如"LOCAL=NO“,然後獲得所有匹配程式的開始時間和程式內容。然後,需要資料要kill的程式是在當前時間點之前多少秒開始的程式。如果輸入null的話。就是kill掉所有匹配的程式。如果輸入1000的話,就是kill掉所有在過去1000秒鐘開始的標記為”LOCAL=NO“的所有的程式。

    執行完過程之後,就應該可以連線到資料庫中。調整process引數。保證系統正常執行,然後再查詢導致此錯誤的原因。

    這樣的話,我們就可以儘可能的減少對系統的影響。

當前指令碼知識在linux上測試過,沒有在其他類unix系統測試。

 

©著作權歸作者所有:來自51CTO部落格作者swswfas的原創作品,如需轉載,請註明出處,否則將追究法律責任


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2334/viewspace-2821117/,如需轉載,請註明出處,否則將追究法律責任。

相關文章