MySQL的臨時表

內(nèi)存表與臨時表的區(qū)別

  • 內(nèi)存表,指的是使用 Memory 引擎的表,建表語法是 create table … engine=memory。這種表的數(shù)據(jù)都保存在內(nèi)存里,系統(tǒng)重啟的時候會被清空,但是表結(jié)構(gòu)還在。除了這兩個特性看上去比較“奇怪”外,從其他的特征上看,它就是一個正常的表。
  • 臨時表,可以使用各種引擎類型 。如果是使用 InnoDB 引擎或者 MyISAM 引擎的臨時表,寫數(shù)據(jù)的時候是寫到磁盤上的。臨時表也可以使用 Memory 引擎。

臨時表的特性

  • 建表語法是 create temporary table …。
  • 一個臨時表只能被創(chuàng)建它的 session 訪問,對其他線程不可見。


所以,圖中 session A 創(chuàng)建的臨時表 t,對于 session B 就是不可見的。

  • 臨時表可以與普通表同名。session A 內(nèi)有同名的臨時表和普通表的時候,show create 語句,以及增刪改查語句訪問的是臨時表。
  • show tables 命令不顯示臨時表。

由于臨時表只能被創(chuàng)建它的 session 訪問,所以在這個 session 結(jié)束的時候,會自動刪除臨時表。也正是由于這個特性,臨時表就特別適合我們文章開頭的 join 優(yōu)化這種場景。為什么呢?

原因主要包括以下兩個方面:

  • 不同 session 的臨時表是可以重名的,如果有多個 session 同時執(zhí)行 join 優(yōu)化,不需要擔(dān)心表名重復(fù)導(dǎo)致建表失敗的問題。
  • 不需要擔(dān)心數(shù)據(jù)刪除問題。如果使用普通表,在流程執(zhí)行過程中客戶端發(fā)生了異常斷開,或者數(shù)據(jù)庫發(fā)生異常重啟,還需要專門來清理中間過程中生成的數(shù)據(jù)表。而臨時表由于會自動回收,所以不需要這個額外的操作。

臨時表為什么可以重名

MySQL 維護(hù)數(shù)據(jù)表,除了物理上要有文件外,內(nèi)存里面也有一套機(jī)制區(qū)別不同的表,每個表都對應(yīng)一個 table_def_key。

  • 一個普通表的 table_def_key 的值是由“庫名 + 表名”得到的,所以如果你要在同一個庫下創(chuàng)建兩個同名的普通表,創(chuàng)建第二個表的過程中就會發(fā)現(xiàn) table_def_key 已經(jīng)存在了。

  • 而對于臨時表,table_def_key 在“庫名 + 表名”基礎(chǔ)上,又加入了“server_id+thread_id”。

也就是說,session A 和 sessionB 創(chuàng)建的兩個臨時表 t1,它們的 table_def_key 不同,磁盤文件名也不同,因此可以并存。

在實現(xiàn)上,每個線程都維護(hù)了自己的臨時表鏈表。這樣每次 session 內(nèi)操作表的時候,先遍歷鏈表,檢查是否有這個名字的臨時表,如果有就優(yōu)先操作臨時表,如果沒有再操作普通表;在 session 結(jié)束的時候,對鏈表里的每個臨時表,執(zhí)行 “DROP TEMPORARY TABLE + 表名”操作。

備庫執(zhí)行怎么處理主庫上不同的線程創(chuàng)建同名的臨時表

主庫 M 上的兩個 session 創(chuàng)建了同名的臨時表 t1,這兩個 create temporary table t1 語句都會被傳到備庫 S 上。

備庫線程在執(zhí)行的時候,要把這兩個 t1 表當(dāng)做兩個不同的臨時表來處理。

MySQL 在記錄 binlog 的時候,會把主庫執(zhí)行這個語句的線程 id 寫到 binlog 中。這樣,在備庫的應(yīng)用線程就能夠知道執(zhí)行每個語句的主庫線程 id,并利用這個線程 id 來構(gòu)造臨時表的 table_def_key:

  • session A 的臨時表 t1,在備庫的 table_def_key 就是:庫名 +t1+“M 的 serverid”+“session A 的 thread_id”;
  • session B 的臨時表 t1,在備庫的 table_def_key 就是 :庫名 +t1+“M 的 serverid”+“session B 的 thread_id”。

由于 table_def_key 不同,所以這兩個表在備庫的應(yīng)用線程里面是不會沖突的。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容