退出PHP脚本后终止或停止MySQL查询

问题描述:

我在工作中运行统计信息服务器,由于运行的查询量有时会变慢。退出PHP脚本后终止或停止MySQL查询

我们的营销团队将其作为主要统计工具。团队中的某些人有时会在结束之前退出脚本(通过关闭浏览器或标签)。同时,SQL查询继续执行。

当某人关闭或离开此脚本时,如何终止或停止PHP脚本的关联查询?

我们当然不希望手工杀死这些查询(我们已经这样做),但只要该用户退出脚本就自动执行。

我们的大部分统计脚本都是基于每天晚上对其中最重的人进行的预先计算,而这些对我们来说并不成问题。对于其他人,我们还没有实施预先计算,我们希望能够在执行之前杀死孤儿查询。

+0

检查该问题和答案:http://stackoverflow.com/questions/1189039/how-do-i-routinely-kill-mysql-queries-that-have-been-alive-for-too-tolong – 2011-03-30 13:20:18

+0

也许更好地指示SQL查询的进度将会使人们不再像以前那样放弃网页。另一种选择是使SQL查询异步,所以人们不必等待结果。 – 2011-03-30 13:22:24

+0

感谢您的建议。然而,我们运行的大多数脚本都有一个庞大的查询parsng,通过10或2000万行。所以没有真正的方法知道查询的n%已经达到我猜。 – cellover 2011-03-30 13:26:57

您可以使用Connection Handling mechanisms检查从浏览器到服务器的连接是否仍处于打开状态,并进行适当的反应。

然而要注意的是有开始至今将运行完所有的SQL查询 - 如果他们是复杂的,这可能需要一段时间,而且也没有带的方式来终止它们:你需要观看哪个线程运行什么并定期收获废弃的线程。

+0

这就是问题所在,一旦用户退出他的页面,我们希望触发一个kill查询。我想我们已经找到了一种方法来做到这一点: - 一旦连接建立,获得SQL CONNECTION_ID()(http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_connection -id) - 它存储在某个变量 - 一旦用户退出网页,发出触发基于以前的变量 – cellover 2011-03-30 14:14:12

+0

@cellover一个KILL查询一个js事件:发出JS事件时,他们关闭浏览器?祝你好运 - 大多数浏览器会杀'onunload'事件处理程序,如果他们跑太久... – Piskvor 2011-03-30 14:18:24

最好的方法(我认为)是在使用后立即关闭连接。 也可以设置wait_timeout会话变量(例如减少到20秒);在这种情况下,连接将自动关闭。

+0

的问题是,一旦查询已完成连接应该被关闭,有时从未happend ^^ – cellover 2011-03-30 13:52:43

+0

为什么你不能手动关闭它在你的PHP脚本?而关于wait_timeout变量 - 它强制服务器关闭连接,如果一段时间没有激活。 – Devart 2011-03-30 14:17:37

+0

我们无法激活它,因为我们不知道用户将在什么步骤退出脚本。至于wait_timeout变量,如果他等待结果显示出来,即使这需要1个小时,我们也不想将用户踢出去。 – cellover 2011-03-30 14:20:04

不幸的是,如果他们只是在他们的浏览器上点击关闭按钮,可以做的不多。列出的已经有一些内置函数会检查会话。也许尝试缓存最常用的查询。 Google“缓存php mysql”。

如果这不起作用,您可以使用AJAX构建它,并且每次查询完成时 - 服务器将发回一条消息,以便用户更新其请求的进度。这可能会减少刚刚放弃会议的人数。

+0

是的,这可能会减少用户过早退出脚本的数量,但它可以在运行大量查询的脚本上工作,这在这里很少见。我们通常在每个脚本中运行更多大约2或3个查询。 – cellover 2011-03-30 13:53:47

随着我的一些同事,我们提出了以下思路:

  • 一旦MySQL连接建立后,在SQL得到CONNECTION_ID() - CONNECTION_ID() doc on MySQL
  • 其存储在某个变量
  • 一次用户退出该页面(可以通过退出或加载另一页面),发出触发基于前一个变量的KILL查询的js事件

我们将我们会在接下来的几个小时内进行测试,一旦我们确信它能够正常工作,我会尽快更新。

+0

它工作?你以其他方式解决了吗? – 2013-12-07 19:31:49

您有时需要能够杀死持续时间过长的查询。如果你想在你的操作系统中这样做,你可以这样做 - 这是相当安全的,因为MySQL在子进程中运行所有这些。在Unix中,这是pskill

您也可以使用MysqlAdmin来做到这一点,它应该在不同的操作系统中基本相同。你正在运行的进程的列表:

$ mysqladmin processlist # password if necessary 
+----+------+-----------+----+---------+------+-------+------------------+ 
| Id | User | Host  | db | Command | Time | State | Info    | 
+----+------+-----------+----+---------+------+-------+------------------+ 
| 2 | root | localhost | | Query | 0 |  | show processlist | 
+----+------+-----------+----+---------+------+-------+------------------+ 

再看看mysqladmin kill将其删除。

编辑

好吧,如果这是关于检测浏览器关闭,我看到几个方法:

  1. 退房PHP的connection handling。看起来您可以注册一个在用户关闭浏览器时调用的句柄。
  2. 如果处理程序不被调用,也许你可以调用插页,说简单地“运行的查询......”,然后该网页的呈现可以在一个循环中坐,等待查询完成或连接结束。如果查询完成,则重定向到“结果”页面,如果连接断开,请手动终止查询(请参见上文)。
  3. 如果这些方法毫无结果,还有另一种选择。浏览器在浏览器中提供了一个“在卸载”事件上的Javascript,该事件在浏览器中最近被触发。一个快速的Ajax帖子可以解决长时间运行的查询问题。

(作业:讨论所有方法的优点和缺点)的这些

无罢工我美丽的,但也有一些工作,他们可以进行工作。说实话,当我们遇到这个问题时,我们只是保留了一个流程列表并杀掉了看起来像错误查询的东西。

+0

感谢您的评论!是的,我们知道如何杀死查询,我们只希望在用户退出该页面时自动终止它们,并且除非出于很好的理由,否则我们不希望杀死太久的查询。 – cellover 2011-03-30 14:50:47

+0

增加了一些关于如何检测用户“退出页面”的想法。 – ndp 2011-03-31 04:19:16