面試官:什麼是大事務?小林哥:就是 很大…的…事務??
最近疫情期間跳槽不易,在外包公司工作了5年的小林在某直聘軟體上邊投遞了好幾家互聯網公司的java工程師崗位。在經歷了快半年的無人問津之後,終於被一家公司的技術leader叫去了面試。
到了南山科技園的某棟大樓地下,看了下時間,距離面試約定時間還有大概15分鐘。小王慢慢悠悠地步入了這棟科技大樓,在前台坐下後,過了不久,面試官便趕來了。
面試官
你好,請自我介紹一下吧。
小林
你好,我是xxxxx
面試官掃了下我的簡歷,發現了簡歷上的一點:熟悉mysql資料庫。這時候面試官笑了笑,彷彿心裡頭在盤算著後邊該怎麼問我這塊的知識點,我背地一涼。
面試官
聊聊你之前做的項目吧,看這上邊的經歷,似乎你寫的很多項目都是有用到過mysql資料庫啊。
小林
嗯嗯,是的,我之前很多的工作經驗都是有用到過mysql資料庫。(心裡暗想:估計接下來要問資料庫的知識點了。)
面試官
那你平時對mysql應該有一定的研究吧,我先簡單問你幾個問題吧。
小林
嗯嗯,可以的。
面試官
我看你簡歷上邊寫了商城的項目,為什麼要用mysql資料庫來存儲數據呢?
小林一開始有點蒙。(怎麼會問這麼奇葩的問題?商品資訊存在mysql不是很正常的操作嗎?)
小林
商品資訊和訂單,用戶等數據都有一定的關聯性,使用關係型資料庫進行數據存儲會比較合適。而且公司早起業務發展的時候就是使用了mysql資料庫,加上市面上mysql資料庫在性能,文檔等方面也比較成熟,哦對了,mysql對外還是開源免費的,綜合這些因素來分析,我覺得使用mysql資料庫是一個比較不錯的選擇。
面試官
嗯嗯,那你在使用mysql存儲數據的時候有遇到過哪些問題呢?
小林
嗯嗯,有的。比如說一些sql查詢的時間特別久。在工作中我也有對其做過一些優化,也有了解過索引的相關知識點。
(嘿嘿,準備問索引知識了吧,我這塊可是準備了很充足的。)
面試官
嗯嗯,那我相信你應該對索引這塊了解比較深入,並且有一定經驗了吧。那你能講下你在使用索引的時候遇到過哪些問題嗎?
小林
嗯嗯,我有用到過覆蓋索引來做一些sql的優化,包括使用一些最左索引前綴的方式進行優化。
面試官
覆蓋索引為何能優化sql查詢效率呢?能講解下嗎?
小林
因為當覆蓋索引生效的時候能夠避免「回表查詢」操作,減少了io查詢的次數。當使用了覆蓋索引當時候,查詢當數據在葉子節點便可以讀取到需要當數值,不需要繼續做「回表查詢」了。
面試官
哦,那是不是如果覆蓋索引沒有生效就一定會觸發回表查詢操作呢?
小林
額。。。不太清楚 (一下子蒙了)
(後來查詢了下資料,回表是因為查詢當數據在主鍵索引裡面才有數據。但是如果資料庫引擎使用了myisam則不需要回表,直接根據對應的葉子地址去查詢數據即可)
面試官
咳咳,沒事我們繼續。你有了解過索引的重建過程嗎?
小林
額。。不太清楚 (漸漸又開始蒙了)
面試官
例如我們在工作中發現某張表的數據量和其存儲的實際數據數目不匹配,這種情況通常是因為刪除了過多的數據,導致表裡面的數據空洞過多佔用導致的,一般會通過命令去壓縮表的體積進行優化。
ps :面試結束後,小林查詢了一些資料,發現有一條sql:alter table t engine=InnoDB 可以用於重建整張表的索引數據,將表裡以前的一些索引空洞給一併壓縮進行重新整合。
假設一棵b+樹(innodb)的起初結構如下圖所示:
圖片
當我們delete from table_a where id=400 的時候,其實id為400的那個位置並不會被刪除,而是會有個標籤記錄,當前位置可以復用。也就是說會變成下圖這種模式:
圖片
此時400的那個位置會空餘出來,但是如果我們新插入的數據,其id並不是400,而是600的時候,就不會復用這個位置了。
圖片
因此有的時候,可能我們表裡的數據即使刪除了一半,體積也反而沒有變化。如果不懂得如何去壓縮這顆樹的話,可能你的磁碟空間就會約佔越大,增加企業在伺服器存儲方面的開銷費用。
當然優化技巧也是有的,可以通過執行 alter table t engine=InnoDB 這樣的一條sql來重新構建整棵樹從而實現索引的壓縮效果。
面試官
好吧,那索引的問題先問這麼多。你應該對innodb也比較了解吧。
小林
嗯嗯,是的。(應該要問innodb和myisam的區別了)
面試官
你了解innodb的背後架構嗎?能說下它內部的執行緒包含了哪些嗎?
小林
額?(這出門前背過,但是不太記得了)
面試官
(引導一下求職者)
innodb背後的執行緒分為了好幾個類型,不同類型的執行緒負責相關的職責工作。
小林
我記得有好幾個執行緒,但是他們的名字記不太清楚了。
ps:後來小林翻查了以前自己整理的筆記,回顧了關於innodb的執行緒知識點。大致整理了一下,如下圖:
圖片
面試官
好吧,那你對事務了解嗎。能講下什麼是大事務嗎?
小林
就是 很大…的…事務??
ps:其實大事務是指運行時間比較長,操作的數據比較多的事務。
這類型的事務容易給資料庫帶來負擔:
鎖定了過多的數據,造成不必要的擁塞堵塞。
在事務執行的過程中需要堵塞容易引起主從數據同步不一致的情況發生。
當我們執行事務的操作過大,例如說delete某張表裡買呢一億條數據的時候,如果加入了事務保護,那麼假設期間出現了異常,整段事務的回滾將會非常消耗機器的性能和耗時。通常可以讓研發將大事務分解為多個小事務進行優化處理。
在mysql的二進位日誌裡面,當多個會話同時訪問server執行事務性sql語句的請求時候,binlog會給每個會話單獨開啟一個執行緒進行事務性sql的快取處理。直至當相應的sql執行完畢之後再寫入到binlog日誌中。
這樣做的好處在於能夠將不同的事物進行分隔出來處理。並且保證每個寫入binlog的事務sql都是完整且正常執行的一個單位。而且如果事務在執行的過程中發生了回滾的話,可以直接在記憶體中間數據刪除,不需要再在日誌裡面進行記錄刪除操作。
面試官
額,好吧。那我們mysql相關的知識點先問到這裡吧。你可以回去等通知了。
小林
我還有機會嗎?……
小林很清楚,自己在以前的工作中過多是偏於crud寫業務方面的內容,對於常用技術的底層原理平時也沒有做過多的整理和總結,也難怪這次面試會失敗。
滴滴滴…. 突然一個陌生的電話響了起來,小林拿起了電話….下一家當面試要開始準備了。