我正在使用Django 1.1和Mysql 5. *以及MyISAM表。
我的一些查询可能需要花费大量时间来处理数据集中的异常值。这些锁定表并关闭站点。其他时候似乎有些用户在完成请求之前取消了请求,而某些查询将停留在“准备”阶段,锁定所有其他查询。
我将尝试追踪所有角落的情况,但很高兴有一个安全网,所以网站不会下降。
我该如何避免这种情况?我可以设置最长查询时间吗?
答案 0 :(得分:1)
不幸的是,MySQL不允许您轻松避免这种情况。一种常见的方法基本上是编写一个脚本,每X秒检查一次所有正在运行的进程(基于你认为“长”的内容)并杀死它看到运行时间过长的进程。但是,您至少可以通过在MySQL中设置log_slow_queries
来获取一些基本诊断信息,这会将所有超过10秒的查询写入日志中。如果对于您认为“慢”的目的而言太长,您可以将long_query_time
设置为10以外的值来更改阈值。
答案 1 :(得分:1)
我正在做一个Django数据库复制应用程序并且具有相同的困境,如果网络延迟增加,跨WAN的查询有时似乎会挂起。
来自http://code.activestate.com/recipes/576780/
食谱576780:(几乎)任何可赎回的超时
创建任何可调用的时间限制版本。
例如,要将函数f
限制为t秒,
首先创建f
的限时版本。
from timelimited import *
f_t = TimeLimited(f, t)
然后,不要使用f(...)
,而是使用f_t
之类的
try:
r = f_t(...)
except TimeLimitExpired:
r = ... # timed out
以下列方式使用它:
def _run_timed_query(cursor, log_msg, timeout, query_string, *query_args):
"""Run a timed query, do error handling and logging"""
import sys
import traceback
from timelimited import *
try:
return TimeLimited(cursor.execute, timeout)(query_string, *query_args)
except TimeLimitExpired:
logger_ec.error('%s; Timeout error.' % log_msg)
raise TimeLimitExpired
except:
(exc_type, exc_info, tb) = sys.exc_info()
logger_ec.error('%s; %s.' % (log_msg, traceback.format_exception(exc_type, exc_info, None)[0]))
raise exc_type
答案 2 :(得分:0)
似乎唯一可靠的中止查询的方法是kill command。一个不太激烈的措施是关闭连接(并重新打开一个连接);这会在他们尝试send some output到客户端时立即终止查询。
答案 3 :(得分:0)
您知道查询是什么吗?也许您可以优化SQL或在表上放置一些索引?
答案 4 :(得分:0)
使用InnoDB表,它们row-locking代替table-locking。
答案 5 :(得分:0)
您不应该编写类似的查询,至少不要针对您的实时数据库运行。 Mysql有一个“慢查询”参数,你可以用它来识别杀死你的查询。大多数情况下,这些慢速查询要么是错误的,要么可以通过定义一个或两个新索引来加速。