我有一张由厚重的斑点组成的桌子,我想对它进行一些测试。
我知道innodb不会回收已删除的空间,所以我决定通过更新自己的值而不是创建新记录来重用现有记录。
但是我注意到,无论是删除和插入新条目,还是在现有的ROW上进行UPDATE,InnoDB都在不断增长。
假设我有100行,每个存储500KB的信息,My InnoDB大小为10MB,现在当我在所有行上调用UPDATE(没有插入/不删除)时,innodb每次运行都会增加~8MB。我所做的就是每行存储500KB的数据,几乎没有修改,并且blob的大小是固定的。
我该怎么做才能防止这种情况发生?
我知道优化表,但我不能这样做,因为在常规使用时,表将大到60-100GB,并且运行优化将停止整个服务器。
答案 0 :(得分:5)
但是我注意到,无论是删除和插入新条目,还是在现有的ROW上进行UPDATE,InnoDB都在不断增长。
InnoDB
是一个多版系统。
这意味着每次更新或删除行时,行的先前版本都会复制到名为rollback segment
的特殊位置。原始记录将使用新数据(如果是UPDATE
)重写或标记为已删除(如果是DELETE
)。
如果您执行事务回滚或执行并发SELECT
语句(必须查看以前的版本,因为尚未提交新版本),则会从rollback segment
中检索数据。 / p>
这个问题是InnoDB
表空间永远不会收缩。如果表空间已满,则分配新空间。来自提交事务的回滚信息占用的空间也可以重用,但如果表空间已满,它将被扩展,这是永久性的。
除了备份整个数据库,删除并重新创建ibdata*
文件并从备份中恢复之外,没有受支持的方法来缩小InnoDB
文件。
即使您使用innodb_file_per_table
选项,回滚表空间仍存储在共享的ibdata*
文件中。
但请注意,表空间占用的空间和表空间占用的空间是不同的东西。可以通过运行OPTIMIZE
来缩小表,这将使它们更紧凑(在表空间内),但表空间本身不能缩小。
答案 1 :(得分:2)