MySQL學習筆記 - 1 - 基本架構與日誌兩階段提交

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;
複製代碼
  • MySQL 8.0已經將查詢緩存整塊功能刪除掉

解析器(作什麼)

  • 詞法分析,識別SQL中的字符串是什麼
  • 語法分析
    • 在詞法分析的基礎上,根據語法規則,判斷SQL是否知足MySQL語法,最後獲得一棵語法樹
    • 對於只是參數不一樣,其餘均相同的sql,它們執行時間不一樣但硬解析的時間是相同的;而同一SQL隨着查詢數據的變化,屢次查詢執行時間可能不一樣,但硬解析的時間是不變的

詞法分析 -> 語法分析能夠稱爲硬解析數據庫

預處理器

  • 根據MySQL規則,進一步檢查語法樹是否合法

好比檢查表、數據列是否存在;別名是否有歧義等等緩存

優化器(怎麼作)

  • 優化器會將語法樹轉化成執行計劃(能夠生成多個執行計劃),而後找出最合適的執行計劃(成本最少)
  • 能夠經過Last_query_cost得知查詢的成本

優化器認爲,這條SQL大概須要作1.399個數據頁的隨機查找才能完成查詢

上圖表示,優化器認爲,這條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的區別

  1. redo log是InnoDB特有的;binlog是Server層實現的,全部存儲引擎均可以使用
  2. redo log是物理日誌,記錄「某個數據頁上的修改」;binlog是邏輯日誌,記錄語句的原始邏輯
  3. 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都持久化到磁盤
相關文章
相關標籤/搜索