为啥 H2 DB FileLock.sleep() 需要这么长时间?

Posted

技术标签:

【中文标题】为啥 H2 DB FileLock.sleep() 需要这么长时间?【英文标题】:Why does H2 DB FileLock.sleep() need to take so long?为什么 H2 DB FileLock.sleep() 需要这么长时间? 【发布时间】:2014-03-31 01:46:10 【问题描述】:

我今天早些时候在评估 H2 的速度,发现在进行许多后续查询时速度明显放缓。我用 JMX 做了一个快速的 CPU 配置文件,我注意到大部分 CPU 时间都花在了FileLock.sleep() 方法上。我在进行数百条 INSERT 语句时调试了代码,这些调用几乎完全源于 FileLock.lockFile() 方法中的这一行:

save();
sleep(SLEEP_GAP);

FileLock.SLEEP_GAPstatic final int 设置为 25,所以它根本无法调整(请不要建议我使用反射,如果您认为这会起作用,我鼓励您使用 read this answer )。调用此方法并导致主线程在执行的每个 INSERT 语句上休眠 25 毫秒。如果你有数以万计的程序要执行,那真的会浪费很多时间。为什么这个值是这样设置的?有什么办法可以不用这个类吗?

Source code,如果您不想将其从 SVN 中取出。

【问题讨论】:

你打开和关闭连接很多,而且只有一个连接吗?在那种情况下,数据库文件被打开和关闭很多,这很慢(不管睡眠间隙有多小)。在这种情况下,我会考虑保持连接打开,或者使用连接池。或者,更简单,将 ";DB_CLOSE_DELAY=1" 附加到数据库 URL。 我正在使用 Spring 来管理数据源,因此它可能会频繁地打开/关闭连接。不知道是否有办法让它在关闭它时更加保守,但我今晚回家时会试试这个参数。 天哪,这产生了巨大的不同;将 400 条记录加载到大约 1 秒需要 20 秒。请给出答案,以便我接受! 【参考方案1】:

FileLock.sleep() 在打开数据库文件时使用,以确保没有其他进程可以同时打开同一个数据库文件(类似于文件锁定)。大多数数据库引擎都使用这种机制。如果您在分析中看到这一点,那么这意味着数据库连续多次打开和关闭。打开和关闭数据库非常慢,应该避免。

如果可能,数据库应保持打开状态,by keeping the connection open or by using a connection pool。

如果这不是一个选项,则将 ;DB_CLOSE_DELAY=1 附加到数据库 URL。这将使数据库文件在关闭最后一个连接后保持打开一秒钟。

【讨论】:

我想为后人补充一点,Spring 不会使用默认配置自行保持连接打开。

以上是关于为啥 H2 DB FileLock.sleep() 需要这么长时间?的主要内容,如果未能解决你的问题,请参考以下文章

H2数据库:啥是以及为啥会出现database.xx.log.db.corrupt二进制文件

将 h2 数据库从 h2.db 转换为 mv.db

查看test.h2.db(H2数据库)的工具[关闭]

H2 DB 网址错误

检查 H2 db 文件是不是存在

如何从 Java 和 H2 DB 连接到 H2 数据库