任何热点错误的问题在于,您需要先达到编译阈值(例如10000),然后才能获取它:因此,如果您的单元测试“琐碎”,则您可能会捉住它。
例如,我们在Lucene中捕获了不正确的结果问题,因为此特定测试创建了20,000个文档索引。
在我们的测试中,我们对不同的接口(例如,不同的Directory实现)和索引参数等进行随机化,并且测试仅在1%的时间内失败,当然,然后可以使用相同的随机种子进行重现。我们还在测试创建的每个索引上运行checkindex,它们会进行一些完整性测试以确保索引没有损坏。
对于我们发现的测试,如果您具有特定的配置:例如RAMDirectory + PulsingCodec
+为该字段存储的有效负载,则在达到编译阈值后,发布中的枚举循环将返回错误的计算结果,在这种情况下,返回的文档数对于术语!=为该术语存储的docFreq。
我们有大量的压力测试,重要的是要注意此测试中的正常断言实际上已经通过,它的checkindex部分在失败的末尾。
这样做的最大问题是,lucene的增量索引从根本上是通过将多个段合并为一个片段来工作的:因此,如果这些枚举计算出无效数据,则该无效数据将被 存储
到新合并的索引中:aka腐败。
我想说这个错误比我们之前遇到的以前的循环优化器热点错误(例如,符号翻转的东西,https://issues.apache.org/jira/browse/LUCENE-2975)要狡猾得多。在那种情况下,我们得到了古怪的负文档增量,这很容易捕获。我们还只需要手动展开一个方法即可躲避它。另一方面,我们最初进行的唯一“测试”是对http://www.pangaea.de/的
10GB巨大索引,因此将其范围缩小到此bug很痛苦。
在这种情况下,我花费了大量时间(例如,上周的每个晚上)尝试手动展开/内联各种内容,尝试创建一些解决方法,以便我们可以躲避该错误并避免创建损坏的索引。我可以避开某些情况,但是还有更多我无法解决的情况…而且我敢肯定,如果我们可以在测试中触发这种情况,那么还有更多的情况…



