體育老師都能看懂的InnoDB存儲(chǔ)引擎原理

老規(guī)矩,我們還是從一些看似不著邊際的基礎(chǔ)知識(shí)開(kāi)始說(shuō)起吧。。。。

操作系統(tǒng)的一些概念

我們常說(shuō)的磁盤(pán)結(jié)構(gòu)圖如下:綠色弧道的就是扇區(qū),灰色的就是磁道

磁盤(pán)中每個(gè)盤(pán)面結(jié)構(gòu)
磁盤(pán)的整體結(jié)構(gòu)

扇區(qū)是磁盤(pán)的最小組成單元,是磁盤(pán)的讀寫(xiě)單位,大小我們就機(jī)械的認(rèn)為是512字節(jié)。
柱面 就是第一張圖中的磁道
磁盤(pán)存儲(chǔ)容量 = 磁頭數(shù)磁道(柱面)數(shù)每道扇區(qū)數(shù)每扇區(qū)字節(jié)數(shù)
可能有人會(huì)發(fā)現(xiàn),每個(gè)扇區(qū)存儲(chǔ)大小一樣,那豈不是越靠近圓心的扇區(qū)越密集??對(duì)于老式磁盤(pán)確實(shí)是!新式磁盤(pán)有所改進(jìn),但是我們不打算深究~~~~
磁盤(pán)塊(blocks)是操作系統(tǒng)層面的虛擬概念,是操作系統(tǒng)與磁盤(pán)打交道的最小單位,一般是4KB(一般是扇區(qū)大小
2^n)
頁(yè) 是操作系統(tǒng)與內(nèi)存打交道的最小單位

InnoDB中的一些概念

為了顯的高大上,我們也俗套的甩幾個(gè)專(zhuān)業(yè)名次上來(lái)吧??
Buffer Pool數(shù)據(jù)庫(kù)緩沖池
Redo Log 重做日志,先理解成草稿吧
Datafile 數(shù)據(jù)文件,先理解成正稿及最終稿吧
Checkpoint,LSN
上面說(shuō)的這幾個(gè)概念都是為了在提升性能的同時(shí),又能保證數(shù)據(jù)不丟失,那么是怎么做到的呢?請(qǐng)看下面一個(gè)對(duì)比的例子,大家就會(huì)明白

互聯(lián)網(wǎng)圈,為了騙取投資人的錢(qián),在進(jìn)行融資前都會(huì)編一些ppt啥的,老板讓你給他編一個(gè)可以忽悠人的ppt,你突然想到一個(gè)絕美的idea,但是你白天都在劃水,又不想干活,只想晚上加班搞,但你又擔(dān)心 暫時(shí)記在腦子里的這個(gè)idea到晚上會(huì)忘記,你就會(huì)先圍繞這個(gè)idea大概思考一個(gè)大綱,匆忙記到一個(gè)草稿上,然后立馬跑到老板面前告訴他,你要編什么東東,讓他確認(rèn),到晚上了,根據(jù)草稿的內(nèi)容去斟詞酌句,編寫(xiě)正文。正文就是我們最終要拿去騙錢(qián)的ppt。
這里我們的大腦就相當(dāng)于Buffer Pool,我們的大腦就像內(nèi)存一樣記得快,忘的也快,就像內(nèi)存數(shù)據(jù)易丟失一樣
重做日志Redolog,就好比我們的草稿
Datafile就是我們的正稿
按照我們編ppt的方式,來(lái)進(jìn)行數(shù)據(jù)庫(kù)事務(wù)的寫(xiě)入操作,不僅能保證數(shù)據(jù)不丟失(大腦忘記了還有草稿),還能夠快速響應(yīng),得到客戶端的確認(rèn)(我們快速給老板響應(yīng)告訴他寫(xiě)什么,得到他的確認(rèn))

數(shù)據(jù)庫(kù)為了保證這個(gè) 【草稿】一定能恢復(fù)成正稿,還不能占用太多空間,就要求這個(gè)redo log(草稿)必須具有幾個(gè)特點(diǎn)
Redo log一定要保存了所有要寫(xiě)入的內(nèi)容
Redolog 只會(huì)在文件末尾增加數(shù)據(jù),而不會(huì)去改變舊的數(shù)據(jù)
一旦事務(wù)數(shù)據(jù)被寫(xiě)入datafile,redo log中的草稿就可以刪除了
正文在形成之前,草稿是不會(huì)刪除的;也就是說(shuō)只要草稿在我們一定能寫(xiě)出正文,就算數(shù)據(jù)庫(kù)Crash了,只要又redolog我們也不怕。

我們知道,數(shù)據(jù)庫(kù)在使用過(guò)程中事務(wù)是源源不斷的,也是很快的,而且根據(jù)草稿寫(xiě)出正稿是一個(gè)很費(fèi)時(shí)間的時(shí),所以往往草稿的產(chǎn)生速度是遠(yuǎn)遠(yuǎn)大于正稿的產(chǎn)生速度的,也就是說(shuō)你加班一個(gè)晚上根本寫(xiě)不完,要連續(xù)寫(xiě)好多次才有可能寫(xiě)完。 這樣就會(huì)面臨一個(gè)問(wèn)題,昨天我編到哪里了?當(dāng)然你也可以一個(gè)個(gè)去對(duì),但是這樣效率也太低了吧。 你或許會(huì)把最后一條生成正稿的草稿 打上一個(gè)標(biāo)記,這樣第二天可以直接從這個(gè)標(biāo)記的地方開(kāi)始寫(xiě),而不關(guān)心前面的內(nèi)容,也可以把前面的草稿內(nèi)容刪除掉。

這里最近一條變成正稿的草稿記錄就是Checkpoint,LSN就是每條草稿的編號(hào)。

數(shù)據(jù)庫(kù)配置文件匯總

木有辦法,為了講解innodb的某些東西,我不得不先拐個(gè)彎,把mysql配置吃透~~~
首先我們通過(guò)如下命令獲取到mysql服務(wù)的安裝目錄

安裝目錄
可以看到我的安裝目錄是/usr 或者連上sql時(shí) 執(zhí)行select @@basedir命令。

使用ps aux|grep mysql|grep 'my.cnf' 查看mysql啟動(dòng)的配置文件,如果沒(méi)有,說(shuō)明使用的默認(rèn)配置,使用下面的命令

mysql --help|grep 'my.cnf' 啟動(dòng)時(shí)會(huì)使用第一個(gè)目錄的文件
order of preference, my.cnf, $MYSQL_TCP_PORT,
/etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf

啟動(dòng)服務(wù) mysqld start 重啟服務(wù)mysqld restart 停止服務(wù) mysqld stop

現(xiàn)在我們知道了如何查找配置文件,已經(jīng)如何啟動(dòng)服務(wù)(其它更詳細(xì)的命令后續(xù)用到了再說(shuō)),終于開(kāi)始正兒八經(jīng)研究配置文件了

  • 數(shù)據(jù)庫(kù)配置文件匯總
// 這個(gè)是官方的默認(rèn)文件,我們按照自己的學(xué)習(xí)記錄一步一步去填充吧。在后續(xù)的概念講解中,我們會(huì)不時(shí)的翻到這個(gè)配置文件中來(lái)做說(shuō)明

/*對(duì)mysql服務(wù)器的優(yōu)化參數(shù)主要集中在mysqld段中國(guó),其它段的參數(shù)對(duì)mysql性能的影響微乎其微*/
[mysqld]
# 開(kāi)啟innodb引擎的獨(dú)立表空間MySQL5.6.7之后默認(rèn)開(kāi)啟
innodb_file_per_table = 1

# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M

# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin

# These are commonly set, remove the # and set as required.
# basedir = .....
# datadir = .....
# port = .....
# server_id = .....
# socket = .....

# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

  • 表空間:即存放數(shù)據(jù)庫(kù)表數(shù)據(jù)的地方
    表空間的具體數(shù)據(jù)結(jié)構(gòu)我們后續(xù)講,先搞明白這個(gè)表空間是干什么用的,在看原理。
    Innodb有兩種管理表空間的方法:
    1. 共享表空間(這個(gè)我們暫時(shí)不研究)
    2. 獨(dú)立表空間每一個(gè)表有一個(gè)獨(dú)立的表空間(現(xiàn)在都用這個(gè),隨著我們講解的進(jìn)行,好處自然而然會(huì)出來(lái))
    如果想要使用獨(dú)立表空間,my.conf中配置innodb_file_per_table【請(qǐng)參照配置文件】
    使用命令 show VARIABLES like 'innodb_file_per_table'; 查看獨(dú)立表空間是否開(kāi)啟
    開(kāi)啟該功能后,每創(chuàng)建一個(gè)新表就會(huì)在數(shù)據(jù)存放目錄中的相應(yīng)庫(kù)目錄下面(我的是/var/lib/mysql,這個(gè)目錄可以通過(guò)上文截圖中的--datadir=/var/lib/mysql找到)增加一個(gè)ibd文件,ibd文件就是該數(shù)據(jù)表的數(shù)據(jù)文件了。
    這個(gè)目錄下,每個(gè)表都會(huì)對(duì)應(yīng)一個(gè).frm 文件和一個(gè) .ibd文件,其中.frm是表結(jié)構(gòu)文件,.ibd 是數(shù)據(jù)文件。其中.frm文件是每個(gè)存儲(chǔ)引擎都會(huì)有的一個(gè)文件。
    .ibd文件
    innodeb引擎,使用IOT(索引組織表,即表中的數(shù)據(jù)都是根據(jù)主鍵順序組織存放)的形式來(lái)管理表數(shù)據(jù),表的索引跟數(shù)據(jù)都保存在.ibd文件中
    既然說(shuō)到了索引,我們又要先跑一下題,看一下InnoDB引擎的索引,innodb使用是B+樹(shù)索引。先從B+樹(shù)結(jié)構(gòu)說(shuō)起吧
    B數(shù)結(jié)構(gòu)
    B樹(shù)的一個(gè)大概查找思路如下:

每個(gè)節(jié)點(diǎn)中都是有序碼表,假如我們要查找9,首先在第一層查找,因?yàn)?<9<35 所以定位到第二層的2-10之間,然后定位到第三層,在有序碼表中>8最終找到葉子節(jié)點(diǎn)上(B數(shù)中葉子節(jié)點(diǎn)不保存數(shù)據(jù)),如果找到了葉子節(jié)點(diǎn)上,說(shuō)明該數(shù)據(jù)不存在。同理找37就可以找到。

innodb表的索引跟數(shù)據(jù)文件是同一個(gè).idb文件,innodb使用B+Tree,與上圖的區(qū)別是,葉子節(jié)點(diǎn)非空,頁(yè)節(jié)點(diǎn)的data域保存了完整的數(shù)據(jù)記錄,碼值域就是數(shù)據(jù)表的主鍵。這種索引與數(shù)據(jù)文件在一塊的就是聚集索引。innodb表的輔助索引也是先找到對(duì)應(yīng)的主索引,然后再根據(jù)主索引找到數(shù)據(jù)data這是因?yàn)閕nnodb表的數(shù)據(jù)是按照主鍵聚集的,這也同時(shí)要求innodb表必須有主鍵
單獨(dú)表空間優(yōu)點(diǎn)和缺點(diǎn)
優(yōu)點(diǎn)
每個(gè)表都有自已獨(dú)立的表空間。
每個(gè)表的數(shù)據(jù)和索引都會(huì)存在自已的表空間中。
可以實(shí)現(xiàn)單表在不同的數(shù)據(jù)庫(kù)中移動(dòng)。
空間可以回收
缺點(diǎn)
1單表增加過(guò)大,響應(yīng)也是較慢,可以使用分區(qū)表
2單表增加過(guò)大,當(dāng)單表占用空間過(guò)大時(shí),存儲(chǔ)空間不足,只能從操作系統(tǒng)層面思考解決方法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容