我想每分钟检查一下我的MySQL服务器并终止运行时间超过150秒的查询。我想这样做的主要原因是因为我不希望某些人的查询为其他人锁定数据库。我知道这不是问题的最终解决方案,但至少它是一个回退,以防查询出现问题。我没有奴隶DB(这只是一个家庭项目)。
我想安排一个脚本来运行,这样做对我来说。我不熟悉Perl或Ruby,我需要在Windows 2008 Server上完成它。我已经研究过创建一个简单的cmd行脚本,但这似乎不可能。我知道目前我可以做这样的事情,但我必须手动完成:
mysqladmin processlist
mysqladmin kill
任何人对我如何做到这一点都有任何想法或例子?
答案 0 :(得分:1)
如果你安装了Wscript - 我认为它应该是 - 你可以试试这个。保存为“somethingorother.vbs”并不时执行。或者您可以使用提供的循环。循环和kill-for-real选项都被评论;在生产服务器上取消注释之前测试脚本。
我认为'mysqladmin processlist'输出的内容(取自我的XP):
+----+------+----------------+----+---------+------+-------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+----------------+----+---------+------+-------+------------------+
| 21 | root | localhost:1648 | | Query | 0 | | show processlist |
+----+------+----------------+----+---------+------+-------+------------------+
所以我们必须删除包含“----”的行和包含“Id | User”的行,剩下的是
| 21 | root | localhost:1648 | | Query | 0 | | show processlist |
我们可以通过管道符号'|'拆分,从0到8得到9个字段:
0 1 2 3 4 5 6 7 8
| 21 | root | localhost:1648 | | Query | 0 | | show processlist |
字段#1是Id,字段#6产生运行时间。
Option Explicit
Dim objShell, objWshScriptExec, objStdOut, strLine
Dim id, fields, rt, Killer, KillRun
' While True
' WScript.Sleep 150000
Set objShell = CreateObject("WScript.Shell")
Set objWshScriptExec = objShell.Exec("mysqladmin processlist")
Set objStdOut = objWshScriptExec.StdOut
While Not objStdOut.AtEndOfStream
strLine = objStdOut.ReadLine
If (InStr(strLine, "----") = 0 and InStr(strLine, "| Id | User |") = 0) Then
fields = Split(strLine, "|")
id = trim(fields(1))
rt = trim(fields(6))
If rt > 150 Then
' Set Killer = CreateObject("WScript.Shell")
' Set KillRun = objShell.Exec("mysqladmin kill " & id)
echo
End If
End If
Wend
' Wend
答案 1 :(得分:0)
这是我最终使用的最终脚本。感谢Iserni的初步回答,帮助我达到了这一点!
我最终从一个调用csript.exe的.bat文件启动它,因为我可以将消息输出到命令行控制台(而不是消息框)。如果要输出到文本文件,也可以添加它,只需确保启动具有完全管理员UAC访问权限的.bat文件。这是.bat文件包含的内容:
C:\Windows\System32\cscript.exe "C:\Program Files\MySQL\MySQL Server 5.6\bin\kill-slow-queries.vbs"
以下是.vbs文件的内容:
Option Explicit
Dim objShell, objWshScriptExec, objStdOut, strLine, fields
Dim id, rt, Killer, KillRun
While True
WScript.Sleep 10000
Set objShell = CreateObject("WScript.Shell")
Set objWshScriptExec = objShell.Exec("C:\Program Files\MySQL\MySQL Server 5.6\bin\mysqladmin processlist -u root -pMYPASSWORD")
Set objStdOut = objWshScriptExec.StdOut
On Error Resume Next
While Not objStdOut.AtEndOfStream
strLine = objStdOut.ReadLine
If InStr(strLine, "| 1") > 0 or InStr(strLine, "| 2") > 0 or InStr(strLine, "| 3") > 0 or InStr(strLine, "| 4") > 0 or InStr(strLine, "| 5") > 0 or InStr(strLine, "| 6") > 0 or InStr(strLine, "| 7") > 0 or InStr(strLine, "| 8") > 0 or InStr(strLine, "| 9") > 0 Then
fields = Split(strLine, "|")
id = trim(fields(1))
rt = trim(fields(6))
If rt = "" Then
rt = 0
End If
WScript.Echo "ID: " + id + " Time: " + rt
If rt > 80 Then
Set Killer = CreateObject("WScript.Shell")
Set KillRun = objShell.Exec("C:\Program Files\MySQL\MySQL Server 5.6\bin\mysqladmin kill " + id + " -u root -pMYPASSWORD")
WScript.Echo "Killed ID: " + id
End If
End If
Wend
WScript.Echo ""
WScript.Echo ""
Wend
我有一个检查每个Integer的If语句的原因是因为它保证了与进程的ID号完全匹配。除了这九个选项之外的任何其他内容都将失败,并且您永远不知道可以包含哪些进程列表,因此比抱歉更安全。