Java7的“Solr/Lucene”错误有多严重?

2022-08-31 15:02:41

显然,Java7在循环优化方面存在一些令人讨厌的错误:Google搜索

从报告和错误描述中,我发现很难判断这个错误有多重要(除非你使用Solr或Lucene)。

我想知道:

  • 我的(任何)程序受到影响的可能性有多大?
  • Bug的确定性是否足以让正常的测试捕获它?

注意:我无法让我的程序用户使用以避免此问题。-XX:-UseLoopPredicate


答案 1

任何热点错误的问题是,你需要达到编译阈值(例如10000)才能得到你:所以如果你的单元测试是“微不足道的”,你可能不会抓住它。

例如,我们在 lucene 中捕获了不正确的结果问题,因为此特定测试创建了 20,000 个文档索引。

在我们的测试中,我们随机化不同的接口(例如不同的目录实现)和索引参数等,并且测试仅在1%的时间内失败,当然,它可以使用相同的随机种子重现。我们还对测试创建的每个索引运行 checkindex,这些索引会执行一些健全性测试以确保索引未损坏。

对于我们发现的测试,如果您有特定的配置:例如RAMDirectory + PulsingCodec +为字段存储的有效负载,那么在达到编译阈值后,对发布进行的枚举循环将返回不正确的计算,在这种情况下,返回的术语的文档数!= 为该术语存储的docFreq。

我们有大量的压力测试,重要的是要注意这个测试中的正常断言实际上通过了,这是最后的checkindex部分失败。

这样做的最大问题是,lucene的增量索引基本上是通过将多个段合并为一个来工作的:因此,如果这些枚举计算出无效数据,则这些无效数据将存储到新合并的索引中:也称为损坏。

我会说这个错误比我们遇到的以前的循环优化器热点错误(例如,符号翻转的东西,https://issues.apache.org/jira/browse/LUCENE-2975)要狡猾得多。在这种情况下,我们得到了古怪的负文档增量,这使得它很容易被捕获。我们也只需要手动展开一种方法来躲避它。另一方面,我们最初对此进行的唯一“测试”是一个巨大的10GB http://www.pangaea.de/ 索引,因此将其缩小到此错误是痛苦的。

在这种情况下,我花了大量时间(例如,上周每天晚上)尝试手动展开/内联各种内容,试图创建一些解决方法,以便我们可以躲避错误,而不会创建损坏的索引。我可以躲避一些案件,但还有更多的案件我无法...我敢肯定,如果我们能在测试中触发这些东西,就会有更多的情况......


答案 2

重现错误的简单方法。打开 eclipse(在我的情况下是 Indigo),然后转到帮助/搜索。输入搜索字符串,您会注意到日食崩溃。查看日志。

# Problematic frame:
# J  org.apache.lucene.analysis.PorterStemmer.stem([CII)Z
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp
#

---------------  T H R E A D  ---------------

Current thread (0x0000000007b79000):  JavaThread "Worker-46" [_thread_in_Java, id=264, stack(0x000000000f380000,0x000000000f480000)]

siginfo: ExceptionCode=0xc0000005, reading address 0x00000002f62bd80e

Registers:

推荐