1. 程式人生 > >MySQL 5.7怎麽爬出暫時表空間的坑

MySQL 5.7怎麽爬出暫時表空間的坑

comm ace borde track strong trac style 保持 tex

版權聲明:本文為博主原創文章。未經博主同意不得轉載。 https://blog.csdn.net/n88Lpo/article/details/78126267

導讀

怎樣確認暫時表是由哪個用戶連接創建的?

上次我們介紹了MySQL 5.7暫時表空間怎麽玩才幹不掉坑裏,這次我們來介紹怎樣確認是哪個用戶連接創建的暫時表。以及怎樣釋放暫時表。

首先,我們查看當前的連接ID:

[email protected]>SELECT CONNECTION_ID();
+-----------------+
| CONNECTION_ID() |
+-----------------+
|            2470 |
+-----------------+

在當前會話中創建暫時表:

[email protected] [test]>create temporary table tmp1
select * from I_S.global_status;

備註:上面的I_S是information_schema的簡寫。下同。

馬上查看暫時表信息:

[email protected] [test]>select TABLE_ID, NAME from
I_S.innodb_temp_table_info; +----------+-----------------------+
| TABLE_ID | NAME |
+----------+-----------------------+
| 505 | #sql17ab5_4000003a6_4 |
+----------+-----------------------+

我們觀察到 NAME 列的值是 #sql17ab5_4000003a6_4,它由3部分構成:

  1. 第1部分,由“#sql”字符串開始,並加上隨機值。

  2. 第2部分,一串”疑似”16進制字符。

  3. 第3部分,單調遞增的數值;

這當中的第2部分,我們註意到是“疑似”16進制,我們把“3a6“從16進制轉成10進制試試看:

[email protected] [test]>select conv(‘3a6‘, 16, 10);
+---------------------+
| conv(‘3a6‘, 16, 10) |
+---------------------+
| 934                 |
+---------------------+

能夠看到,正好和當前的連接ID是一樣的,這證實了我們的設想。

我手上有兩個MySQL 5.7版本號,以下是多次、不定時創建暫時表的整個觀察過程記錄。

首先是Linux系統下的5.7.18版本號:

Server version:    5.7.18-log MySQL Community Server (GPL)

[email protected][test]> select connection_id();
+-----------------+
| connection_id() |
+-----------------+
|            1737 |
+-----------------+

[email protected][test]> select conv(1737, 10 ,16);
+--------------------+
| conv(1737, 10 ,16) |
+--------------------+
| 6C9                |
+--------------------+

[email protected][test]> select TABLE_ID, NAME from
I_S.innodb_temp_table_info where NAME like ‘%6C9%’;

+----------+----------------+
| TABLE_ID | NAME |
+----------+----------------+
| 121 | #sql7e95_6c9_5 |
| 120 | #sql7e95_6c9_4 |
| 119 | #sql7e95_6c9_3 |
| 118 | #sql7e95_6c9_2 |
+----------+----------------+

以及Mac系統下的MySQL 5.7.16版本號:

Server version:    5.7.16-log MySQL Community Server (GPL)


[email protected][test]> select connection_id();
+-----------------+
| connection_id() |
+-----------------+
|            934  |
+-----------------+

[email protected][test]> select conv(934, 10 ,16);
+--------------------+
| conv(1737, 10 ,16) |
+--------------------+
| 3A6                |
+--------------------+

[email protected][test]> select TABLE_ID, NAME from
I_S.innodb_temp_table_info where NAME like ‘%3A6%’; +----------+-------------------------+ | TABLE_ID | NAME | +----------+-------------------------+ | 518 | #sql17ab5_31000003a6_31 | | 517 | #sql17ab5_29000003a6_29 | | 516 | #sql17ab5_26000003a6_26 | | 515 | #sql17ab5_23000003a6_23 | | 514 | #sql17ab5_1e000003a6_1e | | 513 | #sql17ab5_1b000003a6_1b | | 512 | #sql17ab5_18000003a6_18 | | 511 | #sql17ab5_16000003a6_16 | | 510 | #sql17ab5_14000003a6_14 | | 509 | #sql17ab5_12000003a6_12 | | 508 | #sql17ab5_10000003a6_10 | | 507 | #sql17ab5_d000003a6_d | | 506 | #sql17ab5_a000003a6_a | | 505 | #sql17ab5_4000003a6_4 | +----------+-------------------------+

從這個結果能看到暫時表的 NAME 的第三部分數值在兩個版本號中的表現不一樣。

  • 在5.7.16版本號上,盡管也是單調遞增,但並非順序的,而是有跳躍,跳躍規則未知;

  • 在5.7.18版本號上,在保持單調遞增的基礎上,每次值都是順序增長的。未跳躍,這個規則看起來更合理些。

好了,如今我們知道僅僅要依據當前的用戶連接ID。就能找到該會話裏創建的全部暫時表。想要釋放這些暫時表。僅僅須要查詢 I_S.INNODB_TEMP_TABLE_INFO 表的 NAME 列值全部包括當前用戶連接ID的記錄。殺掉相應的用戶連接ID就可以(註意:這會釋放該用戶連接創建的全部暫時表)。

MySQL 5.7怎麽爬出暫時表空間的坑