我试图在MySQL 5.6.23的RDS实例中减少表的磁盘空间使用。它是一个包含大约800万行和30列的InnoDB表。其中几个列的类型为TEXT NULL DEFAULT NULL。表之所以如此大的原因之一是因为通过一个名为“deleted”的标志列将它们标记为已删除,而不是删除该表中的行。
在阅读了有关存储需求的MySQL文档之后:
http://dev.mysql.com/doc/refman/5.7/en/storage-requirements.html
似乎TEXT字段所需的存储取决于字段中的文本长度,而不是固定大小(L + 2 bytes, where L < 2^16 and where L is the length of the value in bytes)。因此,虽然我在其他地方读到这些字段实际上是固定宽度的,但我处理了大约50,000行标记为已删除的行,并将它们的所有TEXT列值设置为null。
但是,MySQL客户端或AWS控制台RDS接口报告的磁盘空间没有减少。为什么这不释放磁盘空间?
发布于 2015-11-16 21:04:57
当您将列值设置为NULL时,InnoDB必须重新组织记录存储,以减少表使用的磁盘空间总量。如果您的虚拟ALTER不足以使MySQL注意到一种短路的方法来使其实际重建表,或者手动删除、重新创建和重新插入记录,那么您应该会看到减少。OPTIMIZE TABLE也应该这么做。
发布于 2015-12-01 19:45:16
萨沙的回答可能适用,也可能不适用。
将列设置为NULL后,任何已释放的块都可用于未来的INSERTs / UPDATEs。但是,释放的块不会返回给操作系统。块是否被释放取决于很多细节。
TEXT字段的磁盘空间大小既取决于文本的数量,也取决于Row_format (“紧凑”等)。TEXT列可以完全或部分存储在与其余数据分离的块中。
如果您的表是在innodb_file_per_table为ON时创建的,那么OPTIMIZE TABLE将将空闲空间还给操作系统。而SHOW TABLE STATUS将显示出一些值的下降。
如果innodb_file_per_table是OFF,那么释放的up空间将留在ibdata1中,但该文件不会缩小。它只能通过转储所有表、停止mysqld、删除ibdata1、重新启动和重新加载来缩小。(讨厌) OPTIMIZE TABLE会增加ibdata1内部的Data_free。
(假设)这将使表更易于管理,但在一个未缩小的ibdata1中留下了大量的空闲空间。
SET innodb_file_per_table = ON;
ALTER TABLE foo ENGINE=InnoDB;如果您出于其他原因预期ibdata1的增长,那么这样做可能是明智的。否则,它只会使磁盘空间问题更加严重。
https://stackoverflow.com/questions/33744474
复制相似问题