2011-08-16 35 views
1

我正在創建一個自定義查詢生成器,當用戶創建了他的查詢時,他可以通過單擊按鈕驗證查詢語法。當用戶點擊按鈕進行驗證時,一個AJAX調用會被髮送到服務器並且查詢開始執行,在此期間用戶可以通過取消按鈕在屏幕上看到一個模式。如果任何機會用戶點擊取消按鈕,我希望發送另一個AJAX調用服務器來終止查詢的執行。在使用PHP和AJAX執行期間殺死MySQL查詢

目前我只能殺死AJAX調用,它本來我送,我的網頁能正常工作,在用戶端

但我要尋找一個PHP代碼停止在服務器端的MySQL查詢,因爲一些查詢可以相當重並且運行很長時間

+0

好吧,不知道它有什麼用處,但是如果你的db用戶允許這樣做,你可以發出'kill * process_id *'命令。但是,你必須以某種方式知道* PROCESS_ID *,除非你執行一些骯髒的把戲,比如追加* USER_ID *爲每個SQL或類似的東西評論這是不可能的。是的,這可能是不安全的,你可能會終止其他用戶啓動的連接或者造成其他安全隱患。 – J0HN

+0

的phpmyadmin做它...它應該是可能的... – Catalin

回答

3

首先,如果查詢的目的只是檢查語法,不要執行它!執行解釋或添加限制0,或針對空數據庫執行。

至於查殺,你必須連接到具有root權限的數據庫,併發出KILL命令(但你需要知道查詢ID)。或者你可以殺死整個線程。看看到mysqli::kill

編輯:看來你並不需要root權限,由您的用戶,使用SHOW PROCESSLIST命令

+0

我已經使用限制1,但我只是想尋找一種方式實際上殺害查詢,從來沒有,我會繼續使用它:) 一個少問題雖然..是否有限制1或限制0之間的任何區別? –

+1

與LIMIT 0一樣,MySQL不會實際執行查詢(優化器將不可能實現where子句),並且實際上不會從磁盤讀取任何行。以任何方式也不會慢則限制1,它只能是快:)有多快 - 最好檢查一下,因爲它取決於很多條件 –

0

不可能,因爲每當執行結束時關閉連接。有沒有辦法(通過PHP)來控制舊的「會話」(連接)

1

我相信,通過THREAD_ID報道CONNECTION_ID()看到查詢是一樣的使用線程ID在mysqladmin ....

你需要捕捉啓動查詢之前連接的進程ID ...

$qry="SELECT CONNECTION_ID() AS c"; 
$row=mysql_fetch_assoc(mysql_query($qry)); 
$_SESSION['mysql_connection_id']=$row['c']; 

那麼當用戶點擊這個按鈕做somethi NG像....

exec('mysqladmin -u $user -p$password killproc ' 
      . $_SESSION['mysql_connection_id']); 

但是這開啓了用戶查殺其他人的查詢的可能性。您可以注入評論鍵,例如php會話ID,在每個查詢的開始處(mysqladmin截斷查詢的文本),然後使用mysqladmin processlist檢查所有權和/或檢索線程ID,然後將其殺死。

+0

謝謝,但我不能查殺的完整過程它的風險只是一個額外的要求,所以我想看看是否有一個簡單的方法來做到這一點。 –

+0

呃?線程是永遠只能去運行查詢的一個實例 - 風險是後續請求可以使用相同的thread_id創建一個線程。你不是「殺死....進程」,而是要求mysqld終止查詢。 – symcbean

+0

嗯..有趣..我會仔細看看代碼 thanx :) –

0

您必須允許應用程序終止數據庫查詢,並且需要在客戶端和服務器之間實現更復雜的交互,否則可能導致安全漏洞。

Start-Request應該包含一個會話和一個頁面ID(安全ID,所以不是3和4和5,但是是一種不可猜測但是獨特的某種類型的散列)。後端然後將此ID與查詢連接起來。這可以在數據庫的某個額外表格中完成,或者如果您有redis,也可以通過redis-way完成,但也可以通過SQL查詢中的註釋來完成,例如「Session fid98a08u4j,Page 940jfmkvlz」=>s:<session>p:<page>

/* s:fid98a08u4jp:940jfmkvlz */ select * from ... 

如果用戶按下「取消」,則向服務器發送帶會話和頁面ID的取消請求。然後,php代碼使用show processlist獲取正在運行的SQL查詢的列表,並搜索會話和頁面以提取查詢ID。

那麼php發送

kill query <id> 

到MySQL的服務器。

這可能會導致不使用事務時出現問題,這可能會損壞複製。甚至一個kill query可能需要一段時間的國家'殺害'。

所以這應該是幾個變種的最後可能。但有時候需要完成,我甚至曾經有一個程序可以列出你自己的正在運行的查詢來殺死它們,這是因爲「配額」而需要的(你不能同時運行兩個或三個報告請求)。