首页 > 解决方案 > 文件系统调整大小后 HSQLDB 损坏

问题描述

我有一组运行 Debian 7、OpenJDK 7 和 HSQLDB 2.3.4 的服务器。我正在缩小他们的 ext4 文件系统,以便为根磁盘上的第二个分区腾出空间。简而言之,这是通过重新启动到临时 RAM 磁盘来完成的,该 RAM 磁盘将对文件系统进行离线调整大小并创建新的分区布局。

在几乎所有服务器上,这都能完美运行。但是,在非常小的系统子集上,数据库最终会出现某种损坏,导致应用程序抛出以下异常:

2018-07-25 19:44:16 ERROR h.d..ENGINE user:<uid> company:<cid> remotehost:<ip> <appdir>/appdb/app.db.data getFromFile failed 49485172
org.hsqldb.HsqlException: IO error: RowInputBinary
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.rowio.RowInputBinary.readInt(Unknown Source)
    at org.hsqldb.index.NodeAVLDisk.<init>(Unknown Source)
    at org.hsqldb.RowAVLDisk.<init>(Unknown Source)
    at org.hsqldb.persist.RowStoreAVLDisk.get(Unknown Source)
    at org.hsqldb.persist.DataFileCache.getFromFile(Unknown Source)
    at org.hsqldb.persist.DataFileCache.get(Unknown Source)
    at org.hsqldb.persist.RowStoreAVLDisk.get(Unknown Source)
    at org.hsqldb.index.NodeAVLDisk.findNode(Unknown Source)
    at org.hsqldb.index.NodeAVLDisk.getRight(Unknown Source)
    at org.hsqldb.index.IndexAVL.next(Unknown Source)
    at org.hsqldb.index.IndexAVL.searchCost(Unknown Source)
    at org.hsqldb.persist.RowStoreAVL.searchCost(Unknown Source)
    at org.hsqldb.RangeVariableResolver.setEqualityConditions(Unknown Source)
    at org.hsqldb.RangeVariableResolver.setIndexConditions(Unknown Source)
    at org.hsqldb.RangeVariableResolver.assignToRangeVariable(Unknown Source)
    at org.hsqldb.RangeVariableResolver.assignToRangeVariables(Unknown Source)
    at org.hsqldb.RangeVariableResolver.processConditions(Unknown Source)
    at org.hsqldb.QuerySpecification.setRangeVariableConditions(Unknown Source)
    at org.hsqldb.QuerySpecification.resolveTypesPartThree(Unknown Source)
    at org.hsqldb.QueryExpression.resolve(Unknown Source)
    at org.hsqldb.ParserDQL.compileCursorSpecification(Unknown Source)
    at org.hsqldb.ParserCommand.compilePart(Unknown Source)
    at org.hsqldb.ParserCommand.compileStatement(Unknown Source)
    at org.hsqldb.Session.compileStatement(Unknown Source)
    at org.hsqldb.StatementManager.compile(Unknown Source)
    at org.hsqldb.Session.execute(Unknown Source)
    at org.hsqldb.jdbc.JDBCPreparedStatement.<init>(Unknown Source)
    at org.hsqldb.jdbc.JDBCConnection.prepareStatement(Unknown Source)
    at com.zaxxer.hikari.pool.ProxyConnection.prepareStatement(ProxyConnection.java:308)
    at com.zaxxer.hikari.pool.HikariProxyConnection.prepareStatement(HikariProxyConnection.java)
    at sun.reflect.GeneratedMethodAccessor381.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at net.bull.javamelody.JdbcWrapper$ConnectionInvocationHandler.invoke(JdbcWrapper.java:215)
    at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:317)
    at com.sun.proxy.$Proxy72.prepareStatement(Unknown Source)
    at sun.reflect.GeneratedMethodAccessor381.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy$TransactionAwareInvocationHandler.invoke(TransactionAwareDataSourceProxy.java:240)

AFAIK,文件系统调整大小期间的错误会导致整个文件系统损坏,或看似随机的数据位损坏。由于系统及其使用的可变性,驱动器上的碎片将不一致。

两个问题: 1. 有谁知道这个过程如何导致 HSQLDB 损坏?2.有没有人知道解决上述错误的干净方法?

标签: databasefilesystemshsqldbext4

解决方案


就 HSQLDB 而言,此类操作不应在数据库打开时执行。如果数据库已关闭,并且复制操作保留了文件中的所有数据位(应该如此),则应该没有问题。


推荐阅读