Mysql

中斷查詢發送錯誤的執行緒 ID

  • September 6, 2019

在 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,因此存在一個難題。也許那個冗長的變更日誌中的一些細節說明了一些有用的東西。

引用自:https://dba.stackexchange.com/questions/186545