Tuesday, October 06, 2015

Mass kill processes in MySQL "show processlist"

So your server load is high you did "SHOW PROCESSLIST;" and you noticed many slow queries and you want to kill them.
If the list is too long to do it manually, you may want to try this way:

<?php

include("mySqlClass.inc.php");

$serv="localhost";
$user="root";
$pass="YOUR_PASS";
$database="SOME_DB";


$link = new mySqlClass();
$link->Connect($serv,$user,$pass,$database);
$result=$link->SqlQuery("SHOW FULL PROCESSLIST");
while ($result->NextRow()) {
    $process_id=$result->field["Id"];
    if ($result->field["Time"]>200) $link->SqlQuery("KILL $process_id");
}   

?>


and the mySqlClass.inc.php:


<?php

class mySqlClass {

  public $query_count;
  public $query_time;

  private $database;
  public $link;
  private $db_connected;

  function __construct()
  {
    $this->query_count = 0;
    $this->query_time = 0;
  }

  public function Connect($host, $user, $password, $database)
  {
    $this->database = $database;

    $this->link = @mysql_connect($host, $user, $password, true);

    if ($this->link)
    {
      if (@mysql_select_db($database, $this->link))
      {
        $this->db_connected = true;
        return true;
      }
    }

    $this->_error(mysql_errno(), mysql_error());
    return false;
  }

  public function SqlQuery($sql)
  {
    $time_start = explode(' ', microtime());

    if (!$this->db_connected) $this->_error(0, 'Error: MySQL DB Not Connected');

    $result_resource = @mysql_query($sql, $this->link);

    if (!$result_resource) $this->_error(@mysql_errno($this->link), @mysql_error($this->link));

    $obj = new SqlQueryResult($result_resource);

    if ($obj->RowCount() > 0)
    {
      // Return the first row of data results
      $result_array = @mysql_fetch_array($result_resource, MYSQL_ASSOC);

      if ($result_array)
      {
        while (list($key, $value) = each($result_array))
        {
          $obj->field[$key] = $value;
        }
      }
    }

    $time_end = explode (' ', microtime());
    $query_time = $time_end[1]+$time_end[0]-$time_start[1]-$time_start[0];
    $this->query_time += $time_end[1] + $time_end[0] - $time_start[1] - $time_start[0];
    $this->query_count++;

    return($obj);
  }

  public function QueryCount()
  {
    return $this->query_count;
  }

  public function QueryTime()
  {
    return $this->query_time;
  }

  private function _error($error_number, $error_text)
  {
    if ($error_number != 1141)
    {
      echo "Error #$error_number: $error_text";
      die();
    }
  }
}


class SqlQueryResult {

  public $field;

  private $result_resource;
  private $num_rows;
  private $current_row;

  function  __construct($result_resource)
  {
    $this->result_resource = $result_resource;
    $this->current_row = 0;
    $this->num_rows = @mysql_num_rows($this->result_resource);
    $this->field = array();
  }

  public function NextRow()
  {
    if ($this->current_row === 0)
    {
      // Row already fetched from SqlQuery() function
      // Do nothing
    }
    else if ($this->num_rows > 0 AND $result_array = @mysql_fetch_array($this->result_resource, MYSQL_ASSOC))
    {
      // This is the next iteration and there is a counted row returned
      // Grab data array
      if ($result_array)
      {
        while (list($key, $value) = each($result_array))
        {
          $this->field[$key] = $value;
        }
      }
    }
    else
    {
      // No more rows, end of data iteration
      // End result
      return false;
    }

    $this->current_row++;

    return true;
  }

  public function RowCount()
  {
    return $this->num_rows;
  }
}

No comments: