MySQL實(shí)戰(zhàn)45講Day12----為什么表數(shù)據(jù)刪掉一半,表文件大小不變

一湾笛、參數(shù)innodb_file_per_table:

??表數(shù)據(jù)既可以存在共享表空間里饮怯,也可以是單獨(dú)的文件。這個(gè)行為是由參數(shù)innodb_file_per_table控制的:
這個(gè)參數(shù)設(shè)置為OFF表示的是嚎研,表的數(shù)據(jù)放在系統(tǒng)共享表空間蓖墅,也就是跟數(shù)據(jù)字典放在一起;
這個(gè)參數(shù)設(shè)置為ON表示的是临扮,每個(gè)InnoDB表數(shù)據(jù)存儲(chǔ)在一個(gè)以 .ibd為后綴的文件中论矾。

從MySQL 5.6.6版本開始,它的默認(rèn)值就是ON了杆勇。
建議不論使用MySQL的哪個(gè)版本贪壳,都將這個(gè)值設(shè)置為ON。因?yàn)椋?strong>一個(gè)表單獨(dú)存儲(chǔ)為一個(gè)文件更容易管理靶橱,而且不需要這個(gè)表的時(shí)候寥袭,通過drop table命令路捧,系統(tǒng)就會(huì)直接刪除這個(gè)文件。而如果是放在共享表空間中传黄,即使表刪掉了杰扫,空間也是不會(huì)回收的。

二膘掰、數(shù)據(jù)刪除流程:

??InnoDB的數(shù)據(jù)是按頁存儲(chǔ)的章姓,那么如果刪掉了一個(gè)數(shù)據(jù)頁上的所有記錄,那么整個(gè)數(shù)據(jù)頁就可以被復(fù)用了识埋。但是凡伊,數(shù)據(jù)頁的復(fù)用跟記錄的復(fù)用是不同的。記錄的復(fù)用窒舟,只限于符合范圍條件的數(shù)據(jù)系忙。而當(dāng)整個(gè)頁從B+樹里面摘掉以后,可以復(fù)用到任何位置惠豺。如果相鄰的兩個(gè)數(shù)據(jù)頁利用率都很小银还,系統(tǒng)就會(huì)把這兩個(gè)頁上的數(shù)據(jù)合到其中一個(gè)頁上,另外一個(gè)數(shù)據(jù)頁就被標(biāo)記為可復(fù)用洁墙。如果我們用delete命令把整個(gè)表的數(shù)據(jù)刪除蛹疯,所有的數(shù)據(jù)頁都會(huì)被標(biāo)記為可復(fù)用。但是磁盤上热监,文件不會(huì)變小捺弦。因?yàn)?strong>delete命令其實(shí)只是把記錄的位置,或者數(shù)據(jù)頁標(biāo)記為了“可復(fù)用”孝扛,但磁盤文件的大小是不會(huì)變的列吼。也就是說,通過delete命令是不能回收表空間的疗琉。這些可以復(fù)用冈欢,而沒有被使用的空間歉铝,看起來就像是“空洞”盈简。實(shí)際上,不止是刪除數(shù)據(jù)會(huì)造成空洞太示,插入數(shù)據(jù)也會(huì)柠贤。如果數(shù)據(jù)是按照索引遞增順序插入的,那么索引是緊湊的类缤。但如果數(shù)據(jù)是隨機(jī)插入的(而且插入的數(shù)據(jù)是在該數(shù)據(jù)頁的數(shù)據(jù)范圍之內(nèi)臼勉,比如說PageA中的數(shù)據(jù)是從0到10,此時(shí)嵌纲,數(shù)據(jù)頁雖然有未被使用的空間盛险,但由于數(shù)據(jù)頁的頭和尾都被插入了數(shù)據(jù),所以再插入8的時(shí)候实愚,就會(huì)把8~10的數(shù)據(jù)移到另一個(gè)數(shù)據(jù)頁中瓢谢,同時(shí)將之前的數(shù)據(jù)頁中移過來的數(shù)據(jù)標(biāo)為可復(fù)用)畸写,就可能造成索引的數(shù)據(jù)頁分裂。同時(shí)氓扛,更新索引上的值枯芬,可以理解為刪除一個(gè)舊的值,再插入一個(gè)新值采郎。這也會(huì)造成空洞的千所。也就是說,經(jīng)過大量增刪改的表蒜埋,都是可能是存在空洞的淫痰。所以,如果能夠把這些空洞去掉整份,就能達(dá)到收縮表空間的目的黑界。

三、收縮表空間的方法:

1皂林、重建表可以達(dá)到這樣的目的朗鸠。
2、重建表的方法:

??假設(shè)表A是需要收縮的表础倍,新建一個(gè)與表A結(jié)構(gòu)相同的表B烛占,然后按照主鍵ID遞增的順序,把數(shù)據(jù)一行一行地從表A里讀出來再插入到表B中沟启。由于表B是新建的表忆家,所以表A主鍵索引上的空洞,在表B中就都不存在了德迹。顯然地芽卿,表B的主鍵索引更緊湊,數(shù)據(jù)頁的利用率也更高胳搞。如果把表B作為臨時(shí)表卸例,數(shù)據(jù)從表A導(dǎo)入表B的操作完成后,用表B替換A肌毅,從效果上看筷转,就起到了收縮表A空間的作用。這里悬而,你可以使用alter table A engine=InnoDB命令來重建表呜舒。在MySQL 5.5版本之前,這個(gè)命令的執(zhí)行流程跟我們前面描述的差不多笨奠,區(qū)別只是這個(gè)臨時(shí)表B不需要你自己創(chuàng)建袭蝗,MySQL會(huì)自動(dòng)完成轉(zhuǎn)存數(shù)據(jù)唤殴、交換表名、刪除舊表的操作到腥。如果在這個(gè)過程中眨八,有新的數(shù)據(jù)要寫入到表A的話,就會(huì)造成數(shù)據(jù)丟失左电。因此廉侧,在整個(gè)DDL過程中,表A中不能有更新篓足。也就是說段誊,這個(gè)DDL不是Online的。

改鎖表DDL

3栈拖、MySQL 5.6版本開始引入的Online DDL连舍,對(duì)上述的這個(gè)操作流程做了優(yōu)化。引入了Online DDL之后涩哟,重建表的流程:

?a索赏、建立一個(gè)臨時(shí)文件,掃描表A主鍵的所有數(shù)據(jù)頁贴彼;
?b潜腻、用數(shù)據(jù)頁中表A的記錄生成B+樹,存儲(chǔ)到臨時(shí)文件中器仗;
?c融涣、生成臨時(shí)文件的過程中,將所有對(duì)A的操作記錄在一個(gè)日志文件(row log)中精钮,對(duì)應(yīng)的是圖中state2的狀態(tài)威鹿;
?d、臨時(shí)文件生成后轨香,將日志文件中的操作應(yīng)用到臨時(shí)文件忽你,得到一個(gè)邏輯數(shù)據(jù)上與表A相同的數(shù)據(jù)文件,對(duì)應(yīng)的就是圖中state3的狀態(tài)臂容;
?e科雳、用臨時(shí)文件替換表A的數(shù)據(jù)文件。

Online DDL

由圖可以看出策橘,Online DDL和改鎖表DDL的區(qū)別是由于日志文件記錄和重放操作這個(gè)功能的存在炸渡,這個(gè)方案在重建表的過程中娜亿,允許對(duì)表A做增刪改操作丽已。

4、Online 和 inplace的區(qū)別:

??a买决、對(duì)于改鎖表DDL來說沛婴,我們把表A中的數(shù)據(jù)導(dǎo)出來的存放位置叫作tmp_table吼畏。這是一個(gè)臨時(shí)表,是在server層創(chuàng)建的嘁灯。而對(duì)于Online DDL泻蚊,根據(jù)表A重建出來的數(shù)據(jù)是放在“tmp_file”里的,這個(gè)臨時(shí)文件是InnoDB在內(nèi)部創(chuàng)建出來的丑婿。整個(gè)DDL過程都在InnoDB內(nèi)部完成性雄。對(duì)于server層來說,沒有把數(shù)據(jù)挪動(dòng)到臨時(shí)表羹奉,是一個(gè)“原地”操作秒旋,這就是“inplace”名稱的來源。(判斷相對(duì) Server 層沒有新建臨時(shí)表一種的方法:看命令執(zhí)行后影響的行數(shù)诀拭,沒有新建臨時(shí)表的話新建的行數(shù)是0迁筛。 )
?b、DDL過程如果是Online的耕挨,就一定是inplace的细卧;
?c、反過來則未必筒占,也就是說inplace的DDL贪庙,有可能不是Online的。比如說截止到MySQL 8.0中的添加全文索引(FULLTEXT index)和空間索引(SPATIAL index)就屬于這種情況翰苫。

5插勤、optimize table、analyze table和alter table這三種方式重建表的區(qū)別:

?a革骨、從MySQL 5.6版本開始农尖,alter table t engine = InnoDB(也就是recreate)默認(rèn)的就是上面Online DDL的流程了;
?b良哲、analyze table t 其實(shí)不是重建表盛卡,只是對(duì)表的索引信息做重新統(tǒng)計(jì),沒有修改數(shù)據(jù)筑凫,這個(gè)過程中加了MDL讀鎖滑沧;
?c、optimize table t 等于recreate+analyze巍实。

四滓技、收縮表空間,結(jié)果適得其反的原因:

?a棚潦、在重建表的時(shí)候令漂,InnoDB不會(huì)把整張表占滿,每個(gè)頁留了1/16給后續(xù)的更新用。也就是說叠必,其實(shí)重建表之后不是“最”緊湊的荚孵。假設(shè)此時(shí)的表本來就很緊湊,沒能整出多少剩余空間纬朝。重新收縮的過程中收叶,頁會(huì)按90%滿的比例來重新整理頁數(shù)據(jù)(10%留給UPDATE使用),未整理之前頁已經(jīng)占用90%以上共苛,收縮之后判没,文件就反而變大了。
?b隅茎、這個(gè)表哆致,本身就已經(jīng)沒有空洞的了,比如說剛剛做過一次重建表操作患膛。在DDL期間摊阀,如果剛好有外部的DML在執(zhí)行,這期間可能會(huì)引入一些新的空洞踪蹬。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末胞此,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子跃捣,更是在濱河造成了極大的恐慌漱牵,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疚漆,死亡現(xiàn)場(chǎng)離奇詭異酣胀,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)娶聘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門闻镶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人丸升,你說我怎么就攤上這事铆农。” “怎么了狡耻?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵墩剖,是天一觀的道長。 經(jīng)常有香客問我夷狰,道長岭皂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任沼头,我火速辦了婚禮爷绘,結(jié)果婚禮上书劝,老公的妹妹穿的比我還像新娘。我一直安慰自己揉阎,他們只是感情好庄撮,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布背捌。 她就那樣靜靜地躺著毙籽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪毡庆。 梳的紋絲不亂的頭發(fā)上坑赡,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音么抗,去河邊找鬼毅否。 笑死,一個(gè)胖子當(dāng)著我的面吹牛蝇刀,可吹牛的內(nèi)容都是我干的螟加。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼吞琐,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼捆探!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起站粟,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤黍图,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后奴烙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體助被,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年切诀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了揩环。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡幅虑,死狀恐怖检盼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情翘单,我是刑警寧澤吨枉,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站哄芜,受9級(jí)特大地震影響貌亭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜认臊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一圃庭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦剧腻、人聲如沸拘央。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽灰伟。三九已至,卻和暖如春儒旬,著一層夾襖步出監(jiān)牢的瞬間栏账,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國打工栈源, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留挡爵,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓甚垦,卻偏偏與公主長得像茶鹃,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子艰亮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容