Hi,你們好!我是白日夢!本文是MySQL專題的第 24 篇。web
今天我要跟你分享的MySQL話題是:「從一條update sql執行都經歷什麼開始,發散開一系列的問題,看看你能抗到第幾問吧」面試
換一種寫做風格,自導自演面試現場!感受這樣仍是比較有趣的,歡迎你們訂閱個人MySQL專題,公衆號首發!持續更新中~
sql
歡迎關注白日夢,公衆號首發!持續連載中後端
Hi同窗,據說你上一面表現的還能夠,這一面要不咱繼續? 緩存
嗯,好啊! 網絡
好,你說一下一條update sql的執行,都經歷了哪些階段吧
多線程
我能夠畫一張簡圖,而後咱們一塊兒看一下這張腦圖吧
你能夠花幾秒看下這個圖哦
嗯,你繼續!
通常在咱們的後端系統中,和數據庫打交道都邏輯都放在DAO層,DAO層的持久化框架中封裝了:數據驅動(Driver),SQL語句通常也都是由DAO層的持久化框架發送給數據庫的。
嗯,那你說的DAO層就是上圖中的客戶端了吧
可是我看你的簡圖,貌似是把數據庫劃分紅兩部分,Server層和InnoDB層。你說說看!
是的,一般你們會把數據庫分層兩部分,上層的Server層和下層的存儲引擎層。
總的來看:Server層主要是負責和客戶端創建網絡鏈接,接受客戶端傳遞過來的SQL、預處理、由執行器發送給儲存引擎執行。
而存儲引擎會和操做系統的文件系統打交道。
我在圖中畫的存儲引擎層是InnoDB,MySQL不止這一種執行引擎,對於MySQL來講存儲引擎是可插拔的。
常見的還有什麼MyISAM、NDB、Memory等等。
嗯,你說的沒錯!那若是我讓你寫一個MySQL的Server層。
你有什麼思路嗎?說說看!
我.....
有思路,下面我用大白話簡單描述一下:
你知道的!MySQL被吹的再神,本質上不過是個軟件而已,並且Server層的功能相對來講比較簡單,主要就是接受客戶端的鏈接,拿到網絡包中的SQL語句,而後處理......
而且它是單進程多線程的軟件,一般會佔用3306端口啓動,那我徹底能夠一比一寫出一個MySQL Server層嘛!
好比我能夠用熟悉的編程語言,TCP編程,寫個TCP - Server端,監聽3306端口啓動。而後從接收到的數據包中取出數據,按照MySQL協議解析數據,獲得SQL語句。再處理SQL語句就是了!
嗯!(我猜這傢伙確定對某個數據庫中間件特別熟悉)
回到正題,繼續說update sql如何被處理。
好,咱們的應用程序把SQL發送給Server層後,SQL會陸續被分析器、優化器、執行器處理。
另外在圖中你能看到:查詢緩存。這個查詢緩存由Server層維護,它設計的初衷就是在內存中暫存原來查詢的結果。以便下次查詢時能夠快速獲得結果^_^
可是它有個缺點就是當有對該表的更新操做時,該表的查詢緩存會被廢棄。因此MySQL8中將查詢緩存砍掉了。
嗯,繼續。
嗯嗯,那我繼續往下說。
分析器的做用:對SQL進行語法、詞法上的分析。
優化器的做用:生成執行計劃、選擇索引。
執行器的做用:操做執行引擎,獲取SQL的執行結果。
嗯,剛纔你還說你能夠寫個MySQL的Server層,那我如今就讓你實現這個分析器!
task is cheap,show me the code!
,能夠下看面的Case。
好,這個話題過
。
你繼續往下說。
咱們的update sql通過server層的分析檢測以後,最終由執行器交由存儲引擎執行。
由於InnoDB是支持事務的,而咱們如今是update類型的SQL,因此會被放在一個單獨的事務中去執行。
爲了提供事務回滾的能力,因而有了上圖中的第5步,InnoDB存儲引擎會先寫undo log。
寫完undo log以後,總體的執行流程會來到圖中的第6步。
在BufferPool緩存池中對內存中的數據進行update。
Buffer Pool緩存池?那我得問下
這個Buffer Pool緩存池是啥?
另外我看你上圖中的Server層也有一個查詢緩存呀,它和BufferPool緩存池啥區別?
嗯,是這樣的。 首先咱們都知道,MySQL是支持持久化的,數據最終都落在磁盤上。
可是若是全部的update sql 都直接、大量、頻繁的進行IO磁盤操做,會致使MySQL總體的性能極具降低。
如今MySQL實現方式是:它在內存中對數據進行CRUD,因此在圖中能夠看到,BufferPool中的數據是從磁盤上讀進去的。
小夥子能夠!繼續說!
當update sql修改完內存中的數據後,接下來就是提交事務了。提交事務的方式通常都是兩階段提交。
也就是:
一、先寫redo log(prepare)
二、寫binlog
三、寫redo log (commit)
這些日誌後續也都會有必定的機制控制把它們持久化到磁盤中。
那你說一下redo log、bin log分別給了MySQL什麼能力吧
記錄binlog可使MySQL就擁有:搭建集羣、數據備份、數據恢復、審計的能力啊
寫redolog後MySQL就擁有了崩潰恢復的能力。
嗯,那你是怎麼理解這個binlog的數據恢復和redolog的崩潰恢復的呢?
binlog 有redolog 崩潰恢復的能力嘛?
嗯~,我是這樣理解的:binlog由MySQL的上層也就是Server層記錄。
能夠看下這張圖:截自部分binlog
能夠看到binlog中記錄的是sql語句,記錄這你對哪張表的id=xx的行作了什麼樣的修改。
而redolog中記錄的是物理層面的概念。好比redo log中會記錄你對xxx表空間的XXX數據頁xxx偏移量的地方作了XXX更新。
因此說,binlog的數據恢復和redo log的崩潰恢復實際上是發生在兩個層面的,徹底是兩碼事的!
就像是上圖那樣,binlog的中不是記錄着SQL嗎?因此能夠把藉助binlog的實現的數據恢復理解成回放binlog中的SQL。
而redolog的崩潰恢復指的是當MySQL出現異常Crash重啓後,將內存中數據恢復成崩潰前的髒數據
嗯!瞭解,總體上看你的回答的還能夠!
我沒有問題了,你還有什麼想問個人嗎?
沒有問題了,感謝大佬百忙抽空來給我面試!
哈哈,客氣!你應該會進入下一面的。好好準備,期待你下一面優秀的表現
換一種寫做風格,自導自演面試現場!感受這樣仍是比較有趣的,歡迎你們訂閱個人MySQL專題,公衆號首發!持續更新中~