简体   繁体   English

无论如何限制MySQL查询执行时间?

[英]Anyway to Limit MySQL Query Execution time?

Hi I'm having issues on my server at the minute because some of the MySQL queries are taking a very long time to run, and hogging the resources on the server. 嗨,我在服务器上遇到问题,因为一些MySQL查询需要很长时间才能运行,并占用服务器上的资源。

I'm already in the process of optimising all the queries to improve the performance, but as we use a fair amount of 3rd party applications on the server using mysql I was hoping to put in place a safeguard to prevent future issues. 我已经在优化所有查询以提高性能,但由于我们使用mysql在服务器上使用了相当数量的第三方应用程序,我希望能够采取措施防止未来出现问题。

What I need is something I can put in place server wide that will apply to all queries but with the possibility of overriding it on a per query basis for some of the more complex reports that do take some time to run. 我需要的是我可以在服务器范围内放置适用于所有查询的东西,但有可能在每个查询的基础上覆盖一些需要一些时间来运行的更复杂的报告。

I've spent time googling to find a solution but so far no luck, 我花时间谷歌搜索找到解决方案,但到目前为止没有运气,

Thanks for your help 谢谢你的帮助

you can use the following procedure to check for queries running longer than 300secs. 您可以使用以下过程来检查运行时间超过300秒的查询。 the event runs the procedure periodically and kills all long running queries. 该事件定期运行该过程并终止所有长时间运行的查询。

    CREATE PROCEDURE DBNAME.kill_long_running_queries ()
BEGIN

  DECLARE v_qid BIGINT;
  DECLARE v_finished INT DEFAULT 0;
  DECLARE c_queries CURSOR FOR SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND = 'Query' AND TIME > 300;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_finished = 1;

  OPEN c_queries;

  l_fetch_queries: LOOP
    FETCH c_queries INTO v_qid;
    IF v_qid > 0 THEN
      KILL QUERY v_qid;
    END IF;
    IF v_finished THEN
      LEAVE l_fetch_queries;
    END IF;
  END LOOP l_fetch_queries;
  CLOSE c_queries;

END

CREATE EVENT kill_long_running_queries
ON SCHEDULE EVERY 60 SECOND
DO CALL DBNAME.kill_long_running_queries();

This is a purely php solution that seems to be the simplest solution from what I've managed to find so far. 这是一个纯粹的php解决方案,似乎是迄今为止我找到的最简单的解决方案。

$result = mysql_query("SHOW FULL PROCESSLIST");
while ($row=mysql_fetch_array($result)) 
{
  $process_id = $row["Id"];
  if ($row["Time"] > 200 ) 
  {
    $sql="KILL {$process_id}";
    mysql_query($sql);
  }
}

And running this from a CRON script every 60 seconds. 每60秒从CRON脚本运行一次。

If anyone does find a better solution to this issue please let me know 如果有人确实找到了解决此问题的更好方法,请告诉我

I can recommend http://www.percona.com/doc/percona-toolkit/2.1/pt-kill.html which is designed specifically for that. 我可以推荐专门为此设计的http://www.percona.com/doc/percona-toolkit/2.1/pt-kill.html From man page: 从手册页:

pt-kill - Kill MySQL queries that match certain criteria.

There is no way to do it using MySQL options. 使用MySQL选项无法做到这一点。 But you can still do it using daemon process as @rabudde advised. 但是你仍然可以使用@rabudde建议的守护进程来完成它。

In this case, if you kill process you will abort transaction and it will be rollback. 在这种情况下,如果您终止进程,您将中止事务并将进行回滚。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM