1葡盗、索引有哪些纽门。聚簇索引和非聚簇索引區(qū)別
2、為什么使用b+樹
3涛癌、索引失效的場景
4反镇、事務(wù)是怎么實(shí)現(xiàn)的固蚤。mvcc?沒有binlog還能實(shí)現(xiàn)事務(wù)嗎
5歹茶、一條sql的執(zhí)行過程夕玩。
1、索引有哪些惊豺。聚簇索引和非聚簇索引區(qū)別
索引有哪些燎孟?
b+樹索引
大多數(shù)MySQL存儲(chǔ)引擎的默認(rèn)索引
哈希索引
innodb存儲(chǔ)引擎有個(gè)特殊的功能叫“自適應(yīng)哈希索引”,當(dāng)某個(gè)索引值被使用的非常頻繁時(shí)尸昧,會(huì)在b+樹索引之上再創(chuàng)建一個(gè)哈希索引
全文索引
全文索引一般使用倒排索引實(shí)現(xiàn)揩页,記錄者關(guān)鍵字到其所在文檔的映射。
聚簇索引和非聚簇索引
聚簇索引烹俗,表數(shù)據(jù)是和主鍵一起存儲(chǔ)的碍沐,主鍵索引的葉結(jié)點(diǎn)存儲(chǔ)行數(shù)據(jù)(包含了主鍵值),二級(jí)索引的葉結(jié)點(diǎn)存儲(chǔ)行的主鍵值衷蜓。使用的是B+樹作為索引的存儲(chǔ)結(jié)構(gòu),非葉子節(jié)點(diǎn)都是索引關(guān)鍵字尘喝,但非葉子節(jié)點(diǎn)中的關(guān)鍵字中不存儲(chǔ)對(duì)應(yīng)記錄的具體內(nèi)容或內(nèi)容地址磁浇。
非聚簇索引表
表數(shù)據(jù)和索引是分成兩部分存儲(chǔ)的,主鍵索引和二級(jí)索引存儲(chǔ)上沒有任何區(qū)別朽褪。使用的是B+樹作為索引的存儲(chǔ)結(jié)構(gòu)置吓,所有的節(jié)點(diǎn)都是索引无虚,葉子節(jié)點(diǎn)存儲(chǔ)的是索引+索引對(duì)應(yīng)的記錄的數(shù)據(jù)
2、為什么使用b+樹
為了減少磁盤讀取次數(shù)衍锚,決定了樹的高度不能高友题。所以選擇b樹
以頁為單位讀取使得一次IO就能完全載入一個(gè)節(jié)點(diǎn),且相鄰的節(jié)點(diǎn)能夠被預(yù)先載入戴质,所以數(shù)據(jù)放在葉子結(jié)點(diǎn)度宦,本質(zhì)上是一個(gè)page頁
為了支持查詢范圍以及關(guān)聯(lián)關(guān)系,頁中數(shù)據(jù)需要有序告匠。
b+樹是基于b樹和葉子節(jié)點(diǎn)順序訪問指針進(jìn)行實(shí)現(xiàn)的戈抄。具有b樹的平衡性,并且通過順序訪問指針來提高區(qū)間查詢的性能后专。
3划鸽、索引失效的場景
常見的一些場景回答一下。
4戚哎、事務(wù)是怎么實(shí)現(xiàn)的裸诽。mvcc?沒有binlog還能實(shí)現(xiàn)事務(wù)嗎
臟讀:當(dāng)一個(gè)事物正在訪問數(shù)據(jù)并對(duì)數(shù)據(jù)進(jìn)行了修改型凳,但沒提交時(shí)丈冬,另一個(gè)事務(wù)訪問了這個(gè)數(shù)據(jù),這個(gè)數(shù)據(jù)是還沒提交的數(shù)據(jù)啰脚,則適合讀到的數(shù)據(jù)就是臟數(shù)據(jù)殷蛇。
不可重復(fù)讀:一個(gè)數(shù)據(jù)內(nèi)多次讀同一個(gè)數(shù)據(jù),這個(gè)事務(wù)沒結(jié)束時(shí)橄浓,另一個(gè)事務(wù)訪問改數(shù)據(jù)粒梦,那可能第一個(gè)事務(wù)兩次讀取的結(jié)果不同。
幻讀荸实,一個(gè)事務(wù)讀取幾行數(shù)據(jù)匀们,另一個(gè)事務(wù)插入了一些數(shù)據(jù)時(shí),第一個(gè)事務(wù)就會(huì)發(fā)現(xiàn)多了幾行數(shù)據(jù)准给。
不可重復(fù)讀重在修改泄朴,幻讀重在新增、刪除露氮。
隔離級(jí)別 | 臟讀 | 不可重復(fù)讀 | 幻讀 |
---|---|---|---|
讀未提交 | √ | √ | √ |
讀已提交 | × | √ | √ |
可重復(fù)讀(mysql的默認(rèn)級(jí)別) | x | x | √ |
串行化 | x | x | x |
事務(wù)的基本特性:ACID祖灰。
原子性:一個(gè)事務(wù)中的操作要么全部成功,要么全部失敗畔规。
由undo log日志保證局扶,記錄了需要回滾的日志信息,事務(wù)回滾時(shí)撤銷已經(jīng)執(zhí)行成功的sql
一致性:數(shù)據(jù)庫總是從一個(gè)一致性的狀態(tài)轉(zhuǎn)換到另一個(gè)一致性的狀態(tài)。
一般由代碼層面來保證
隔離性:一個(gè)事務(wù)的修改在最終提交前三妈,對(duì)其他事務(wù)是不可見的畜埋。
由mvcc保證
持久型:一旦事務(wù)提交,所做的修改就會(huì)永遠(yuǎn)保存到數(shù)據(jù)庫中畴蒲。
由內(nèi)存+redo log保證悠鞍,mysql修改數(shù)據(jù)同時(shí)在內(nèi)存和redo log記錄這次操作,事務(wù)提交的時(shí)候通過redo log栓盤模燥,宕機(jī)的時(shí)候可以從redo log恢復(fù)
InnoDB通過 Force Log at Commit
機(jī)制保證持久性:當(dāng)事務(wù)提交(COMMIT)時(shí)咖祭,必須先將該事務(wù)的所有日志緩沖寫入到重做日志文件進(jìn)行持久化,才能 COMMIT 成功涧窒。
為了確保每次日志都寫入 redo log 文件心肪,在每次將 redo log buffer cache 寫入重做日志文件后,InnoDB 引擎都需要調(diào)用一次 fsync 操作纠吴。因此磁盤的性能決定了事務(wù)提交的性能硬鞍,也就是數(shù)據(jù)庫的性能。
redo log擁有兩階段提交戴已。
MVCC
一般來說 MVCC 只在 Read Committed 和 Repeatable Read 兩個(gè)隔離級(jí)別下工作固该。Read Uncommitted 總是能讀取到未提交的記錄,不需要版本控制糖儡;Serializable 對(duì)所有的讀取都對(duì)加鎖伐坏,單獨(dú)靠 MVCC 無法完成。
MVCC 的實(shí)現(xiàn)握联,是通過保存數(shù)據(jù)在某一個(gè)時(shí)間點(diǎn)的快照來實(shí)現(xiàn)的桦沉。因此每一個(gè)事務(wù)無論執(zhí)行多長時(shí)間看到的數(shù)據(jù),都是一樣的金闽。所以 MVCC 實(shí)現(xiàn)可重復(fù)讀纯露。
在innodb引擎中就是指在已提交讀(READ COMMITTD)和可重復(fù)讀(REPEATABLE READ)這兩種隔離級(jí)別下的事務(wù)對(duì)于SELECT操作會(huì)訪問版本鏈中的記錄的過程。
MVCC 的目的就是多版本并發(fā)控制代芜,在數(shù)據(jù)庫中的實(shí)現(xiàn)埠褪,就是為了解決讀寫沖突
,它的實(shí)現(xiàn)原理主要是依賴記錄中的 3個(gè)隱式字段
挤庇,undo日志
钞速, Read View
來實(shí)現(xiàn)的。
三個(gè)隱式字段是:最近修改的事務(wù)id嫡秕,回滾指針渴语,還有隱式的自增id。
undo log 主要分為兩種insert undo log和update undo log
已提交讀和可重復(fù)讀的區(qū)別就在于它們生成ReadView的策略不同昆咽。
ReadView中主要就是有個(gè)列表來存儲(chǔ)我們系統(tǒng)中當(dāng)前活躍著的讀寫事務(wù)驾凶,也就是begin了還未提交的事務(wù)屠升。通過這個(gè)列表來判斷記錄的某個(gè)版本是否對(duì)當(dāng)前事務(wù)可見。
已提交讀隔離級(jí)別下的事務(wù)在每次查詢的開始都會(huì)生成一個(gè)獨(dú)立的ReadView,而可重復(fù)讀隔離級(jí)別則在第一次讀的時(shí)候生成一個(gè)ReadView狭郑,之后的讀都復(fù)用之前的ReadView。
這就是Mysql的MVCC,通過版本鏈汇在,實(shí)現(xiàn)多版本翰萨,可并發(fā)讀-寫,寫-讀糕殉。通過ReadView生成策略的不同實(shí)現(xiàn)不同的隔離級(jí)別亩鬼。
bin log作用
復(fù)制和恢復(fù)數(shù)據(jù)
MySQL在公司使用的時(shí)候往往都是一主多從結(jié)構(gòu)的,從服務(wù)器需要與主服務(wù)器的數(shù)據(jù)保持一致阿蝶,這就是通過binlog來實(shí)現(xiàn)的
數(shù)據(jù)庫的數(shù)據(jù)被干掉了雳锋,我們可以通過binlog來對(duì)數(shù)據(jù)進(jìn)行恢復(fù)。
5羡洁、一條sql的執(zhí)行過程玷过。
更新一條數(shù)據(jù)到事務(wù)的提交過程:
首先執(zhí)行器根據(jù) MySQL 的執(zhí)行計(jì)劃來查詢數(shù)據(jù),先是從緩存池中查詢數(shù)據(jù)筑煮,如果沒有就會(huì)去數(shù)據(jù)庫中查詢辛蚊,如果查詢到了就將其放到緩存池中在數(shù)據(jù)被緩存到緩存池的同時(shí),會(huì)寫入 undo log 日志文件更新的動(dòng)作是在 BufferPool 中完成的真仲,同時(shí)會(huì)將更新后的數(shù)據(jù)添加到 redo log buffer 中完成以后就可以提交事務(wù)袋马,
在提交的同時(shí)會(huì)做以下三件事
1、將redo log buffer中的數(shù)據(jù)刷入到 redo log 文件中
2秸应、將本次操作記錄寫入到 bin log文件中
3虑凛、將 bin log 文件名字和更新內(nèi)容在 bin log 中的位置記錄到redo log中,同時(shí)在 redo log 最后添加 commit 標(biāo)記