Max*_*ams 1 mysql diskspace rds
今天,当我们的 RDS MySQL 数据库实例上的空间不足时,我们遇到了一些站点紧急情况。这是因为我尝试在拥有 3000 万行的数据库表中填充新添加的 MEDIUMTEXT 列。哎呀。
我认为,使问题变得更加复杂的一件事是,在我意识到是什么导致它耗尽空间并终止了该update进程之后,我试图删除新列,愚蠢地认为这会释放一些空间。
这实际上是行不通的,因为当你在 Mysql 中删除一列时,你不会收回磁盘空间,至少在不做一些额外的清理工作的情况下是这样。
但是,我认为通过增加数据库中临时文件的大小(大概是保存列数据)实际上使事情变得更糟,以使进程可事务化 - 就像一个废纸篓一样,有效地为已删除的数据提供可恢复性。
这使得它的空间更加不足(我通过 AWS 控制台给了它更多的空间)。
所以,这不是一个美好的早晨(早上 7 点我的孩子们也在我耳边尖叫)。
有没有一种方法可以删除一个列,它a)快速,即使对于大型表b)不会产生任何额外的临时数据c)实际上给你一些磁盘空间?
在不暂时占用更多空间的情况下减少存储使用的唯一方法是 DROP TABLE 或 TRUNCATE TABLE,即使这样也只有在您有选择的情况下才会减少空间innodb_file_per_table=ON(从 MySQL 5.6 开始默认启用)。
许多类型的 ALTER TABLE 操作都会创建表的临时副本,从而创建新的表空间。参考https://dev.mysql.com/doc/refman/5.6/en/innodb-create-index-overview.html并注意标有“重建表:是”的每种类型的 ALTER TABLE
重建表意味着创建一个新表,将旧表中的所有数据复制到新表,同时适应新表中列的变化,然后用新表替换旧表,最后删除旧表。对于大表来说这需要时间,并且暂时需要同时存储该表和新表。
基本上,任何更改行大小的更改(例如添加/删除列、更改列的数据类型,甚至更改列的可为空性)都会重建表。没有办法快速删除列或不暂时使用更多空间。
某些其他类型的 ALTER TABLE(例如删除辅助键)会释放表空间中的数据库页,而不重建表。但这些页面仍然由表空间保存,并由后续数据或索引回收。
表空间永远不会收缩。它只能被删除,或者在复制到新表空间时进行碎片整理。
因此,您需要确保至少有足够的可用磁盘空间来存储最大表的第二个副本(如果二进制日志存储在同一卷上,则还要加上二进制日志,但我不知道 RDS 是否将二进制日志存储在同一卷上)体积)。