最近面試,還真有一個面試官,問到我以前遇到過的一個線上故障問題解決方案(當面試官說出口時,我暗自慶幸還好我遇到過......),以下。mysql
最近有個上位機獲取下位機上報數據的項目,因爲上報頻率比較頻繁且數據量大,致使數據增加過快,磁盤佔用多。面試
爲了節約成本,按期進行數據備份,並經過delete刪除表記錄。sql
明明已經執行了delete,可表文件的大小卻沒減少,使人費解數據庫
項目中使用Mysql做爲數據庫,對於表來講,通常爲表結構和表數據。表結構佔用空間都是比較小的,通常都是表數據佔用的空間。數據結構
當咱們使用 delete刪除數據時,確實刪除了表中的數據記錄,但查看錶文件大小卻沒什麼變化。spa
凡是使用過mysql,對B+樹確定是有所耳聞的,MySQL InnoDB 中採用了 B+ 樹做爲存儲數據的結構,也就是常說的索引組織表,而且數據時按照頁來存儲的。所以在刪除數據時,會有兩種狀況:線程
好比想要刪除 R4 這條記錄:設計
InnoDB 直接將 R4 這條記錄標記爲刪除,稱爲可複用的位置。若是以後要插入 ID 在 300 到 700 間的記錄時,就會複用該位置。因而可知,磁盤文件的大小並不會減小。code
通用刪除整頁數據也將記錄標記刪除,數據就複用用該位置,與刪除默寫記錄不一樣的是,刪除整頁記錄,當後來插入的數據不在原來的範圍時,均可以複用位置,而若是隻是刪除默寫記錄,是須要插入數據符合刪除記錄位置的時候才能複用。索引
所以,不管是數據行的刪除仍是數據頁的刪除,都是將其標記爲刪除的狀態,用於複用,因此文件並不會減少。
DELETE只是將數據標識位刪除,並無整理數據文件,當插入新數據後,會再次使用這些被置爲刪除標識的記錄空間,可使用OPTIMIZE TABLE來回收未使用的空間,並整理數據文件的碎片。
OPTIMIZE TABLE 表名;
注意:OPTIMIZE TABLE只對MyISAM, BDB和InnoDB表起做用。
另外,也能夠執行經過ALTER TABLE重建表
ALTER TABLE 表名 ENGINE=INNODB
有人會問OPTIMIZE TABLE和ALTER TABLE有什麼區別?
alter table t engine = InnoDB(也就是recreate),而optimize table t 等於recreate+analyze
最後,再說一下Online DDL,dba的平常工做確定有一項是ddl變動,ddl變動會鎖表,這個能夠說是dba心中永遠的痛,特別是執行ddl變動,致使庫上大量線程處於「Waiting for meta data lock」狀態的時候。所以在 5.6 版本後引入了 Online DDL。
Online DDL推出之前,執行ddl主要有兩種方式copy方式和inplace方式,inplace方式又稱爲(fast index creation)。相對於copy方式,inplace方式不拷貝數據,所以較快。可是這種方式僅支持添加、刪除索引兩種方式,並且與copy方式同樣須要全程鎖表,實用性不是很強。Online方式與前兩種方式相比,不只能夠讀,還能夠支持寫操做。
執行online DDL語句的時候,使用ALGORITHM和LOCK關鍵字,這兩個關鍵字在咱們的DDL語句的最後面,用逗號隔開便可。示例以下:
ALTER TABLE tbl_name ADD COLUMN col_name col_type, ALGORITHM=INPLACE, LOCK=NONE;
執行DDL操做時,ALGORITHM選項能夠不指定,這時候MySQL按照INSTANT、INPLACE、COPY的順序自動選擇合適的模式。也能夠指定ALGORITHM=DEFAULT,也是一樣的效果。若是指定了ALGORITHM選項,但不支持的話,會直接報錯。
OPTIMIZE TABLE 和 ALTER TABLE 表名 ENGINE=INNODB都支持Oline DDL,但依舊建議在業務訪問量低的時候使用
delete 刪除數據時,其實對應的數據行並非真正的刪除,僅僅是將其標記成可複用的狀態,因此表空間不會變小。
能夠重建表的方式,快速將delete數據後的表變小(OPTIMIZE TABLE 或ALTER TABLE),在 5.6 版本後,建立表已經支持 Online 的操做,但最好是在業務低峯時使用。
來源:https://www.toutiao.com/i6935...