MySQL基本架構
MySQL大體能夠分爲Server層和存儲引擎層html
Server層包括鏈接器,查詢緩存,解析器,預處理器,優化器,執行器等,全部跨存儲引擎的功能都在這一層實現,好比存儲過程,觸發器和視圖等mysql
鏈接器
- 負責跟客戶端創建鏈接,獲取權限,維持和管理鏈接
- 用戶名密碼驗證經過後,鏈接器會到權限表中查詢用戶的權限,以後這個連接裏面的權限判斷邏輯,都依賴於此時讀取的權限;即便使用管理員帳號對用戶權限做修改,也不會影響已存在的鏈接的權限
- 參數wait_timeout控制服務器保持與客戶端的空閒鏈接的時長,默認值爲8小時
- 長鏈接積累致使MySQL佔用內存飛漲
- 考慮按期斷開長鏈接
- MySQL5.7之後,執行mysql_reset_connection來從新初始化鏈接資源 (此過程不須要重連和重現驗證權限,可是會將鏈接恢復到剛建立完成的狀態)
MySQL :: MySQL 5.7 Reference Manual :: 27.8.7.60 mysql_reset_connection() dev.mysql.com/doc/refman/…sql
查詢緩存
- 若是查詢剛好命中查詢緩存,那麼查詢不會被解析,執行計劃不會被生成,在返回查詢結果以前,MySQL會檢查用戶的權限
- 對一張表的更新,會致使這張表的查詢緩存被清空(查詢緩存失效頻繁,弊大於利)
- 推薦按需使用查詢緩存
- 設置參數query_cache_type設置成DEMAND,默認狀況下,SQL不使用查詢緩存,經過SQL_CACHE顯示指定使用查詢緩存
select SQL_CACHE * from T where ID = 10;
複製代碼
解析器(作什麼)
- 詞法分析,識別SQL中的字符串是什麼
- 語法分析
- 在詞法分析的基礎上,根據語法規則,判斷SQL是否知足MySQL語法,最後獲得一棵語法樹
- 對於只是參數不一樣,其餘均相同的sql,它們執行時間不一樣但硬解析的時間是相同的;而同一SQL隨着查詢數據的變化,屢次查詢執行時間可能不一樣,但硬解析的時間是不變的
詞法分析 -> 語法分析能夠稱爲硬解析數據庫
預處理器
好比檢查表、數據列是否存在;別名是否有歧義等等緩存
優化器(怎麼作)
- 優化器會將語法樹轉化成執行計劃(能夠生成多個執行計劃),而後找出最合適的執行計劃(成本最少)
- 能夠經過Last_query_cost得知查詢的成本
上圖表示,優化器認爲,這條SQL大概須要作1.399個數據頁的隨機查找才能完成查詢服務器
- 能夠請求優化器解析優化過程的各個因素(explain sql)
- 在表裏面有多個索引的時候,決定使用那個索引
- 經過特殊的關鍵字提示優化器,能夠影響優化器的決策過程(例如:for index)
- 優化器階段完成後,執行計劃就肯定下來了
- 優化器有時候會選擇錯誤的執行計劃
- 索引統計信息不許
- 優化器理解的最優執行計劃不必定是響應最快的執行計劃
存儲引擎層
- 負責數據的存儲和提取,插件式的架構模式,支持InnoDB,MyISAM等多個存儲引擎
- 不一樣的存儲引擎共用同一個Server層
redo log
InnoDB引擎獨有的日誌,存儲引擎層日誌架構
- 當有一條記錄須要更新的時候,InnoDB引擎會更新內存,並把記錄寫到redo log裏面,而後在適當的時候,將這個操做記錄更新到磁盤
- redo log的大小是固定的
- write pos是當前記錄的位置,一邊寫一邊後移,寫到末尾又從頭開始
- check point是當前要擦除的位置,一樣也是日後移動而且循環,擦除記錄,先把日誌更新到磁盤中
有了redo log,innodb能夠保證,數據庫發生異常重啓,以前提交的記錄都不會丟失(崩潰恢復能力,crash-safe)優化
bin log
- Server層的日誌,只能用於歸檔,,沒有carsh-safe能力
以後再介紹更加詳細的信息spa
redo log跟bin log的區別
- redo log是InnoDB特有的;binlog是Server層實現的,全部存儲引擎均可以使用
- redo log是物理日誌,記錄「某個數據頁上的修改」;binlog是邏輯日誌,記錄語句的原始邏輯
- redo log是循環寫的,空間固定;binlog是能夠追加寫入的,不會覆蓋之前的日誌
一條更新語句的執行流程
經過日誌兩階段提交,能夠保證redo log和bin log的邏輯一致插件
- 若是事務在①處奔潰了,事務會回滾
- 若是事務在②處奔潰了,因爲redo log處於prepare階段,而且binlog也已經寫入,那麼在恢復事務的時候,會自動commit
Write-Ahead Logging
- 使用日誌,存儲引擎能夠在內存中更新數據,而後將更新持久化到磁盤的日誌文件中,不須要每次都將更新後的數據刷新到磁盤(隨機IO)
- 日誌採用的是追加方式,寫日誌的操做實在磁盤上一小塊區域的順序IO(比隨機IO快得多)
- 日誌持久化到磁盤後,內存中被修改的數據(髒頁)在後臺能夠慢慢刷新到磁盤
推薦參數設置
- innodb_flush_log_at_trx_commit參數設置成1,表示每次事務的redo log都會持久化到磁盤
- sync_binlog參數設置成1,表示每次事務的binlog都持久化到磁盤