一、表的空間是怎么回收的勒葱?
InnoDB包含了兩個部分:表結(jié)構(gòu)定義和數(shù)據(jù)浪汪;在MySQL8.0前表結(jié)構(gòu)是存在以.frm為后綴的文件里,8.0及之后已經(jīng)允許放在系統(tǒng)數(shù)據(jù)表中凛虽,因為表結(jié)構(gòu)占用空間很小死遭。
1.怎么控制InnoDB表的表結(jié)構(gòu)存放位置
innodb_file_per_table : MySQL5.6.6之后默認(rèn)是ON
ON:每個InnDB的表數(shù)據(jù)存在一個以.ibd為后綴的文件中;
OFF:表的數(shù)據(jù)放在系統(tǒng)共享表空間凯旋,也就是跟數(shù)據(jù)字典放在一起呀潭;
建議設(shè)置
建議設(shè)置為ON,因為如果需要刪除表至非,設(shè)置為ON钠署,執(zhí)行drop table 命令也會刪除.ibd文件,會回收表結(jié)構(gòu)的空間荒椭;設(shè)置為OFF雖然把表刪了也不會回收表結(jié)構(gòu)的空間谐鼎。
2.數(shù)據(jù)的刪除流程
DQL(查詢):查詢數(shù)據(jù):select語句(最常用)
DML(操縱):表數(shù)據(jù)的增刪改,insert趣惠、update该面、delete
DDL(定義):對表的增刪改,create信卡、drop、alter
DCL(控制):grant授權(quán)题造、revoke撤消等
TCL(事務(wù)控制):commit事務(wù)提交傍菇、rollback回滾事務(wù)
(1)什么叫數(shù)據(jù)的“空洞”?
數(shù)據(jù)在刪除的時候界赔,表結(jié)構(gòu)InnDB的索引是以B+tree的形式儲存的丢习,當(dāng)刪除某個數(shù)據(jù)時,只會把該子葉子節(jié)點的數(shù)據(jù)標(biāo)記淮悼,不會立即釋放空間咐低,只有有一條記錄的索引等于該值時才會復(fù)用這個位置。
我們直到mysql都是以數(shù)據(jù)頁的形式儲存的袜腥,如果整個數(shù)據(jù)頁都被標(biāo)記见擦,那么新增數(shù)據(jù)在該數(shù)據(jù)頁的范圍值內(nèi),就可以直接復(fù)用。
當(dāng)相鄰兩個數(shù)據(jù)頁的數(shù)據(jù)都比較少時鲤屡,兩個數(shù)據(jù)頁的數(shù)據(jù)會合在一起损痰,騰出一個新的數(shù)據(jù)頁被標(biāo)記為可復(fù)用。
delete命令刪除表時酒来,都會把刪除的位置標(biāo)記卢未,認(rèn)為是可復(fù)用,我們把那些沒有被復(fù)用到的位置稱為空洞堰汉。
(2)怎么解決空洞問題呢辽社?
重建表
2.怎么重建表?
用語句:
alert table t engine=InnoDB
(1)請簡述重建表的過程:
在MySQL5.6之后翘鸭,重建表支持Online DDL(在重建表時滴铅,可以有DDL操作)的操作:
- 建立一個臨時文件,記錄掃描表t的數(shù)據(jù)頁
- 用數(shù)據(jù)頁表t的記錄生成B+tree矮固,記錄臨時文件
- 在生成記錄臨時文件的過程中失息,對表t的操作記錄到日志文件 row log,
-把row log日志文件的記錄寫入到臨時文件的得到邏輯上與表t相同的文件 - 用臨時文件把表t替換
(2)DDL 之前是要拿 MDL 寫鎖的档址,這樣還能叫 Online DDL 嗎盹兢?
在執(zhí)行alert之后是會獲取MDL寫鎖的,但是在復(fù)制數(shù)據(jù)的時候會退化成MDL讀鎖守伸,這個時候是可以修改數(shù)據(jù)的绎秒。
為什么不直接放開MDL鎖呢?
因為要禁止其它線程對表DDL
所以在整個DDL過程來說尼摹,鎖的時間非常短见芹,所以可以看做是Online DDL
(3)在生產(chǎn)中一般怎么使用
在生產(chǎn)中一般數(shù)據(jù)量比較大的數(shù)據(jù)庫來說的話,因為會對整個表掃描和建立臨時文件是非常消耗io和cpu的蠢涝,建議使用Githud開源的gh-ost
gh-ost是什么玄呛?
是一個開源的縮小表空間的工具。
3.DDL online 和 inplace的區(qū)別
DDL online和inplace是包含與被包含的關(guān)系和二,online一定是inplace徘铝,反之亦然。截止到 MySQL 8.0惯吕,添加全文索引(FULLTEXT index)和空間索引 (SPATIAL index) 就屬于這種情況
alter table t add FULLTEXT(field_name);
這個過程是 inplace 的惕它,但會阻塞增刪改操作,是非 Online 的废登。
二淹魄、思考題
假設(shè)現(xiàn)在有人碰到了一個“想要收縮表空間,結(jié)果適得其反”的情況堡距,看上去是這樣的:一個表 t 文件大小為 1TB甲锡;對這個表執(zhí)行 alter table t engine=InnoDB兆蕉;發(fā)現(xiàn)執(zhí)行完成后,空間不僅沒變小搔体,還稍微大了一點兒恨樟,比如變成了 1.01TB。你覺得可能是什么原因呢 疚俱?