【问题标题】:why does InnoDB keep on growing without for every update?为什么 InnoDB 在没有每次更新的情况下继续增长?
【发布时间】:2010-12-28 13:10:02
【问题描述】:

我有一张由大块组成的表,我想对其进行一些测试。

我知道 innodb 不会回收已删除的空间,因此我决定通过更新其自己的值而不是创建新记录来重用现有记录。

但我注意到,无论是删除并插入新条目,还是对现有 ROW 进行更新,InnoDB 都在不断增长。

假设我有 100 行,每行存储 500KB 的信息,我的 InnoDB 大小为 10MB,现在当我对所有行调用 UPDATE(不插入/不删除)时,innodb 每次运行都会增长约 8MB。我所做的只是在每行中准确存储 500KB 的数据,几乎没有修改,并且 blob 的大小是固定的。

我能做些什么来防止这种情况发生?

我知道优化表,但我不能这样做,因为在正常使用时,表将是 60-100GB 大,运行优化只会让整个服务器停止。

【问题讨论】:

    标签: mysql innodb


    【解决方案1】:

    但我注意到,无论是删除并插入新条目,还是对现有 ROW 进行更新,InnoDB 都在不断增长。

    InnoDB 是一个多版本系统。

    这意味着每次更新或删除一行时,该行的先前版本都会被复制到一个名为 rollback segment 的特殊位置。原始记录被新数据重写(在UPDATE 的情况下)或标记为已删除(在DELETE 的情况下)。

    如果您执行事务回滚或执行并发SELECT 语句(必须查看以前的版本,因为新版本尚未提交),则从rollback segment 检索数据。

    问题在于InnoDB 表空间从不缩小。如果表空间已满,则分配新空间。已提交事务的回滚信息所占用的空间也可以重复使用,但如果表空间已满,它将被扩展,这是永久性的。

    除了备份整个数据库、删除并重新创建 InnoDB 文件以及从备份中恢复之外,没有支持的方法来缩小 ibdata* 文件。

    即使您使用innodb_file_per_table 选项,回滚表空间仍然存储在共享的ibdata* 文件中。

    但请注意,表占用的空间和表空间占用的空间是不同的东西。可以通过运行OPTIMIZE 来收缩表,这将使它们更紧凑(在表空间内),但表空间本身不能收缩。

    【讨论】:

    • 感谢您的深入解释,如果数据将被修改,我必须找到一些以后的方法来存储大量数据,如果可能的话,是否有一些简单的方法来回收已删除的行?
    【解决方案2】:

    您可以通过运行优化查询来减小表大小

    OPTIMIZE TABLE table_name;
    

    更多信息可以找到here

    【讨论】:

    • 我知道优化表,但我不能这样做,因为在常规使用时,表将是 60-100GB 大,运行优化只会使整个服务器停止运行。在 InnoDB 上,Optimize 映射到 ALTER TABLE,这是一种重建表。
    • 恐怕这只是一种解决方案,除非您计划镜像数据库服务器。
    猜你喜欢
    • 2019-04-01
    • 2022-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 2013-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多