我们有用户报告Firebird数据库,这些数据库对于我们的应用程序存储的条目数量来说太大了。
我发现一篇文章Commit vs CommitRetaining指出使用CommitRetaining不是最聪明的事情,可能会阻止GarbageCollection工作。
我们的软件由多个应用程序组成,所有应用程序都连接到Firebird数据库。有些是绑定到某些用户操作,只运行几秒钟或几分钟,其他的是可以运行数月的后台应用程序。
因为我认为CommitRetaining和Commit“一样好”,而且我不必小心启动一个新事务,所以我在任何地方都使用CommitRetaining。
现在我想弄清楚,如果我需要让所有的应用程序都没有CommittingRetaining,或者这就足够了,如果长时间运行的应用程序是“干净的”,而短时间运行的应用程序不重要,因为当它们被关闭时,无论如何都算一个Commit?
只是因为好奇:Firebird是否需要使用CommittRetaining来执行GC,或者每个连接都单独处理。
换句话说:假设有2个应用程序A和B在运行
AAAA--AAAA--AAAA-....
---BBBB--BBBB--B...
所以总是A或B连接到DB,这会永远阻止GC吗?
1条答案
按热度按时间busg9geu1#
使用提交保留提交的事务在真正提交之前不会有效地结束,这意味着最旧的感兴趣事务和最旧的活动事务被有效地冻结,并且这抑制了记录版本的大多数垃圾收集,因为它们可能对最旧的活动事务仍然感兴趣。时间越长,越多的版本积累,这需要空间,也降低了性能。
垃圾收集的禁止并不依赖于连接本身(事实上,如果没有活动连接阅读数据页,Firebird就不会收集垃圾)。它依赖于一个连接的一个或多个活动事务句柄没有被真正提交,只有提交(或回滚)被保留。因此,一旦您切换到使用正常的提交,或者通过定期使用真实的提交而不是提交保留来减少事务的生存时间,垃圾收集应该能够向前移动。
然而,只要你使用了commit retain,你可能会比在任何地方切换到真实的提交时积累更多的垃圾。
换句话说,将长时间运行的应用程序切换到使用真实的提交应该可以缓解数据库增长带来的大部分问题。