将文本值设置为null不会减少MySQL表的磁盘空间使用

将文本值设置为null不会减少MySQL表的磁盘空间使用,mysql,amazon-web-services,innodb,diskspace,rds,Mysql,Amazon Web Services,Innodb,Diskspace,Rds,我试图减少MySQL 5.6.23的RDS实例中表的磁盘空间使用。这是一个InnoDB表,大约有800万行和30列。一些列的类型为TEXT NULL DEFAULT NULL。该表如此之大的原因之一是,它们不是从该表中删除行,而是通过名为“deleted”的标志列标记为deleted 阅读有关存储要求的MySQL文档后: 似乎文本字段所需的存储取决于字段中文本的长度,而不是固定大小(L+2字节,其中L

我试图减少MySQL 5.6.23的RDS实例中表的磁盘空间使用。这是一个InnoDB表,大约有800万行和30列。一些列的类型为
TEXT NULL DEFAULT NULL
。该表如此之大的原因之一是,它们不是从该表中删除行,而是通过名为“deleted”的标志列标记为deleted

阅读有关存储要求的MySQL文档后:

似乎
文本
字段所需的存储取决于字段中文本的长度,而不是固定大小(
L+2字节,其中L<2^16,其中L是以字节为单位的值的长度
)。因此,尽管我在别处读到这些字段实际上是固定宽度的,但我处理了大约50000行标记为已删除的行,并将它们的
TEXT
列值设置为null


但是,MySQL客户端或AWS控制台RDS接口报告的磁盘空间没有减少。为什么没有释放磁盘空间?

当您将列值设置为NULL时,InnoDB必须重新组织记录存储以减少表使用的磁盘空间总量。如果您创建了一个虚拟ALTER表,但该表的虚拟性不足以让MySQL注意到一种短路方式,从而使其实际重建表,或者手动删除、重新创建并重新插入记录,那么应该会看到减少<代码>优化表格也应该这样做。

萨沙的答案可能适用,也可能不适用

将列设置为
NULL
后,任何释放的块都可用于将来的
插入
/
更新
。但是释放的块不会返回给操作系统。块是否被释放取决于很多细节

文本
字段的磁盘空间量取决于文本量和行格式(“压缩”等)。
TEXT
列可以全部或部分存储在与其余数据分开的块中

如果您的表是在
innodb\u file\u per\u table
处于
状态时创建的,则
OPTIMIZE table
会将可用空间返回操作系统。而
SHOW TABLE STATUS
将显示一些值的减少

如果每个表的
innodb\u文件关闭
,则在
ibdata1
中保留释放的空间,但该文件不会缩小。它只能通过转储所有表来缩小;停止mysqld;删除ibdata1;重新启动;重新加载(糟糕.
优化表
将增加
内的免费数据
ibdata1

(假设禁用)这将使表更易于管理,但在未缩小的
ibdata1
中保留大量可用空间:

SET innodb_file_per_table = ON;
ALTER TABLE foo ENGINE=InnoDB;
如果您出于其他原因预期ibdata1的增长;这样做可能是明智的。否则,它只会使磁盘空间问题变得更糟