Mysql在生產環境中快速清理資料及表空間釋放
Mysql資料快速清理及表空間釋放
1、TABLES表主要欄位說明:
MySQL的 information_schema 資料庫中的TABLES 表記錄了MySQL資料庫中每個表佔用的空間、表記錄的行數,更新時間,說明等,這個表主要欄位如下:
TABLE_SCHEMA : 資料庫名
TABLE_NAME:表名
ENGINE:所使用的儲存引擎
TABLES_ROWS:記錄數,即表的行數
DATA_LENGTH:資料大小
INDEX_LENGTH:索引大小
CREATE_TIME:建立時間
UPDATE_TIME:最近更新時間
DATA_FREE:該引數與mysql碎片有關,如果是共享表空間,該欄位表示共享表空間的大小而非資料的大小。只有使用獨佔表空間時,該欄位才表示該表的剩餘空間;
說明:當MySQL從列表中刪除一行內容,該段空間就會被留空。在一段時間內執行大量刪除操作後,往往會使碎片空間變得比儲存列表內容所使用的空間更大。
通俗的講:Data_free欄位即為多佔的物理空間,通過‘show table status’可以檢視指定表的Data_free欄位,對應的值就是多佔用的物理空間,drop表重建或是重新匯入可以釋放這部分空間。
mysql> use hellodb
mysql> show table status like 'students%';
+-----------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+-----------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
| students | InnoDB | 10 | Compact | 27 | 606 | 16384 | 0 | 32768 | 0 | 28 | 2017-11-28 15:31:15 | NULL | NULL | utf8_general_ci | NULL | | |
| students1 | InnoDB | 10 | Compact | 8 | 2048 | 16384 | 0 | 32768 | 0 | 9 | 2018-06-11 20:16:53 | NULL | NULL | utf8_general_ci | NULL | | |
+-----------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+-----------------
此時可以使用optimize整理表的碎片:
注意:該操作執行的時候會把該表格先寫入一個tmp臨時表,所以磁碟剩餘空間必須大於表空間,否則會執行失敗。
mysql> optimize table classes,students;
5.6.X以前的版本會提示該表不支援optimize,5.6.X的版本已經支援Innodb了。
2、生產案例:釋放表空間
思路1:
資料不刪除:備份表,drop表,匯入備份的表到資料庫;
show table status like 'oldtb%'; -->重點關注Data_free欄位,對應的值就是多佔用的物理空間,即碎片空間
mysqldump -uroot -p123456 mydb oldtb >/mnt/oldtb.sql -->匯出可以恢復系統空間的表格。
drop table oldtb; -->drop舊錶釋放表空間
source /mnt/oldtb.sql; -->匯出備份的表到資料庫。
show table status like 'oldtb%'; -->對比恢復前後的狀態,重點關注Data_free欄位
該操作通過多次單表操作,多次對錶進行備份和恢復,從而釋放了碎片空間,適用於不允許停機的業務。
如果系統業務允許在一段時間內停止服務,可以備份整個資料庫,然後清空,重建mysql資料根目錄,然後恢復整個資料庫。
思路2 :
刪除部分舊資料:適用於可以刪除部分舊資料的場景
create table newtb like oldtb if no exist; -->新建newtb表,表結構同舊錶
insert into newtb select * from oldtb where time > 'xxx' and time<='xxx';
-->備份表的新資料,可以按時間段備份最近一個月或半個月
drop table oldtb; -->drop舊錶釋放表空間
alter tables newtb rename to oldtb; -->重新命名新表“newdtb”
思路3:直接優化表:optimize table 表名;
select table_name,data_free,engine from information_schema.tables where table_schema='mydb';
-->檢視庫中各表data_free值,單位是位元組,data_free/1024/1024/1024即為理論上釋放後可以恢復空間G。
show table status like 'oldtb'; -->單個表的data_free大小
mysql> OPTIMIZE TABLE hellodb.students;
-->顯示不支援,實際上已進行重建和分析,空間已經回收
+------------------+----------+----------+-------------------------------------------------------------------+
| Table | Op | Msg_type | Msg_text |
+------------------+----------+----------+-------------------------------------------------------------------+
| hellodb.students | optimize | note | Table does not support optimize, doing recreate + analyze instead |
| hellodb.students | optimize | status | OK |
+------------------+----------+----------+-------------------------------------------------------------------+
2 rows in set (0.08 sec)