1. 程式人生 > >Mysql在生產環境中快速清理資料及表空間釋放

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)