删除或缩小 HSQLDB 数据库中的 lobs 文件

Posted

技术标签:

【中文标题】删除或缩小 HSQLDB 数据库中的 lobs 文件【英文标题】:Delete or shrink lobs file in a HSQLDB database 【发布时间】:2014-05-06 06:46:28 【问题描述】:

我正在使用 HSQLDB 2.3.0。我有一个具有以下架构的数据库:

CREATE TABLE MEASUREMENT (ID INTEGER NOT NULL PRIMARY KEY IDENTITY, OBJ CLOB);

当我用测试数据填充此表时,我的数据库中的 LOBS 文件会增长:

ls -lath

-rw-rw-r-- 1 hsqldb hsqldb   35 May  6 16:37 msdb.log
-rw-rw-r-- 1 hsqldb hsqldb   85 May  6 16:37 msdb.properties
-rw-rw-r-- 1 hsqldb hsqldb   16 May  6 16:37 msdb.lck
drwxrwxr-x 2 hsqldb hsqldb 4.0K May  6 16:37 msdb.tmp
-rw-rw-r-- 1 hsqldb hsqldb 1.6M May  6 16:37 msdb.script
-rw-rw-r-- 1 hsqldb hsqldb 625M May  6 16:35 msdb.lobs

运行以下命令后:

TRUNCATE SCHEMA public AND COMMIT;
CHECKPOINT DEFRAG;
SHUTDOWN COMPACT;

lobs 文件大小还是一样:

-rw-rw-r-- 1 hsqldb hsqldb   84 May  6 16:44 msdb.properties
-rw-rw-r-- 1 hsqldb hsqldb 1.6M May  6 16:44 msdb.script
-rw-rw-r-- 1 hsqldb hsqldb 625M May  6 16:35 msdb.lobs

截断架构并取回所有磁盘空间的最佳方法是什么?

【问题讨论】:

【参考方案1】:

我有一个使用 hsqldb 2.3.3 的应用程序有同样的问题。即使在调用“检查点碎片整理”之后,.lobs 文件似乎也在无限增长。我的场景是我要插入 1000 个 300 字节的 blob。我会定期将它们全部删除并插入 1000 个大小相同的新 blob。经过几轮这样我的 .lobs 文件现在大小为 1.3GB,但它实际上只存储了大约 300kB 的数据。尽管调用了检查点碎片整理,.lobs 文件还是会不断增长。这种行为是错误吗?

【讨论】:

我看到了同样的行为【参考方案2】:

数据库引擎专为在实际应用程序中持续使用而设计。如果您的应用程序使用了 lob 并删除了其中的一些,则该空间将在每个检查点之后重用于未来的 lob。

在正常的应用程序使用中,DELETE 语句用于删除行。此语句在每个检查点之后释放 lob 空间以供重用。

您可以以重新创建数据库的方式设计测试,而不是在删除数据后重用旧数据库。

【讨论】:

当我说测试数据时,我的意思是“测试数据”来测试我是否可以缩小 lobs 文件。考虑这个用例:应用程序生成足够的数据来填充存储介质。应用程序崩溃是因为无法再将数据插入数据库。我想删除数据库中的一部分数据,以便恢复操作。如果我无法缩小 LOBS 文件,我该怎么做?还是应该只为 LOBS 文件分配 X 空间?这可能吗? 已更新。使用DELETE批量删除行,lob空间稍后释放。 但我不明白这会如何在以后缩小 LOB 文件?所以基本上LOB文件一旦增长就没有办法收缩了,即使LOB内部已经释放了空间? 它将在内部释放空间并允许引擎重用它,以便应用程序可以恢复运行。如果没有剩余 LOB,它将缩小 .lob 文件。 我需要 SQLite 中的 VACUUM 功能。在 HSQLDB 中,我无法阻止 LOB 文件增长,直到它大到足以使系统崩溃。你有什么建议?一旦 LOB 太大(因为内部可用空间),也许是一个重新创建数据库的脚本?

以上是关于删除或缩小 HSQLDB 数据库中的 lobs 文件的主要内容,如果未能解决你的问题,请参考以下文章

从 HSQLDB LOBS 文件增长中恢复的最佳方法

HSQLDB:为现有数据库启用 LOB 压缩

HSQLDB - DELETE 后自动执行 CHECKPOINT

hsqldb休眠持久化@Lob

HSQLDB - 如何设置 .lobs 文件编码?

使用 Hibernate 更新 HSQLDB 上的 LOB/BLOB 值会产生数据异常