如何回收MySql磁盘空间

Ram*_*ams 6 mysql database

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

在每一行插入之后,我做一些处理然后在我真的不需要这个列之后。

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

MySql 服务器详细信息

服务器版本:5.7

引擎:InnoDB

托管:谷歌云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 |
+--------------------+---------------------+------------------+
Run Code Online (Sandbox Code Playgroud)

谢谢

Bil*_*win 6

编辑:从下面的评论看来,用户的二进制日志是罪魁祸首。假设 MySQL 实例使用基于行的复制,那么在进行大量 DELETE 操作后,二进制日志会很大,这是有道理的。

\n
\n

答案很复杂。

\n

您可以使用 NULL 而不是实际值来节省空间。InnoDB 每行每列仅使用 1 位来指示该值为 NULL(有关详细信息,请参阅我对/sf/answers/16164641/的旧答案)。

\n

但这只会在存储该行的页面中腾出空间。每个页面必须仅存储来自同一个表的行。因此,如果将其中一堆设置为 NULL,则会在该页中腾出空间,该空间仅可用于该表的后续插入后续插入。它不会使用属于其他表的行的间隙。

\n

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

\n

我不确定这个细节,你必须阅读Jeremey Cole 对 InnoDB 存储的研究才能知道答案。这是摘录:

\n
\n

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

\n

用户记录按照插入的顺序添加到页面正文中(并且可能会占用以前删除的记录中的现有可用空间),并使用 \xe2\x80\x9cnext 记录\xe2\x80 按键按升序进行单链接每个记录头中的 \x9d 指针。

\n
\n

目前还不太清楚是否可以乱序插入行并重用页面上的空间。

\n

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

\n

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

\n

删除不需要的行,然后优化表会更有效。这将消除整个页面,而不是让它们支离破碎。

\n

  • 我确实优化了表,但它仍然没有回收可用磁盘空间。我已经更新了我的问题,请检查。 (2认同)