中斷查詢發送錯誤的執行緒 ID
在 MySQL 命令行客戶端 (Linux) 中,當我通過按
CTRL
+來終止查詢時,c
這通常可以正常工作。mysql (slave) > select sleep(5); ^CCtrl-C -- sending "KILL QUERY 117920686" to server ... Ctrl-C -- query aborted. +----------+ | sleep(5) | +----------+ +----------+ 1 row in set (0.78 sec)
但是,當我在我的實時主伺服器上執行相同操作時(在所有伺服器中,它必須是這個……)它以某種方式發送了錯誤的執行緒 ID。
mysql (master) > select sleep(5); ^CCtrl-C -- sending "KILL QUERY 770543254" to server ... Ctrl-C -- query aborted. +----------+ | sleep(5) | +----------+ +----------+ 1 row in set (5.00 sec) /* <- it obviously hasn't aborted at all */
ID太低了 其他執行緒的 ID 為 26534760326。所有伺服器的版本相同:
# yum list installed mysql* Loaded plugins: dellsysid, rhnplugin, security, ulninfo This system is receiving updates from RHN Classic or Red Hat Satellite. Installed Packages MySQL-python.x86_64 1.2.3-0.3.c1.1.el6 @public_ol6_latest mysql-community-client.x86_64 5.6.27-2.el6 @mysql56-community mysql-community-common.x86_64 5.6.27-2.el6 @mysql56-community mysql-community-libs.x86_64 5.6.27-2.el6 @mysql56-community mysql-community-libs-compat.x86_64 5.6.27-2.el6 @mysql56-community mysql-community-release.noarch el6-5 @/mysql-community-release-el6-5.noarch mysql-community-server.x86_64 5.6.27-2.el6 @mysql56-community
附加資訊:
然而,該
connection_id()
函式返回正確的值。root@ods01:(none) > select connection_id(); +-----------------+ | connection_id() | +-----------------+ | 26542310314 | +-----------------+ 1 row in set (0.00 sec) root@ods01:(none) > select sleep(5); ^CCtrl-C -- sending "KILL QUERY 772506538" to server ... Ctrl-C -- query aborted. +----------+ | sleep(5) | +----------+ +----------+ 1 row in set (5.00 sec)
有誰知道如何解決這一問題?
寫一個錯誤報告! http://bugs.mysql.com。
26542310314 MOD 2^32 = 772506538
也就是說,將 64 位的 connection_id 切成 32 位以發送 KILL,從而將其發送到錯誤的 id。
沒有多少使用者超過 40 億個連接。你的伺服器上線多久了?我希望程式碼不會為每個查詢重新連接。
更改日誌
—– 2014-09-25 5.7.5 里程碑 15 – 錯誤修復 – —–
連接 ID 是 32 位無符號整數,從 1 開始。當伺服器分配連接 ID 並達到 32 位範圍的頂部時,它會將值翻轉以再次從 1 開始。如果舊執行緒執行時間特別長,伺服器可能會將連接 ID 分配給新執行緒,而該 ID 仍由現有執行緒使用。對於這種情況,對 ID 的引用變得不明確。例如,不能可靠地確定KILL connection_id要殺死哪個執行緒,這可能導致未定義的行為。此行為已得到糾正,因此使用中的 ID 不會被重複使用。連接 ID 是 32 位無符號整數,從 1 開始。當伺服器分配連接 ID 並達到 32 位範圍的頂部時,它會將值翻轉以再次從 1 開始。如果舊執行緒執行時間特別長,伺服器可能會將連接 ID 分配給新執行緒,而該 ID 仍由現有執行緒使用。對於這種情況,對 ID 的引用變得不明確。例如,不能可靠地確定KILL connection_id要殺死哪個執行緒,這可能導致未定義的行為。此行為已得到糾正,因此使用中的 ID 不會被重複使用。
—– 2012-12-11 5.6.9 候選版本 – 已修復的錯誤 – 不兼容的更改 —–
在某些系統(例如繁忙或長時間執行的 64 位系統)上,可能會出現大於 32 位的連接 ID(執行緒 ID)值,從而導致以下問題:
寫入一般查詢日誌和慢查詢日誌的連接 ID 不正確。這對於記錄到文件和表都是正確的。
對於
大於 32 位的值,CONNECTION_ID()函式可能會返回一個數據類型太小的值。
mysql_thread_id () 和 mysql_kill() C API 函式不處理大於 32 位的 ID 值。這可能會導致殺死錯誤的執行緒;例如,如果您呼叫了 mysql_kill(mysql_thread_id())。
當伺服器支持連接 ID(使用 64 位數據類型建構時)時,現在允許連接 ID 為 64 位值,這具有以下效果:
連接 ID 被正確記錄到一般查詢日誌和慢查詢日誌中。
注意此更改涉及對日誌表的修改,因此升級到此版本後,您必須執行 mysql_upgrade 並重新啟動伺服器。
CONNECTION_ID() 返回適用於大於 32 位的值的數據類型。
mysql_thread_id() 不變;客戶端/伺服器協議的 ID 值只有 4 個字節。對於大於 32 位的連接 ID,此函式返回錯誤(截斷)值,應避免使用。
mysql_kill() 仍然無法處理大於 32 位的值,但為了防止殺死錯誤的執行緒,現在在這些情況下會返回錯誤:
如果給定一個大於 32 位的 ID, mysql_kill() 返回一個 CR_INVALID_CONN_HANDLE 錯誤。
在伺服器的內部執行緒 ID 計數器達到大於 32 位的值後,它 會 為任何 mysql_kill() 呼叫 返回ER_DATA_OUT_OF_RANGE錯誤,並且mysql_kill() 失敗。
為避免 mysql_thread_id() 和 mysql_kill()出現問題,請不要使用它們。要獲取連接 ID,請執行 SELECT CONNECTION_ID() 查詢並檢索結果。要終止執行緒,請執行 KILL 語句。
(錯誤 #19806、錯誤 #11745768、錯誤 #65715、錯誤 #14236124、錯誤 #44728、錯誤 #11753308)
(小的 bug 編號可以在 bugs.mysql.com 上找到;大的 bug 編號是無法訪問的 - Oracle 內部的。)
因此,建議您升級到 5.6.9+ 或 5.7.5+。由於您使用的是 5.6.27,因此存在一個難題。也許那個冗長的變更日誌中的一些細節說明了一些有用的東西。