Mysql存储引擎原理
Mysql的數據是如何組織的呢?
當然是page,也就是說mysql以頁為單位進行內外存交換。
一、 MySQL記錄存儲(頁為單位)
頁頭
記錄頁面的控制信息,共占56字節,包括頁的左右兄弟頁面指針、頁面空間使用情況等。
虛記錄
最大虛記錄:比頁內最大主鍵還大
最小虛記錄:比頁內最小主鍵還小
(作用:比如說我們要查看一個記錄是否在這個頁面里,就要看這個記錄是否在最大最小虛記錄范圍內)
記錄堆
行記錄存儲區,分為有效記錄和已刪除記錄兩種
自由空間鏈表
已刪除記錄組成的鏈表
(重復利用空間)
未分配空間
頁面未使用的存儲空間;
Slot區
頁尾
頁面最后部分,占8個字節,主要存儲頁面的校驗信息;
頁內記錄維護
1、順序保證
2. 邏輯有序(插入刪除性能高,查詢效率低) 默認
所以mysql是像下圖所示這樣子有序的組織數據的。
2、插入策略
3、頁內查詢
遍歷
二分查找(數據不一樣大,不能用二分)
利用槽位做二分,實現近似的二分查找,近似于跳表
二、 MySQL InnoDB存儲引擎內存管理
預分配內存空間
數據以頁為單位加載 (減少io訪問次數)
內存頁面管理
數據內外存交換
數據淘汰
頁面管理
空閑頁
數據頁
臟頁(需刷回磁盤)
頁面淘汰
LRU(淘汰冷數據)
某時刻狀態->訪問P2->訪問新頁P7
全表掃描對內存的影響?
可能會把內存中的熱數據淘汰掉(比如說對一個幾乎沒有訪問量的表進行全表掃描)
所以mysql不是單純的利用LRU算法
解決問題:如何避免熱數據被淘汰?
解決方案:
訪問時間 + 頻率(redis)
兩個LRU表
Mysql的解決方案
MySQL內存管理—LRU
頁面裝載
磁盤數據到內存
沒有空閑頁怎么辦?
Free list中取 > LRU中淘汰 > LRU Flush
頁面淘汰
LRU尾部淘汰
Flush LRU淘汰
LRU鏈表中將第一個臟頁刷盤并“釋放”
放到LRU尾部?直接放FreeList?
位置移動
old 到 new
new 到 old
思考:移動時機是什么?
innodb_old_blocks_time
old區存活時間,大于此值,有機會進入new區
LRU_new的操作
鏈表操作效率很高,有訪問移動到表頭?
Lock!!!
MySQL設計思路: 減少移動次數
兩個重要參考:
1、freed_page_clock:Buffer Pool淘汰頁數
2、LRU_new長度1/4
當前freed_page_clock - 上次移動到Header時freed_page_clock>LRU_new長度1/4
三、MySQL事務實現原理
MySQL事務基本概念
1、事務特性
A(Atomicity原子性):全部成功或全部失敗
I(Isolation隔離性):并行事務之間互不干擾
D(Durability持久性):事務提交后,永久生效
C(Consistency一致性):通過AID保證
2、并發問題
臟讀(Drity Read):讀取到未提交的數據
不可重復讀(Non-repeatable read):兩次讀取結果不同
幻讀(Phantom Read):select 操作得到的結果所表征的數據狀態無法支撐后續的業務操作
3、隔離級別
Read Uncommitted(未提交讀):最低隔離級別,會讀取到其他事務未提交的數據。臟讀;
Read Committed(提交讀):事務過程中可以讀取到其他事務已提交的數據。不可重復讀;
Repeatable Read(可重復讀):每次讀取相同結果集,不管其他事務是否提交,幻讀;(兩次當前讀不會產生幻讀)
Serializable(串行化):事務排隊,隔離級別最高,性能最差;
MySQL事務實現原理(事務管理機制)
1、MVCC 多版本并發控制
解決讀-寫沖突
如何工作:隱藏列
–當前讀(讀在存儲引擎中存儲的那個數據)
RR級別下
2、undo log
回滾日志
保證事務原子性
實現數據多版本
delete undo log:用于回滾,提交即清理;
update undo log:用于回滾,同時實現快照讀,不能隨便刪除
思考:undolog如何清理?
依據系統活躍的最小活躍事務ID Read view
為什么InnoDB count(*)這么慢?
因為
3、redo log
l實現事務持久性
寫入流程
l 記錄頁的修改,狀態為prepare
l 事務提交,講事務記錄為commit狀態
意義
體積小,記錄頁的修改,比寫入頁代價低
末尾追加,隨機寫變順序寫,發生改變的頁不固定
四、MySQL鎖實現原理
所有當前讀加排他鎖,都有哪些是當前讀?
SELECT FOR UPDATE
UPDATE
DELETE
唯一索引/非唯一索引 * RC/RR
4種情況逐一分析
會出現幻讀問題,不可重復讀了
死鎖在庫表中有記錄,通過kill 那個鎖刪除
總結
以上是生活随笔為你收集整理的Mysql存储引擎原理的全部內容,希望文章能夠幫你解決所遇到的問題。