一小時總結 -- MySql 知識(一)

一小時總結 – MySql 知識(一)

數據庫知識是開發和麪試必須掌握的知識,只有瞭解數據庫的脾性才能更好的使用它。

在衆多數據庫軟件裏面,Oracle 的性能最強悍,目前基本上還沒有 Oracle 一體機跑不動的應用(如果有隻能說明你的體量太大或者使用太爛)。MySql 作爲免費開源的代表基本上是大中小企業的首選。也是面試和應用中應該掌握的重點。

以下內容爲默記整理內容,如存在表述錯誤表述不準確歡迎指正。

要點:

  • 原理性知識:
    • 整體:MySql 的體系結構;
      • 線程模型:線程連接池;
      • 內存模式:緩衝區;
      • 網絡模型:reactor 模型;
      • 文件模型:B+樹、binlog 及重做日誌
      • 高可用:主從複製、binlog 及重做日誌;
    • 擴展原理:MySql 引擎對比;
    • 效能原理:MySql 的索引結構和存儲;
    • 實現原理:MySql InnoDB 如何實現事務;
      • InnoDB MVVC 的原理和實現;
      • InnoDB 鎖相關知識;
  • 應用性知識:
    • explain 的用法和關注點;
    • 慢查詢的查詢思路;
    • sql 優化原則;
    • 如何選擇合適的存儲引擎;

原理性知識

整體:MySql 的體系結構

MySql 整體可分爲三層:

  • 連接層:最上層,實現連接管理;
  • ??中間層??:MySql 本身實現的查詢緩存、sql 解析、sql 優化器,中間層調用底層存儲引擎層的 Api 實現 sql 的執行和優化;
  • 存儲引擎層:最底層,可以以插件形式實現 MySql 的文件存儲和數據查詢;

線程模型:線程池

MySql 採用多線程實現,其內部運行了多個線程,採用統一線程池管理,每個連接的查詢發送到 mysql 後,有一個獨立線程負責此次 sql 的執行。

內存模型:緩衝區

MySql 採用內存緩衝區的方式提升應用效率,爲了降低磁盤 IO 次數,MySql 儘量把熱點數據緩存到內存中。

  • 寫緩衝:當有數據發生修改後,MySql 採用寫緩衝的方式先操作內存數據,待合適時機再將數據修改寫入到物理磁盤;
  • IO 合併:MySql 中的很多 IO 爲邏輯 IO,邏輯 IO 可能操作的是緩存數據,待合適時機多個邏輯 IO 會被合併爲一個物理 IO 進行一次性操作。

網絡模型:Reactor 模型

MySql 的網絡連接和驅動採用 Reactor 模型管理連接,僅當數據準備充分後再分配線程。

文件模型:B+樹、binlog 及重做日誌

爲了充分利用磁盤特性,尤其是 HDD 磁盤的磁頭移動特性,MySql 採用:

  • 使用 矮胖 的 B+ 樹作爲索引的存儲和實現結構,相比 AVL 樹 B+ 樹有更低的樹高度,能有效的減少磁盤 IO 次數,而相對 B 樹,B+ 樹的搜索效率更穩定,葉子節點的鏈表指針讓範圍查詢變得更容易和高效,更能充分利用磁盤連續讀和操作系統 page cache 特性。
  • binlog 及重做日誌:爲了儘量減少磁盤 IO,MySql 將數據寫入內存緩衝帶來的風險是機器掉電帶來的數據丟失風險,因此 MySql 設計了 binlog 和重做日誌。binlog 和重做日誌在設計上採用單文件追加的方式具有更高的刷盤效率。

高可用:主從複製、binlog 及重做日誌

MySql 的高可用提現在兩個方面:

  • 單機掉電的情況下:可保證的數據一致性;
  • 提供集羣容災策略:主從複製策略,並提供主從數據一致性保證;

單機掉電:

  • 在內存模型中,MySql 爲了提升操作效率大部分操作的是內存緩衝數據,爲了保證掉電後緩衝數據丟失帶來的數據丟失風險,mysql 建立了 binlog 和重做日誌機制(InnoDB 機制);
  • binlog 機制:binlog 記錄了所有的 sql 操作(select 不記錄),利用 binlong 可實現主從複製和宕機重啓後的數據恢復。
  • 重做日誌:innodb 實現的日誌,分爲 redo log 和 undo log,redo log ,redo log 記錄了尚未刷新到磁盤的數據變化,undo log 記錄了事務執行過程產生的事務日誌可實現數據回滾。

擴展原理:MySql 引擎對比

MySql 的存儲引擎機制讓 MySql 本身不 care 數據如何被存儲和索引。存儲引擎機制讓 MySql 可適用多種適用場景:

  • ISAM 和 MyISAM:早期 MySql 官方默認的存儲引擎,最早引擎叫 ISAM 後面改名叫 MyISAM,ISAM 是一種算法。MyISAM 引擎的實現簡單不支持事務,僅支持表鎖但是其數據存儲的空間效率高。適合
  • InnoDB:MySql 5.6 後官方默認的引擎,InnoDB 引擎支持事務並擴展實現了行級鎖。適合絕大部分 OLTP 應用(增刪改查比較均衡的場景)
  • 其他引擎:NDB 等,有些將數據以列方式組織存儲,有些將數據全部放到內存中提升效率各有自己的目標應用場景。

效能原理:MySql 的索引結構和存儲

基礎原理

MySql 的文件分爲兩類:

  • 表定義文件:這類文件 MySql 本身實現了相關文件的存儲;
  • 表數據文件:這類文件 MySql 交給存儲引擎去實現相關數據的存儲;

索引文件基本上由存儲引擎來實現,所有存儲引擎基本上使用 B+ 樹

MyISAM 的實現

MyISAM 的存儲和索引實現比較簡單,

  • 表數據:表數據按插入行順序存儲在表文件中;
  • 索引:MyISAM 的索引使用 B+ 樹實現,葉子節點存儲了行的物理文件指針,通過此指針可以定位到具體行數據。

InnoDB 的實現

InnoDB 的表被稱爲索引組織表,表數據和索引數據存放在一起;

  • 表數據:表數據按行組織,作爲主鍵索引的葉子節點存放,具體數據表還分爲:區、頁、端 等;
  • 索引:採用 B+ 樹實現,主鍵索引的葉子節點存儲了行數據,非主鍵索引的葉子節點存儲了主鍵值,因此非主鍵索引查詢非索引值要進行回表操作。

實現原理:MySql InnoDB 如何實現事務

InnoDB 引擎支持 4 級事務,MyISAM 是不支持事務的。InnoDB 採用下面的技術實現了事務的 ACID 特性。

  • 重做日誌:採用 redo log 和 undo log 的方式保證事務的一致性和持久性。
  • MVVC 和行鎖:實現了事務的隔離性;

爲了提升事務的併發效率,InnoDB 採用 MVVC 技術提供了 非鎖定讀一致性寫 的特性。

MVVC 技術

  • MVVC:多版本併發控制技術,簡單理解是某行併發操作數據在同一個時刻可能存在多個快照版本,根據事務的隔離級別,InnoDB 會確定此事務可見的數據快照版本。
  • 實現:同時真的維護多個快照版本數據是難以實現的,因此 InnoDB 採用在每行上添加三個字段的方式來實現:創建號、刪除號、undo 指針。
  • 快照數據的確定:每個事務都會被分配一個事務 id,事務 id 是嚴格自增的,在可重複讀級別下,某個行在某個事務中是否可見,是通過比較當前事務 id 和行數據的創建號、刪除號來決定的,具體確定策略;
    • 行可見:行的刪除號 == null && 行的創建號 <= 當前事務號;
    • 新增行:行的創建號 = 當前事務號 && 行的刪除號 = null;
    • 刪除行:行的刪除號 = 當前事務號;
  • 歷史版本:如果某個事務併發的修改了其中一行,那麼此行的歷史版本通過 undo 指針可以從 undo 日誌中找到。

  • 行鎖:鎖定某一行,加了行鎖後,其他併發事務會被阻塞;
  • 間隙鎖:鎖定某一個範圍,加了範圍鎖後,其他併發事務在此範圍內操作數據都會被阻塞,間隙鎖是一個開區間鎖;
  • next key 鎖:行鎖 + 間隙鎖,是一個左閉右開的鎖;
  • InnoDB 在讀已提交的隔離級別下:加行鎖;
  • InnoDB 在可重複讀的隔離級別下:加 next key lock;

應用性知識

explain 的用法和關注點;

explain 用來分析 sql 的查詢計劃,本身 explain 用法比較複雜,實際應用中要關注的點很多,但是很多點要關聯起來看,一般來說,某個 SQL 的效率可以通過下面幾個點來關注:

  • keys:是否走了索引;
  • extra:是否有 using file sorted 和 using temporary;
  • rows:查詢出來的數據是否過大;

慢查詢的查詢思路

慢查詢並不一定等於慢 sql,慢查詢先要定位是否是慢 sql:

  • 是否慢 sql:查看 mysql 的慢 sql 日誌,如果慢 sql 的閾值不理想可調整閾值後再觀察;
  • 如果慢 sql 日誌出現了記錄,則分析相關 sql,如果沒有則問題查詢方向要改爲關注 mysql 連接層和網絡狀況。

mysql 連接層和網絡狀態

  • 先確認 mysql 的壓力:是否連接過載很大,導致大部分應用連接沒有及時獲得 thread 陷入了等待,結合 top 等命令查詢;
  • 排除 mysql 的壓力,確認網絡狀況是否良好,可以使用 tcpdump 抓包,確定是否有 tcp 重傳或者網絡抖動帶來的網絡大面積延遲。通過 trace 等命令確定某個網關路由是否有問題,通過 ping 、telnet 來確認業務主機和 mysql 的網卡是否有問題。

慢 sql 確定

慢 sql 的主要確認方式是通過 explain 來分析 sql 效率,並結合 sql 優化原則來優化自己的 sql 達到理想執行效率。

sql 優化原則

  • 儘量做到索引覆蓋:做到索引覆蓋則可以避免 mysql 的回表操作;
  • 減少不必要的字段查詢:可以縮小數據包增強網絡傳輸效率;
  • 查詢要走索引:走索引則可以快速過濾不必要的數據,減少全表掃描,減少數據的 IO 次數,具體做法:
    • 避免索引字段爲 null 的查詢;
    • 做到最左前綴匹配,儘量去除 like ‘%a%’ 的查詢;
    • 用 exist 替代 in 操作,尤其是 in 的值過多的情況;
  • 使用預編譯語句:預編譯語句不僅能避免 sql 注入還可以加快查詢效率,避免每次的 sql 解析,還能充分幫助數據庫命中查詢緩存。

如何選擇合適的存儲引擎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章