面試官:說說MySQL存儲引擎原理,幸好我準(zhǔn)備過
你知道的越多,不知道的就越多,業(yè)余的像一棵小草!
你來,我們一起精進(jìn)!你不來,我和你的競爭對手一起精進(jìn)!
編輯:業(yè)余草
blog.csdn.net/weixin_46269257
推薦:https://www.xttblog.com/?p=5263
MySQL的數(shù)據(jù)是如何組織的呢?當(dāng)然是 page,也就是說MySQL以頁為單位進(jìn)行內(nèi)外存交換。
一、 MySQL記錄存儲(頁為單位)

頁頭
記錄頁面的控制信息,共占56字節(jié),包括頁的左右兄弟頁面指針、頁面空間使用情況等。
虛記錄
最大虛記錄:比頁內(nèi)最大主鍵還大 最小虛記錄:比頁內(nèi)最小主鍵還小 (作用:比如說我們要查看一個記錄是否在這個頁面里,就要看這個記錄是否在最大最小虛記錄范圍內(nèi))
記錄堆
行記錄存儲區(qū),分為有效記錄和已刪除記錄兩種
自由空間鏈表
已刪除記錄組成的鏈表 (重復(fù)利用空間)
未分配空間
頁面未使用的存儲空間;
Slot區(qū)
頁尾 頁面最后部分,占8個字節(jié),主要存儲頁面的校驗信息;
頁內(nèi)記錄維護(hù)

「順序保證」
物理有序(利于查詢,不利于插入刪除)

「邏輯有序(插入刪除性能高,查詢效率低)」 默認(rèn)

所以MySQL是像下圖所示這樣子有序的組織數(shù)據(jù)的。

「2、插入策略」
「自由空間鏈表」(優(yōu)先利用自由空間鏈表)
「未使用空間」
「3、頁內(nèi)查詢」
「遍歷」
「二分查找(數(shù)據(jù)不一樣大,不能用二分)」

利用槽位做二分,實現(xiàn)近似的二分查找,近似于跳表 。
二、 MySQL InnoDB存儲引擎內(nèi)存管理
預(yù)分配內(nèi)存空間
內(nèi)存池
數(shù)據(jù)以頁為單位加載 (減少io訪問次數(shù))
內(nèi)存頁面管理
頁面映射(記錄哪塊磁盤上的數(shù)據(jù)加載到哪塊內(nèi)存上了)
頁面數(shù)據(jù)管理
數(shù)據(jù)內(nèi)外存交換
數(shù)據(jù)淘汰
內(nèi)存頁耗盡
需要加載新數(shù)據(jù)

頁面管理
空閑頁
數(shù)據(jù)頁
臟頁(需刷回磁盤)
頁面淘汰
LRU(淘汰冷數(shù)據(jù))

某時刻狀態(tài)->訪問P2->訪問新頁P(yáng)7
全表掃描對內(nèi)存的影響?
可能會把內(nèi)存中的熱數(shù)據(jù)淘汰掉(比如說對一個幾乎沒有訪問量的表進(jìn)行全表掃描)
所以MySQL不是單純的利用LRU算法
解決問題:如何避免熱數(shù)據(jù)被淘汰?
解決方案:訪問時間 + 頻率(redis)
兩個LRU表
MySQL的解決方案

MySQL內(nèi)存管理—LRU

頁面裝載
磁盤數(shù)據(jù)到內(nèi)存


沒有空閑頁怎么辦?Free list中取 > LRU中淘汰 > LRU Flush
頁面淘汰
LRU尾部淘汰Flush LRU淘汰
LRU鏈表中將第一個臟頁刷盤并“釋放”,放到LRU尾部?直接放FreeList?
位置移動
old 到 new new 到 old

思考:移動時機(jī)是什么?innodb_old_blocks_timeold區(qū)存活時間,大于此值,有機(jī)會進(jìn)入new區(qū)

LRU_new的操作 鏈表操作效率很高,有訪問移動到表頭?Lock!!!``MySQL設(shè)計思路:減少移動次數(shù)
兩個重要參考:1、freed_page_clock:Buffer Pool淘汰頁數(shù) 2、LRU_new長度1/4
當(dāng)前freed_page_clock - 上次移動到Header時freed_page_clock>LRU_new長度1/4
三、MySQL事務(wù)實現(xiàn)原理
MySQL事務(wù)基本概念。
1、事務(wù)特性
A(Atomicity原子性):全部成功或全部失敗
I(Isolation隔離性):并行事務(wù)之間互不干擾
D(Durability持久性):事務(wù)提交后,永久生效
C(Consistency一致性):通過AID保證
2、并發(fā)問題
臟讀(Drity Read):讀取到未提交的數(shù)據(jù)
不可重復(fù)讀(Non-repeatable read):兩次讀取結(jié)果不同
幻讀(Phantom Read):select 操作得到的結(jié)果所表征的數(shù)據(jù)狀態(tài)無法支撐后續(xù)的業(yè)務(wù)操作
3、隔離級別
Read Uncommitted(未提交讀):最低隔離級別,會讀取到其他事務(wù)未提交的數(shù)據(jù)。臟讀;
Read Committed(提交讀):事務(wù)過程中可以讀取到其他事務(wù)已提交的數(shù)據(jù)。不可重復(fù)讀;
Repeatable Read(可重復(fù)讀):每次讀取相同結(jié)果集,不管其他事務(wù)是否提交,幻讀;(兩次當(dāng)前讀不會產(chǎn)生幻讀)
Serializable(串行化):事務(wù)排隊,隔離級別最高,性能最差;
MySQL事務(wù)實現(xiàn)原理(事務(wù)管理機(jī)制)
1、MVCC 多版本并發(fā)控制
解決讀-寫沖突 如何工作:隱藏列
–當(dāng)前讀(讀在存儲引擎中存儲的那個數(shù)據(jù))

RR級別下

2、undo log
回滾日志 保證事務(wù)原子性 實現(xiàn)數(shù)據(jù)多版本delete undo log:用于回滾,提交即清理;update undo log:用于回滾,同時實現(xiàn)快照讀,不能隨便刪除

思考:undolog如何清理?依據(jù)系統(tǒng)活躍的最小活躍事務(wù)ID Read view 為什么InnoDB count(*)這么慢?因為你真的懂 select count(*) 嗎?
SQL 查找是否"存在",別再 COUNT 了,很耗費(fèi)時間的
3、redo log
實現(xiàn)事務(wù)持久性

寫入流程 l 記錄頁的修改,狀態(tài)為prepare l 事務(wù)提交,講事務(wù)記錄為commit狀態(tài)


意義
體積小,記錄頁的修改,比寫入頁代價低 末尾追加,隨機(jī)寫變順序?qū)懀l(fā)生改變的頁不固定
四、MySQL鎖實現(xiàn)原理

所有當(dāng)前讀加排他鎖,都有哪些是當(dāng)前讀?SELECT FOR UPDATE``UPDATE``DELETE


唯一索引/非唯一索引 * RC/RR4種情況逐一分析

會出現(xiàn)幻讀問題,不可重復(fù)讀了




死鎖在庫表中有記錄,通過kill 那個鎖刪除。
好了,今天就分享到這里了。
冰凍三尺非一日之寒!
記得點(diǎn)個贊、點(diǎn)在看、轉(zhuǎn)發(fā)。
