H2 数据库定期损坏
H2 database corruption on a regular basis
我是 an open-source application 专为自托管而设计的开发者。因此,许多人在各种系统、操作系统和硬件上使用它。它使用 Kotlin 和 Spring Boot 构建,并使用 H2 作为数据库。我遇到的问题是许多用户时常面临数据库损坏(我也发生过几次)。
损坏总是以下形式:
org.h2.jdbc.JdbcSQLNonTransientException: General error: "java.lang.IllegalStateException: Chunk 20221 not found [1.4.200/9]" [50000-200]
我无法查明这些损坏的任何特定原因。该应用程序不使用任何危险的 H2 选项。我在网络或 Whosebug 上找不到任何与我(恕我直言)平凡使用 H2 相关的内容。
我正在使用:
- Spring开机
2.2.6.RELEASE
- jOOQ
3.13.1
(但我在使用 Hibernate 之前遇到过同样的问题)
- H2
1.4.200
连接字符串非常简单:
jdbc:h2:~/.komga/database.h2
应用程序偶尔会进行大量写入(在文件系统扫描期间),但之后它主要进行读取。
您对如何更好地配置 H2 以避免这些问题有什么建议吗?
如果您的应用程序将 Thread.interrupt()
用于调用嵌入式数据库的线程,这就是损坏的原因,请不要这样做或使用 async:
文件系统(jdbc:h2:async:…
).
如果带有H2的类加载器可以被强制卸载(例如在某些应用服务器上)或者应用程序将以某种异常方式终止,您需要在它之前关闭所有连接或执行SHUTDOWN
命令并等待其完成。
如果您尝试使用某些旧版本的 H2 打开数据库文件,它可能会损坏由较新版本创建的文件。
您可能 运行 遇到 H2 中的一些错误,因此如果您可以构建一个独立的测试用例 (Java / JDBC / SQL只有,没有第三方库),你需要在 GitHub 上填写一个新问题。您也可以尝试从其当前源构建 H2,存储后端有一些变化,但当前 H2 在其他方面与 1.4.200 有很大不同,您使用的第三方库可能尚未准备好使用它。
您可以使用旧版 PageStore 后端而不是默认后端,方法是在创建数据库时将 ;MV_STORE=FALSE
附加到 JDBC URL。此后端使用 table 级别的锁(您需要在所有事务中以相同的顺序锁定 table )并且不会并行执行来自不同会话的命令,但它更可靠。
可以使用单独的H2 Server进程;这种配置通常比嵌入式数据库更可靠,但速度较慢。
无论如何,对于任何 DBMS,您都应该定期创建备份副本。 H2 具有用于此目的的 BACKUP
命令。
我是 an open-source application 专为自托管而设计的开发者。因此,许多人在各种系统、操作系统和硬件上使用它。它使用 Kotlin 和 Spring Boot 构建,并使用 H2 作为数据库。我遇到的问题是许多用户时常面临数据库损坏(我也发生过几次)。
损坏总是以下形式:
org.h2.jdbc.JdbcSQLNonTransientException: General error: "java.lang.IllegalStateException: Chunk 20221 not found [1.4.200/9]" [50000-200]
我无法查明这些损坏的任何特定原因。该应用程序不使用任何危险的 H2 选项。我在网络或 Whosebug 上找不到任何与我(恕我直言)平凡使用 H2 相关的内容。
我正在使用:
- Spring开机
2.2.6.RELEASE
- jOOQ
3.13.1
(但我在使用 Hibernate 之前遇到过同样的问题) - H2
1.4.200
连接字符串非常简单:
jdbc:h2:~/.komga/database.h2
应用程序偶尔会进行大量写入(在文件系统扫描期间),但之后它主要进行读取。
您对如何更好地配置 H2 以避免这些问题有什么建议吗?
如果您的应用程序将
Thread.interrupt()
用于调用嵌入式数据库的线程,这就是损坏的原因,请不要这样做或使用async:
文件系统(jdbc:h2:async:…
).如果带有H2的类加载器可以被强制卸载(例如在某些应用服务器上)或者应用程序将以某种异常方式终止,您需要在它之前关闭所有连接或执行
SHUTDOWN
命令并等待其完成。如果您尝试使用某些旧版本的 H2 打开数据库文件,它可能会损坏由较新版本创建的文件。
您可能 运行 遇到 H2 中的一些错误,因此如果您可以构建一个独立的测试用例 (Java / JDBC / SQL只有,没有第三方库),你需要在 GitHub 上填写一个新问题。您也可以尝试从其当前源构建 H2,存储后端有一些变化,但当前 H2 在其他方面与 1.4.200 有很大不同,您使用的第三方库可能尚未准备好使用它。
您可以使用旧版 PageStore 后端而不是默认后端,方法是在创建数据库时将
;MV_STORE=FALSE
附加到 JDBC URL。此后端使用 table 级别的锁(您需要在所有事务中以相同的顺序锁定 table )并且不会并行执行来自不同会话的命令,但它更可靠。可以使用单独的H2 Server进程;这种配置通常比嵌入式数据库更可靠,但速度较慢。
无论如何,对于任何 DBMS,您都应该定期创建备份副本。 H2 具有用于此目的的
BACKUP
命令。