java - 使用 Spring-Data 回收 MySql 表内存
问题描述
我正在为我的应用程序使用 MySql Engine=InnoDB。有一个表格可以收集来自不同位置的搜索数据并将其保存以供处理。在特定的时间间隔后,我们使用调度程序删除这些数据。当我们删除大量行时会出现问题,它不会释放磁盘空间。我们已经将innodb_file_per_table设置为ON。一种解决方案是运行查询:
Optimize Table <TableName>
但这会导致该特定表上的其他 Select 操作失败,告诉:
引起: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,所以这个解决方案应该从应用程序中处理。即使需要使用分区,也应该可以从应用程序进行配置。
解决方案
几个想法:
- 虽然磁盘空间没有被释放,但它并没有丢失。当您在该表中插入新行时,之前使用的空间将被重新使用。换句话说,如果您的表在每次删除之前都增长到相似的大小,则没有问题。
- 您应该认真考虑在该表上使用分区。如果每个批次进入不同的分区,您可以删除该分区而不是删除。这会更快,实际上会将存储释放回操作系统。在任何给定时间,您最多可能只需要两个分区。
推荐阅读
- python - 使用字典的 for 循环,但仅在键是单个字符时才有效
- python - 如何将此字符串 '2012-07-06T21:00:00.000Z' 转换为日期时间格式以计算年龄
- c - 尝试在 linux C 套接字中将客户端连接到服务器时连接被拒绝
- binary-search-tree - 数据结构
- ios - 如何更改此已弃用的代码?(flutter_inappwebview)
- python - 如何在 python 中生成孟加拉语文本的 wordcloud?
- javascript - 在ndoejs和mongoose中保存数据库后返回数据时调用socket
- java - Java - 替换所有重音符号,但保留版权、商标和注册等符号
- swift - 创建自己的/自定义的类对象
- scala - 在scala中读取多行作为输入