最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

24 我們寫入數(shù)據(jù)庫的一行數(shù)據(jù),在磁盤上是怎么存儲(chǔ)的?

2023-06-20 10:37 作者:儒猿課堂  | 我要投稿

我們寫入數(shù)據(jù)庫的一行數(shù)據(jù),在磁盤上是怎么存儲(chǔ)的?


1、承上啟下:在Buffer Pool之后,為什么要學(xué)習(xí)MySQL物理數(shù)據(jù)模型?


之前的一些文章我們已經(jīng)深入的給大家分析了當(dāng)你執(zhí)行crud操作的時(shí)候,MySQL是如何把磁盤上的數(shù)據(jù)頁加載到內(nèi)存中的Buffer Pool的緩存頁里去的,以及對(duì)Buffer Pool是如何進(jìn)行一整套復(fù)雜的管理機(jī)制的。


相信現(xiàn)在每個(gè)人都對(duì)緩存頁加載到Buffer Pool中,更新和讀取緩存頁里的數(shù)據(jù),這個(gè)過程中的free鏈表、flush鏈表以及l(fā)ru鏈表的維護(hù),都有了一個(gè)深刻的理解,包括后臺(tái)線程是如何定時(shí)根據(jù)flush鏈表以及l(fā)ru鏈表將部分被更新的緩存頁刷入磁盤的,以及緩存頁都用完了以后是如何根據(jù)lru鏈表將一些冷數(shù)據(jù)緩存頁刷入磁盤的。


按理來說,在講解完上述內(nèi)容之后,我們下一步就應(yīng)該是要給大家講解undo log和redo log以及事務(wù)機(jī)制了,但是現(xiàn)在還不行,實(shí)際上我們?cè)诶斫饬薓ySQL中的數(shù)據(jù)緩存機(jī)制以及內(nèi)存數(shù)據(jù)更新機(jī)制,包括緩存到磁盤的數(shù)據(jù)刷新機(jī)制之后,我們還得來理解一下MySQL中的物理數(shù)據(jù)結(jié)構(gòu)。


之前很多朋友可能會(huì)發(fā)現(xiàn)我在文章里提到了表空間、區(qū)、數(shù)據(jù)頁、一個(gè)區(qū)中的連續(xù)數(shù)據(jù)頁、表空間號(hào)以及數(shù)據(jù)頁號(hào),這些概念,這些概念,我們之前即使不理解,其實(shí)也不妨礙我們?nèi)ダ斫釳ySQL的Buffer Pool緩存機(jī)制。


因?yàn)榇蠹抑翱赡苣X子里大致都有一個(gè)概念,就是數(shù)據(jù)頁這個(gè)概念,起碼知道每一行數(shù)據(jù)都是放在數(shù)據(jù)頁里的,我們是按照數(shù)據(jù)頁為單位把磁盤上的數(shù)據(jù)加載到內(nèi)存的緩存頁里來,也是按照頁為單位,把緩存頁的數(shù)據(jù)刷入磁盤上的數(shù)據(jù)頁中。


但是我之前也問過大家,我們平時(shí)寫SQL語句的時(shí)候腦子里都有一個(gè)表、行和字段的概念,但是為什么跑到MySQL內(nèi)部,就出現(xiàn)了一堆表空間、數(shù)據(jù)區(qū)、數(shù)據(jù)頁這些概念呢?


其實(shí)很多人都說了,表、行和字段是邏輯上的概念,而表空間、數(shù)據(jù)區(qū)和數(shù)據(jù)頁其實(shí)已經(jīng)落實(shí)到物理上的概念了。


實(shí)際上表空間、數(shù)據(jù)頁這些東西,都對(duì)應(yīng)到了MySQL在磁盤上的一些物理文件了。


所以接下來,我們要用一些文章來逐步逐步的講解MySQL的表空間、數(shù)據(jù)區(qū)、數(shù)據(jù)頁、磁盤上的物理文件這些概念。當(dāng)大家看明白這些東西之后,你就會(huì)理解,當(dāng)我們執(zhí)行SQL語句的時(shí)候,是從MySQL機(jī)器上的哪些磁盤文件里加載數(shù)據(jù)頁到緩存頁里來的,數(shù)據(jù)頁是如何由數(shù)據(jù)區(qū)這個(gè)概念來組織起來的,表空間這個(gè)概念是怎么回事


很多朋友之前還在評(píng)論區(qū)提問,你一個(gè)SQL語句僅僅指定了你要查詢或者更新哪個(gè)表的哪些數(shù)據(jù),那你怎么知道這些數(shù)據(jù)在哪個(gè)表空間里?在哪個(gè)數(shù)據(jù)區(qū)里?在哪些數(shù)據(jù)頁里?對(duì)應(yīng)是在MySQL機(jī)器上的哪些磁盤文件里呢?


當(dāng)我們學(xué)習(xí)完接下來的一部分內(nèi)容后,上述問題的答案都會(huì)迎刃而解。


2、之前遺留思考題解答:為什么不能直接更新磁盤上的數(shù)據(jù)?


之前我們留過一個(gè)思考題,讓大家思考一下,為什么MySQL要設(shè)計(jì)這么一套復(fù)雜的數(shù)據(jù)存取機(jī)制,要基于內(nèi)存、日志、磁盤上的數(shù)據(jù)文件來完成數(shù)據(jù)的讀寫呢?為什么對(duì)insert、update請(qǐng)求,不直接更新磁盤文件里的數(shù)據(jù)呢?


很多人都在評(píng)論區(qū)給出了自己的思考和回答,我覺得每個(gè)人的思考都特別的好,大家可以多去評(píng)論區(qū)里看看別人的思考以及進(jìn)行交流。


這里我簡單一句話總結(jié),為什么不能直接更新磁盤上的數(shù)據(jù),因?yàn)閬硪粋€(gè)請(qǐng)求就直接對(duì)磁盤文件進(jìn)行隨機(jī)讀寫,然后更新磁盤文件里的數(shù)據(jù),雖然技術(shù)上是可以做到的,但是那必然導(dǎo)致執(zhí)行請(qǐng)求的性能極差。


因?yàn)榇疟P隨機(jī)讀寫的性能是最差的,所以直接更新磁盤文件,必然導(dǎo)致我們的數(shù)據(jù)庫完全無法抗下任何一點(diǎn)點(diǎn)稍微高并發(fā)一點(diǎn)的場景。


所以MySQL才設(shè)計(jì)了如此復(fù)雜的一套機(jī)制,通過內(nèi)存里更新數(shù)據(jù),然后寫redo log以及事務(wù)提交,后臺(tái)線程不定時(shí)刷新內(nèi)存里的數(shù)據(jù)到磁盤文件里


通過這種方式保證,你每個(gè)更新請(qǐng)求,盡量就是更新內(nèi)存,然后順序?qū)懭罩疚募?/p>


更新內(nèi)存的性能是極高的,然后順序?qū)懘疟P上的日志文件的性能也是比較高的,因?yàn)轫樞驅(qū)懘疟P文件,他的性能要遠(yuǎn)高于隨機(jī)讀寫磁盤文件。


也正是通過這套機(jī)制,才能讓我們的MySQL數(shù)據(jù)庫在較高配置的機(jī)器上,每秒可以抗下幾千的讀寫請(qǐng)求。


3、復(fù)習(xí)鞏固:MySQL為什么要引入數(shù)據(jù)頁這個(gè)概念?


首先我們先考慮一下,剛才是不是已經(jīng)給大家講過,當(dāng)我們要執(zhí)行update之類的SQL語句的時(shí)候,必然涉及到對(duì)數(shù)據(jù)的更新操作?那么此時(shí)對(duì)數(shù)據(jù)是在哪里更新的?


此時(shí)并不是直接去更新磁盤文件,而是要把磁盤上的一些數(shù)據(jù)加載到內(nèi)存里來,然后對(duì)內(nèi)存里的數(shù)據(jù)進(jìn)行更新,同時(shí)寫redo log到磁盤上去,我們看下圖回憶一下。

? ? ? ? ? ?

? ? ? ? ?

但是這里就有一個(gè)問題了,難道我們每次都是把磁盤里的一條數(shù)據(jù)加載到內(nèi)存里去進(jìn)行更新,然后下次要更新別的數(shù)據(jù)的時(shí)候,再從磁盤里加載另外一條數(shù)據(jù)到內(nèi)存里去?


這樣每次都是一條數(shù)據(jù)一條數(shù)據(jù)的加載到內(nèi)存里去更新,大家覺得效率高嗎?


很明顯是不高的


所以innodb存儲(chǔ)引擎在這里引入了一個(gè)數(shù)據(jù)頁的概念,也就是把數(shù)據(jù)組織成一頁一頁的概念,每一頁有16kb,然后每次加載磁盤的數(shù)據(jù)到內(nèi)存里的時(shí)候,是至少加載一頁數(shù)據(jù)進(jìn)去,甚至是多頁數(shù)據(jù)進(jìn)去,我們看下圖

? ? ? ? ? ?

? ? ? ? ? ? ?

假設(shè)我們有一次要更新一條id=1的數(shù)據(jù):


update xxx set xxx=xxx where id=1


那么此時(shí)他會(huì)把id=1這條數(shù)據(jù)所在的一頁數(shù)據(jù)都加載到內(nèi)存里去,這一頁數(shù)據(jù)里,可能還包含了id=2,id=3等其他數(shù)據(jù)。


然后我們更新完id=1的數(shù)據(jù)之后,接著更新id=2的數(shù)據(jù),那么此時(shí)是不是就不用再次讀取磁盤里的數(shù)據(jù)了?


因?yàn)閕d=2本身就跟id=1在一頁里,之前這一頁數(shù)據(jù)就加載到內(nèi)存里去了,你直接更新內(nèi)存里的數(shù)據(jù)頁中的id=2這條數(shù)據(jù)就可以了。


我們看下圖,這就是數(shù)據(jù)頁的意義,磁盤和內(nèi)存之間的數(shù)據(jù)交換通過數(shù)據(jù)頁來執(zhí)行,包括內(nèi)存里更新后的臟數(shù)據(jù),刷回磁盤的時(shí)候,也是至少一個(gè)數(shù)據(jù)頁刷回去。

? ? ? ? ? ?

? ? ? ? ? ? ?

我們?cè)倏聪聢D,要明白的一點(diǎn)是,我們不是一直在內(nèi)存里更新各種數(shù)據(jù)嗎?當(dāng)IO線程把內(nèi)存里的臟數(shù)據(jù)刷到磁盤上去的時(shí)候,也是以數(shù)據(jù)頁為單位來刷回去的


下圖中有這個(gè)刷數(shù)據(jù)的圖示:

? ? ? ? ? ?

? ? ? ? ? ? ?

4、初涉MySQL物理數(shù)據(jù)存儲(chǔ)格式:一行數(shù)據(jù)在磁盤上是如何存儲(chǔ)的?


那么接著我們可以來思考一下,對(duì)數(shù)據(jù)頁中的每一行數(shù)據(jù),他在磁盤上是怎么存儲(chǔ)的?


其實(shí)這里涉及到一個(gè)概念,就是行格式。我們可以對(duì)一個(gè)表指定他的行存儲(chǔ)的格式是什么樣的,比如我們這里用一個(gè)COMPACT格式。


CREATE TABLE table_name (columns) ROW_FORMAT=COMPACT

ALTER TABLE table_name ROW_FORMAT=COMPACT


你可以在建表的時(shí)候,就指定一個(gè)行存儲(chǔ)的格式,也可以后續(xù)修改行存儲(chǔ)的格式。這里指定了一個(gè)COMPACT行存儲(chǔ)格式,在這種格式下,每一行數(shù)據(jù)他實(shí)際存儲(chǔ)的時(shí)候,大概格式類似下面這樣:


變長字段的長度列表,null值列表,數(shù)據(jù)頭,column01的值,column02的值,column0n的值......


對(duì)于每一行數(shù)據(jù),他其實(shí)存儲(chǔ)的時(shí)候都會(huì)有一些頭字段對(duì)這行數(shù)據(jù)進(jìn)行一定的描述,然后再放上他這一行數(shù)據(jù)每一列的具體的值,這就是所謂的行格式。除了COMPACT以外,還有其他幾種行存儲(chǔ)格式,基本都大同小異。


大家可能對(duì)一行數(shù)據(jù)實(shí)際存儲(chǔ)的時(shí)候,他里面的一些東西到底都是什么含義,感覺都很好奇,大可不必著急,我們明天的文章會(huì)繼續(xù)講解的。


5、今天學(xué)習(xí)的要點(diǎn)總結(jié)


今天我們主要是做了一些承上啟下的復(fù)習(xí)和鞏固,告訴了大家innodb存儲(chǔ)引擎在存儲(chǔ)數(shù)據(jù)的時(shí)候,是通過數(shù)據(jù)頁的方式來組織數(shù)據(jù)的


然后我們初步的開始嘗試切入了MySQL的物理數(shù)據(jù)存儲(chǔ)格式,講解了對(duì)于數(shù)據(jù)頁中的每一行數(shù)據(jù),其實(shí)他都有對(duì)應(yīng)的行格式


接下來,我們將會(huì)深入探索這個(gè)每一行數(shù)據(jù)到底是怎么存儲(chǔ)的。

End

專欄版權(quán)歸公眾號(hào)儒猿技術(shù)窩所有

未經(jīng)許可不得傳播,如有侵權(quán)將追究法律責(zé)任

24 我們寫入數(shù)據(jù)庫的一行數(shù)據(jù),在磁盤上是怎么存儲(chǔ)的?的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
易门县| 册亨县| 平罗县| 封开县| 仲巴县| 桑日县| 宁海县| 蓬莱市| 溧阳市| 黄平县| 元阳县| 应用必备| 陈巴尔虎旗| 黑龙江省| 台安县| 盐池县| 青铜峡市| 马尔康县| 武定县| 西城区| 旌德县| 南木林县| 长沙县| 横峰县| 商洛市| 徐水县| 高淳县| 包头市| 金溪县| 牙克石市| 若尔盖县| 伊宁市| 富平县| 桦川县| 景东| 鹤庆县| 竹溪县| 昌图县| 绥宁县| 泽州县| 黎平县|