How can I stop a MySQL query if it takes too long?

后端 未结 9 1334
野趣味
野趣味 2020-12-02 09:22

Is it possible to timeout a query in MySQL?

That is, if any query exceeds the time I specify, it will be killed by MySQL and it will return an error instead of waiti

相关标签:
9条回答
  • 2020-12-02 09:38

    The MySQL forum has some threads about this.

    This post details how to set up timeouts on the server using innodb_lock_wait_timeout.

    Here's a way to do it programmatically, assuming you're using JDBC.

    0 讨论(0)
  • 2020-12-02 09:44

    There is a nice Perl script on CPAN to do just this: http://search.cpan.org/~rsoliv/mysql-genocide-0.03/mysql-genocide

    One only needs to schedule it to run with the proper parameters. Create a CRONtab file /etc/cron.d/mysql_query_timeout to schedule it to run every minute:

    * * * * * root /path/to/mysql-genocide -t 7200 -s -K

    Where 7200 is the maxiumum allowed execution time in seconds. The -s switch filters out all except SELECT queries. The -K switch instructs the script to kill the matching processes.

    The root user should be able to run local mysql tools without authentication otherwise you will need to provide credentials on the command line.

    0 讨论(0)
  • 2020-12-02 09:45

    Since MySQL 5.7.8 there is max_execution_time option that defines the execution timeout for SELECT statements.

    0 讨论(0)
  • 2020-12-02 09:51

    I thought it has been around a little longer, but according to this,

    MySQL 5.7.4 introduces the ability to set server side execution time limits, specified in milliseconds, for top level read-only SELECT statements.

    SELECT 
    MAX_STATEMENT_TIME = 1000 --in milliseconds
    * 
    FROM table;
    

    Note that this only works for read-only SELECT statements.

    0 讨论(0)
  • 2020-12-02 09:54

    I just set up the following bash script as a cron job to accomplish this with MySQL 5.0 (kills any query that has been executing for more than 30 seconds). Sharing it here in case it proves useful to anyone (apologies if my bash scripting style is inefficient or atrocious, it is not my primary development language):

    #!/bin/bash
    linecount=0
    processes=$(echo "show processlist" | mysql -uroot -ppassword)
    oldIfs=$IFS
    IFS='
    '
    echo "Checking for slow MySQL queries..."
    for line in $processes
    do
        if [ "$linecount" -gt 0 ]
            then
                pid=$(echo "$line" | cut -f1)
                length=$(echo "$line" | cut -f6)
                query=$(echo "$line" | cut -f8)
                #Id User    Host    db  Command Time    State   Info
                if [ "$length" -gt 30 ]
                    then
                        #echo "$pid = $length"
                        echo "WARNING:  Killing query with pid=$pid with total execution time of $length seconds! (query=$query)"
                        killoutput=$(echo "kill query $pid" | mysql -uroot -ppassword)
                        echo "Result of killing $pid:  $killoutput"
                fi
        fi
        linecount=`expr $linecount + 1`
    done
    IFS=$oldIfs
    
    0 讨论(0)
  • 2020-12-02 09:54

    I don't think the egrep above would find "2000".
    Why not try just selecting the id as well, and avoiding all of that posh shell stuff:

    mysql -e 'select id from information_schema.processlist where info is not null and time > 30;'
    
    0 讨论(0)
提交回复
热议问题