如何回收MySql磁盘空间

时间:2018-01-07 18:01:25

标签: mysql database

我在MySql服务器中有一个表,该表包含大约1M行。仅因为一个列表每天占用更多磁盘空间。此列的数据类型为Mediumblob。表大小约为90 GB。

每次插入行后,我都会进行一些处理,然后我才真正需要这个列。

对于这一列,如果我在处理完行后将值设置为NULL,MySql是否会利用这个空白空间进行下一行插入?

MySql Server详细信息

服务器版本:5.7

引擎:InnoDB

托管:Google Cloud Sql

编辑1 : 我从表中删除了90%的行,然后运行了OPTIMIZE TABLE table_name 但它只减少了4GB的磁盘空间,并且没有回收可用磁盘空间。

编辑2 我甚至删除了我的数据库并创建了新的数据库和表,但MySql服务器仍然显示80GB的磁盘空间。 MySQL服务器的所有数据库的大小

SELECT table_schema "database name",
         sum( data_length + index_length ) / 1024 / 1024 "database size in MB",
         sum( data_free )/ 1024 / 1024 "free space in MB"
     FROM information_schema.TABLES
     GROUP BY table_schema; 

+--------------------+---------------------+------------------+
| database name      | database size in MB | free space in MB |
+--------------------+---------------------+------------------+
| information_schema |          0.15625000 |      80.00000000 |
| app_service        |         15.54687500 |       4.00000000 |
| mysql              |          6.76713467 |       2.00000000 |
| performance_schema |          0.00000000 |       0.00000000 |
| sys                |          0.01562500 |       0.00000000 |
+--------------------+---------------------+------------------+

由于

1 个答案:

答案 0 :(得分:1)

编辑:从下面的评论中可以看出,用户的二进制日志是罪魁祸首。在很多DELETE之后,二进制日志会很大,假设MySQL实例使用基于行的复制,这是有意义的。

答案很复杂。

您可以使用NULL而不是实际值来节省空间。 InnoDB每行每列仅使用1位来表示该值为NULL(有关详细信息,请参阅我对https://stackoverflow.com/a/230923/20860的旧答案)。

但这只会在存储该行的页面中留出空间。每个页面只能存储同一个表中的行。因此,如果您将其中的一组设置为NULL,则会在该页面中创建空间,该空间可用于后续插入仅适用于该表。它不会对属于其他表的行使用间隙。

它仍然可能无法重复用于您的mediumblob表的任何行,因为InnoDB以主键顺序存储行。给定表的页面不必是连续的,但我猜测页面中的行可能是连续的。换句话说,您可能无法在页面中的主键随机顺序中插入行。

我确实不知道这个细节,你必须阅读Jeremey Cole's research on InnoDB storage才能知道答案。这是一段摘录:

  

用户记录的实际磁盘格式将在以后的文章中描述,因为它相当复杂,本身需要冗长的解释。

     

用户记录按插入顺序添加到页面正文中(并且可以从先前删除的记录中获取现有可用空间),并使用每个记录中的“下一条记录”指针按键按升序单链接报头中。

仍然不太清楚行是否可以按顺序插入,并重用页面上的空间。

因此,您可能只会严重破坏页面,并且无论如何都会将具有高主键值的新行添加到其他页面。

如果您不时使用OPTIMIZE TABLE,您可以更好地回收空间,这将有效地将整个表重写为新页面。这个可能重新打包行,如果您将值更改为NULL,则会在每个页面中插入更多行。

删除不需要的行会更有效,然后是OPTIMIZE TABLE。这将消除整个页面,而不是让它们分散。