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

时间:2015-07-20 18:49:50

标签: java hsqldb

我使用嵌入式HSQLDB 2.3.2实例在应用程序中将XML文档作为LOB存储一段时间,该应用程序与文档应该结束的任何地方间歇性连接。

为了限制HSQBDL的.lobs文件大小增长,我通过documentation中提到的jdbc连接URL启用了LOB压缩(使用hsqldb.lob_compressed = true),但是从我的'最近发现这个URL参数没有任何效果。

如果我理解HSQLDB JDBC URL正确解析代码,org.hsqldb.persist.Logger #setVariables()应该在某个时候检查HsqlDatabaseProperties.hsqldb_lob_file_compressed来设置propCompressLobs,就像它对LOB加密和放大一样。 cryptLobs,但绝不会这样做。

使用URL中的此类参数创建的数据库中的database.script文件,尽管有URL参数,但未提及LOB压缩,并且不压缩LOB。

我已尝试发出" SET FILES LOB COMPRESSED TRUE"在打开数据库之后的语句,这对于一个全新的数据库正常工作(lobs得到压缩,database.script提到LOB压缩)。

当我尝试使用其中一个现有数据库时,由于现有的LOB,我得到一个错误(错误消息是"正在使用的数据文件")。我理解这背后的原因,因为压缩所有LOB可能需要一段时间,并且可能是一个非常长的运行操作,如果被中断,可能会使db处于错误状态。

我认为我可以解决这个限制,因为有时XML文档被删除(最终被发送后),所以理论上DB在某些时候没有LOB。

不幸的是,这个错误也发生在空数据库上,因为有未使用的已删除LOB的LOB条目,我认为这些条目会保留在那里以回收.lobs文件空间。似乎负责允许LOB压缩模式更改的org.hsqldb.persist.Logger #setLobFileCompressed()方法只检查SYSTEM_LOBS.LOB_IDS中的条目数,无论它们当前是否正在使用。

从我读过的内容来看,没有办法清除已删除的LOB条目(例如减少.lobs文件大小),所以基本上即使当前存储在LOB中的所有XML文档都是从LOB中发送和清除的数据库,这不是启用压缩的好时机,因为删除的LOB会留下足以阻止启用压缩的脚印。

如果没有文档,关闭数据库,销毁它,创建一个新数据库,然后手动发出lob压缩语句,我就没有看到任何为现有应用程序启用LOB压缩的方法数据库。

我并不特别喜欢这种似乎是hackish的选择。

我还没有尝试过2.3.3,但从我对sources的看法来看,它在该版本中看起来并不好看。

还有其他方法可靠地启用现有HSQLDB数据库的LOB压缩吗?甚至"空"那些?

2 个答案:

答案 0 :(得分:1)

URL上的压缩设置仅在创建数据库时有效。 SQL设置可以在没有lob历史记录的空数据库上执行。

压缩功能在版本2.0之后添加了很长时间,支持非压缩的lob数据。无法更改现有数据库的设置。

如果数据库中没有lobs,您应该能够执行CHECKPOINT,然后使用SQL设置。如果这不起作用,则有下一个选项。

如果数据库中没有lobs(但可以包含其他数据),则可以关闭数据库,然后编辑.script文件并删除SYSTEM_LOBS的INSERT INTO ...条目并添加默认条目INSERT INTO BLOCKS VALUES(0,2147483647,0)出现在新数据库中。如果这样做,您也应该删除.lobs文件。

您可以使用SQL选择表单SYSTEM_LOBS表来检查其内容,但不能修改它们。

答案 1 :(得分:0)

我已经找到了一种方法,只使用SQL可靠地执行它,无论数据库是新数据库还是已经看过某些活动的现有数据库。

  • 确保使用select count(*) from SYSTEM_LOBS.LOB_IDS
  • 存在0个现有LOB
  • 在任何带有LOB的表中插入一行,以便将LobManager usageChanged设置为true。
  • 提交。
  • 删除刚刚创建的行。
  • 再次提交。
  • 执行CHECKPOINT以清除所有lob元数据。由于最近添加了LOB,检查点实际上将运行LobManager.deleteUnusedLobs()并清理未使用的lob条目。
  • 使用SET FILES LOB COMPRESSED TRUE启用压缩。这现在有效,因为SYSTEM_LOBS.LOB_IDS表中不再有任何内容。

如果你想要可靠地修剪HSQLDB .lobs文件,因为压缩没有激活而变大了:

  • 使用LOB插入另一行,以便HSQLDB可以计算高空占用空间(LobManager.getLobUseLimit在检查点期间没有LOB时不起作用)
  • 提交
  • 再次执行CHECKPOINT,以便将lob文件修剪为使用情况。
  • 删除检查点之前创建的行。
  • 提交