<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
今天我們就從這個問題說起:臨時表有哪些特徵,適合哪些場景?
這裡,我需要先幫你釐清一個容易誤解的問題:有的人可能會認為,臨時表就是記憶體表。但是,這兩個概念可是完全不同的。
弄清楚了記憶體表和臨時表的區別以後,我們再來看看臨時表有哪些特徵。
為了便於理解,我們來看下下面這個操作序列:
可以看到,臨時表在使用上有以下幾個特點:
由於臨時表只能被建立它的session存取,所以在這個session結束的時候,會自動刪除臨時表。
也正是由於這個特性,臨時表就特別適合上篇文章中join優化這種場景。為什麼呢? 原因主要包括以下兩個方面:
由於不用擔心執行緒之間的重名衝突,臨時表經常會被用在複雜查詢的優化過程中。其中,分庫分表系統的跨庫查詢就是一個典型的使用場景。
一般分庫分表的場景,就是要把一個邏輯上的大表分散到不同的資料庫範例上。比如。將一個大表ht,按照欄位f,拆分成1024個分表,然後分佈到32個資料庫範例上。如下圖所示:
一般情況下,這種分庫分表系統都有一箇中間層proxy。不過,也有一些方案會讓使用者端直接連線資料庫,也就是沒有proxy這一層。
在這個架構中,分割區key的選擇是以“減少跨庫和跨表查詢”為依據的。如果大部分的語句都會包含f的等值條件,那麼就要用f做分割區鍵。這樣,在proxy這一層解析完SQL語句以後,就能確定將這條語句路由到哪個分表做查詢。
比如下面這條語句:
select v from ht where f=N;
這時,我們就可以通過分表規則(比如,N%1024)來確認需要的資料被放在了哪個分表上。這種語句只需要存取一個分表,是分庫分表方案最歡迎的語句形式了。
但是,如果這個表上還有另外一個索引k,並且查詢語句是這樣的:
select v from ht where k >= M order by t_modified desc limit 100;
這時候,由於查詢條件裡面沒有用到分割區欄位f,只能到所有的分割區中去查詢滿足條件的所有行,然後統一做order by的操作。這種情況下,有兩種比較常用的思路。
第一種思路是,在proxy層的程序程式碼中實現排序。 這種方式的優勢是處理速度快,拿到分庫的資料以後,直接在記憶體中參與計算。不過,這個方案的缺點也比較明顯:
另一種思路就是,把各個分庫拿到的資料,彙總到一個MySQL範例的一個表中,然後在這個彙總範例上做邏輯操作。
比如上面這條語句,執行流程可以類似這樣:
select v,k,t_modified from ht_x where k >= M order by t_modified desc limit 100;
select v from temp_ht order by t_modified desc limit 100;
得到結果。 這個過程對應的流程圖如下所示:
在實踐中,我們往往會發現每個分庫的計算量都不飽和,所以會直接把臨時表temp_ht放到32個分庫中的某一個上。
你可能會問,不同執行緒可以建立同名的臨時表,這是怎麼做到的呢?
我們在執行
create temporary table temp_t(id int primary key)engine=innodb;
這個語句的時候,MySQL要給這個InnoDB表建立一個frm檔案儲存表結構定義,還要有地方儲存表資料。
這個frm檔案放在臨時檔案目錄下,檔名的字尾是.frm,字首是“#sql{程序id}_ {執行緒id}_ 序列號”。
從檔名的字首規則,我們可以看到,其實建立一個叫作t1的InnoDB臨時表,MySQL在儲存上認為我們建立的表名跟普通表t1是不同的,因此同一個庫下面已經有普通表t1的情況下,還是可以再建立一個臨時表t1的。
先來舉一個例子。
這個程序的程序號是1234,session A的執行緒id是4,session B的執行緒id是5。所以你看到了,session A和session B建立的臨時表,在磁碟上的檔案不會重名。
MySQL維護資料表,除了物理上要有檔案外,記憶體裡面也有一套機制區別不同的表,每個表都對應一個table_def_key。
也就是說,session A和session B建立的兩個臨時表t1,它們的table_def_key不同,磁碟檔名也不同,因此可以並存。
在實現上,每個執行緒都維護了自己的臨時表連結串列。這樣每次session內操作表的時候,先遍歷連結串列,檢查是否有這個名字的臨時表,如果有就優先操作臨時表,如果沒有再操作普通表;在session結束的時候,對連結串列裡的每個臨時表,執行 “DROPTEMPORARY TABLE +表名”操作。
這時候你會發現,binlog中也記錄了DROPTEMPORARY TABLE這條命令。你一定會覺得奇怪,臨時表只線上程內自己可以存取,為什麼需要寫到binlog裡面?這,就需要說到主備複製了。
既然寫binlog,就意味著備庫需要。 你可以設想一下,在主庫上執行下面這個語句序列:
create table t_normal(id int primary key, c int)engine=innodb;/*Q1*/ create temporary table temp_t like t_normal;/*Q2*/ insert into temp_t values(1,1);/*Q3*/ insert into t_normal select * from temp_t;/*Q4*/
如果關於臨時表的操作都不記錄,那麼在備庫就只有create table t_normal表和insert intot_normal select * fromtemp_t這兩個語句的binlog紀錄檔,備庫在執行到insert into t_normal的時候,就會報錯“表temp_t不存在”。
你可能會說,如果把binlog設定為row格式就好了吧?因為binlog是row格式時,在記錄insert intot_normal的binlog時,記錄的是這個操作的資料,即:write_rowevent裡面記錄的邏輯是“插入一行資料(1,1)”。
確實是這樣。如果當前的binlog_format=row,那麼跟臨時表有關的語句,就不會記錄到binlog裡。也就是說,只在binlog_format=statment/mixed的時候,binlog中才會記錄臨時表的操作。
這種情況下,建立臨時表的語句會傳到備庫執行,因此備庫的同步執行緒就會建立這個臨時表。主庫線上程退出的時候,會自動刪除臨時表,但是備庫同步執行緒是持續在執行的。所以,這時候我們就需要在主庫上再寫一個DROPTEMPORARY TABLE傳給備庫執行。
現在,我給你舉個例子,下面的序列中範例S是M的備庫。
主庫M上的兩個session建立了同名的臨時表t1,這兩個create temporary table t1 語句都會被傳到備庫S上。
但是,備庫的應用紀錄檔執行緒是共用的,也就是說要在應用執行緒裡面先後執行這個create 語句兩次。(即使開了多執行緒複製,也可能被分配到從庫的同一個worker中執行)。那麼,這會不會導致同步執行緒報錯?
顯然是不會的,否則臨時表就是一個bug了。也就是說,備庫執行緒在執行的時候,要把這兩個t1表當做兩個不同的臨時表來處理。這,又是怎麼實現的呢? MySQL在記錄binlog的時候,會把主庫執行這個語句的執行緒id寫到binlog中。這樣,在備庫的應用執行緒就能夠知道執行每個語句的主庫執行緒id,並利用這個執行緒id來構造臨時表的table_def_key:
由於table_def_key不同,所以這兩個表在備庫的應用執行緒裡面是不會衝突的。
到此這篇關於MySQL為什麼臨時表可以重名的文章就介紹到這了,更多相關MySQL臨時表重名內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45