【问题标题】:Reclaim MySql Table memory using Spring-Data [duplicate]使用 Spring-Data 回收 MySql 表内存
【发布时间】:2019-07-26 22:12:06
【问题描述】:

我正在为我的应用程序使用 MySql Engine=InnoDB。 有一个表格可以收集来自不同位置的搜索数据并将其保存以供处理。 在特定的时间间隔后,我们使用调度程序删除这些数据。 当我们删除大量行时会出现问题,它不会释放磁盘空间。我们已经将 innodb_file_per_table 设置为 ON。 一种解决方案是运行查询:

Optimize Table <TableName> 

但这会导致该特定表上的其他选择操作失败,告诉:

Caused by: java.sql.SQLException: 表定义已更改,请 重试交易 com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:545) 在 com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:513) 在 com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:115) 在 com.mysql.cj.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:1983) 在 com.mysql.cj.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1826) 在 com.mysql.cj.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1923) 在 com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:353) 在 org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:60) ...省略了154个常用帧

我需要一个回收/重用表空间的解决方案。 我正在使用 Spring-boot,所以这个解决方案应该从应用程序中处理。即使需要使用分区,也应该可以从应用程序中配置。

【问题讨论】:

  • 有一个主题看起来像这样,但没有令人满意的答案,因为它建议我已经拥有但问题仍然存在的 innodb_file_per_table。
  • Big DELETEs 有问题。以下是几种解决方法:mysql.rjweb.org/doc.php/deletebig

标签: java mysql spring-boot spring-data-jpa innodb


【解决方案1】:

一些想法:

  1. 虽然没有释放磁盘空间,但它并没有丢失。当您在该表中插入新行时,之前使用的空间将被重新使用。换句话说,如果您的表在每次删除之前都增长到相似的大小,则没有问题。
  2. 您应该认真考虑在该表上使用分区。如果每个批次进入不同的分区,您可以删除该分区而不是删除。这会更快,实际上会将存储释放回操作系统。在任何给定时间,您最多可能只需要两个分区。

【讨论】:

  • 谨慎推荐分区。分区键必须是表的每个唯一键的一部分的要求通常使其不适合用例。例如,如果 OP 想要通过时间戳列删除旧数据,那么只有当时间戳列是主键的一部分时,分区删除才会有用。这很少是真的。
  • 正确@BillKarwin,如果我使用分区,我需要根据时间戳删除它们。此外,这些分区需要在应用程序中是动态的。这是我担心的事情。对此方向的任何帮助将不胜感激。
  • 应用程序不需要知道分区 - 它只是引用表和由数据库处理的分区。有很多用例可以满足分区的唯一键限制。
猜你喜欢
  • 2019-12-26
  • 2022-07-21
  • 2016-08-05
  • 2017-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-19
  • 2017-04-01
相关资源
最近更新 更多