MySQL|空間碎片化問題處理
一、空間碎片化嚴重案例分享
1.1 問題描述
例項磁碟空間近1個月上漲趨勢明顯,主要是個別日誌表儲存較大且部分表存在空間碎片化的現象。
1.2 處理流程
1、通過日常巡檢以及監控發現某例項磁碟空間近1月上漲趨勢明顯
2、在詢問業務方是否為正常的業務增長外,檢視該例項top表空間的表,排查是否存在異常較大的表
1)檢視資料儲存量較大的schema
SELECT table_Schema , round(SUM((DATA_LENGTH + INDEX_LENGTH + DATA_FREE) / 1024 / 1024), 2) AS Total_Size FROM tables GROUP BY table_schema ORDER BY Total_Size DESC;
2)檢視具體schema下top表的空間使用情況
SELECT table_schema, table_name , round(DATA_LENGTH / 1024 / 1024, 2) AS Data_Size , round(INDEX_LENGTH / 1024 / 1024, 2) AS Index_Size , round(DATA_FREE / 1024 / 1024, 2) AS Free_Size FROM tables WHERE table_schema = 'db_rim' ORDER BY Data_Size DESC LIMIT 10;
3、從以上截圖中我們可以得到資訊:db_rim庫庫下,rim_user_msg_log表的資料量很大,可檢視是否可對該表中無效的資料進行清理?rim_user_msg_analyse這張表的碎片化將盡17G,可考慮對這些碎片化空間進行回收
4、最終採取的處理方法為:rim_user_msg_log表直接清空,rim_user_msg_analyse進行碎片化回收
1)清理前
2)清理後
3)例項磁碟空間使用趨勢
二、表資料量過大清理案例
2.1 問題描述
通過對TOP表資料量的監控,我們可以看到sys_rest_server_log的資料量已經達到7000w,除空間佔用外,我們更關注的是該表對資料庫帶來的效能隱患。若業務上或者人為不當的查詢該表資料,其操作的資源消耗在一定程度上一定會對正常業務造成影響。
2.2 問題處理
1、該表當前的表現主要有兩點,一點是某瞬時寫入量極大,另外一點是表日增可達到300w記錄數。對於資料庫而言這種錶行為或業務設計是不合理的,我們需要搞清楚該表究竟是用來記錄哪些資訊,業務設計是否合理?
通過觀察表資料以及與相關開發人員溝通,我們得知該表會記錄應用端所有的介面呼叫資訊,我們所觀察到的資料增長尖峰也正是由於業務量上漲而導致該表瞬間併發寫入大量日誌資訊。
2、對於這種大資料量的日誌記錄資訊,建議最好使用ELK這種日誌分析服務,而不是使用資料庫進行儲存
3、限於開發人員開發能力有限,無法改造業務架構。針對該表日增長、瞬間增長都極大的情況,我們與開發人員溝通該表記錄的資料是否可從源端上進行減少。只記錄重要資訊、非重要資訊的介面日誌入庫進行遮蔽
4、確定表資料記錄可從最根本減產後,我們仍需要對目前7000w的資料進行處理,將歷史無效資料進行清理,並制定合適的資料清理策略
5、無效歷史資料清理/資料清理策略
1、建立備份表: create table sys_rest_server_log_bak_0228_1 like sys_rest_server_log;
2、表名替換 將源表sys_rest_server_log重新命名為備份表,備份表sys_rest_server_log_bak_0208_1重新命名為源表sys_rest_server_log,業務資料會寫入空的新表,但是在rename期間這部分業務日誌寫入會失敗【需關注】 rename table sys_rest_server_log to sys_rest_server_log_bak_0228_2,sys_rest_server_log_bak_0228_1 to sys_rest_server_log;
3、將備份表sys_rest_server_log_bak_0208_2中的仍然需要的資料重新寫入到sys_rest_server_log,分批次寫入,sys_rest_server_log保留近15天資料。程式上可保證主鍵fd_id唯一,避免主鍵衝突。 insert into sys_rest_server_log select * from sys_rest_server_log_bak_0228_2 where fd_start_time between 'xxx' and 'xxx';
4、調整平臺數據清理策略,將服務執行日誌備份天數改為15天,清除服務執行日誌備份天數改為30天
5、sys_rest_server_log_bak_0228_2表保留80+天記錄資料,暫時可以不做清理,等程式維護的sys_rest_server_log_backup有完備的資料後,將sys_rest_server_log_bak_0228_2表清除;
三、總結歸納
2.1 如何判斷表碎片化問題是否嚴重
表資料的頻繁更新容易對錶空間造成一定的碎片化,我們可以通過information_schema.table表中的data_free欄位判斷該表碎片化是否嚴重。
2.2 如何處理碎片化問題
optimize table tableName; alter table tablName engine=innodb;
2.3 大表歷史資料清楚過程中的關注點
1、通過建立bak表與源表進行rename替換,rename期間會造成業務對該表資料寫入失敗
2、bak表建立的時需關注primayr key
1)程式上保證主鍵唯一可不需要關注
2)若主鍵使用自增長,建議在建立bak表建立時提高當前的auto_increment指,空餘一部分buffer空間,保證後續將源表歷史資料寫入rename後的新表時主鍵不衝突
3、對於此類經常需要進行資料清理的表,建議使用分割槽表進行儲存,後續對資料的處理僅僅需要刪除指定分割槽
更多技術資訊請檢視雲掣官網https://www.dtstack.com/dtsmart/