連接配接器
分析器
優化器
執行器
存儲引擎(插件的形式)
前面的四個分别是Server層的元件,後面存儲引擎層是插件,如InnoDB,MyISAM,Memory等
連接配接器的作用主要是維持和用戶端之間的通信功能。同時還負責同用戶端的認證和授權的功能。
每個連接配接在完成認證和授權後就會一直維持一個長連接配接,建立完連接配接的後的所有通信都不需要進行再次進行認證,但每次SQL請求操作都會有權限的認證
在連接配接完成後,如果連接配接長時間沒有SQL請求通信,該連接配接會處于Sleep狀态,直到超過MySQL執行個體配置的<code>wait_timeout</code>參數的時間後,連接配接器會主動斷開該長連接配接。MySQL執行個體預設的<code>wait_timeout</code>的的時間是8小時
分析器的執行分為兩個過程,一個是詞法分析,另一個是文法分析
我們發送的SQL語句是一個字元串,裡面可能存在空格和字元串。詞法分析器的作用就是把這個字元串代表的意思進行資料的格式化,比如<code>SELECT</code>子串辨別這是一個讀請求,<code>FROM t_table</code>表示要操作t_table這張表
文法分析的作用是要對這個文法的正确性做一個檢查,如果目前的SQL文法不符合MySQL的文法,那麼就直接報錯了,不進行下一步的執行
優化器的作用是根據分析器得出的結果再結合目前表資料的儲存情況來的出一個查詢效率最高的執行計劃。常見的情況有“:
同一個SQL語句中存在多個索引列條件,那麼應該先選擇哪個索引先進行查詢
多表join操作的時候,如何選擇哪個表作為驅動表等
上面兩種情況都是優化器等工作職責
執行器的作用就是負責調用底層存儲引擎實作的抽象接口,按照優化器輸出的執行計劃進行執行。執行器才是真正負責執行SQL操作的元件
存儲引擎的作用就是當初MySQL實作的時候留下的可擴充的點,不同的存儲引擎的實作可以有着不同的應用場景。MySQL為存儲引擎定一個統一的抽象接口,隻要不同的存儲引擎實作該抽象接口就能被上層的執行器比如OLTP的場景下需要資料庫事務的支援,那麼InnoDB就是好的選擇。而在需要大量讀請求而寫請求少,并且不需要事物的情況下MyISAM是一個好的選擇
一條SQL的執行就是上面的元件從上到下的執行順序,下面就用MySQL預設的InnoDB引擎進行展開看看InnoDB的執行原理
InnoDB有一個重要的子產品: <code>redo-log</code>,它是InnoDB支援事物的重要子產品。redo-log是實體日志,它記錄了哪一個資料頁上做了什麼修改。可以說如果沒有redo-log,InnoDB就不具有crash-safe的能力
redo-log是由一組分别為4個固定大小檔案組成。可以通過MySQL的參數來指定檔案的大小。作為日志檔案,redo-log是順序寫的,是以寫對磁盤來說是非常高效的。資料的結構可以看成是下面的圖

Check-point是目前的資料擦除指針,辨別了目前redo-log的擦除檔案位置。write-point是寫指針,辨別了目前的資料寫檔案位置。InnoDB要保證的是write-point不能超過check-point。check-point要一直保持在write-point之前的一段距離。
bin-log是MySQL的server層實作的邏輯日志,相當于記錄的SQL語句的操作邏輯。
InnoDB是如何實作crash-safe的呢?一個需要知道的理論就是<code>兩階段送出</code>
兩階段送出用簡單點的話講就是:
先讀取資料,并更新然後将新行資料儲存在記憶體中
将實體更新記錄寫入redo-log,并标記這條記錄為prepare狀态(第一步)
InnoDB将操作送出到執行器,執行器再将邏輯更新記錄寫入bin-log,同時調用引擎的寫入和更新接口将磁盤檔案更新
上一步操作完成後再送出事物,将redo-log中對應的記錄狀态改為commit狀态(第二步)
傳回更新結果
如果在更新或寫入資料的過程中,機器出現崩潰。那麼在機器在重新開機後,MySQL會首先去驗證redolog的完整性,如果redolog中沒有prepare狀态的記錄,則記錄是完整的,就日記送出。如果redolog中存在prepare記錄,那麼就去驗證這條redolog對應的binlog記錄,如果這條binlog是完整的,那麼完整送出redolog,否則執行復原邏輯
沐風的原創文章