65 votes

Quelle est la gravité du bogue "Solr/Lucene" de Java7 ?

Apparemment, Java7 a un méchant bug concernant l'optimisation des boucles : Recherche sur Google .

D'après les rapports et les descriptions de bogues, il est difficile de juger de l'importance de ce bogue (sauf si vous utilisez Solr ou Lucene).

Ce que j'aimerais savoir :

  • Quelle est la probabilité que mon (n'importe quel) programme soit affecté ?
  • Le bogue est-il suffisamment déterministe pour que les tests normaux le détectent ?

Note : Je ne peux pas obliger les utilisateurs de mon programme à utiliser -XX:-UseLoopPredicate pour éviter le problème.

79voto

Robert Muir Points 2663

Le problème avec les bugs de type hotspot, c'est que vous devez atteindre le seuil de compilation (par exemple 10000) avant qu'ils ne vous atteignent : donc si vos tests unitaires sont "triviaux", vous ne l'attraperez probablement pas.

Par exemple, nous avons détecté le problème des résultats incorrects dans Lucene, car ce test particulier crée 20 000 index de documents.

Dans nos tests, nous rendons aléatoires différentes interfaces (par exemple, différentes implémentations de répertoire) et les paramètres d'indexation, etc., et le test n'échoue que dans 1 % des cas, bien sûr, il peut être reproduit avec la même graine aléatoire. Nous exécutons également checkindex sur chaque index créé par les tests, ce qui permet d'effectuer quelques tests de sanité pour s'assurer que l'index n'est pas corrompu.

Pour le test que nous avons trouvé, si vous avez une configuration particulière : par exemple RAMDirectory + PulsingCodec + charges utiles stockées pour le champ, alors après avoir atteint le seuil de compilation, la boucle d'énumération sur les écritures renvoie des calculs incorrects, dans ce cas le nombre de documents retournés pour un terme != le docFreq stocké pour le terme.

Nous avons un bon nombre de tests de stress, et il est important de noter que les assertions normales dans ce test passent, c'est la partie checkindex à la fin qui échoue.

Le gros problème est que l'indexation incrémentale de Lucene fonctionne fondamentalement en fusionnant plusieurs segments en un seul : de ce fait, si ces enums calculent des données invalides, ces données invalides sont alors stocké dans le nouvel index fusionné : c'est de la corruption.

Je dirais que ce bogue est beaucoup plus sournois que les précédents bogues de l'optimiseur de boucle que nous avons rencontrés (par exemple, le truc du retournement de signe), https://issues.apache.org/jira/browse/LUCENE-2975 ). Dans ce cas, nous avons obtenu des deltas de documents négatifs farfelus, ce qui permet de l'attraper facilement. Nous n'avons également dû dérouler manuellement qu'une seule méthode pour l'éviter. D'un autre côté, le seul "test" que nous avions initialement pour cela était un énorme index de 10GB de http://www.pangaea.de/ donc il a été douloureux de le réduire à ce bug.

Dans ce cas, j'ai passé une bonne partie du temps (par exemple, toutes les nuits de la semaine dernière) à essayer de dérouler/inclure manuellement diverses choses, en essayant de créer une solution de contournement pour que nous puissions éviter le bogue et ne pas avoir la possibilité de créer des index corrompus. J'ai pu éviter certains cas, mais je n'ai pas pu en éviter beaucoup d'autres... et je suis sûr que si nous pouvons déclencher ce genre de choses dans nos tests, il y aura d'autres cas...

8voto

Narayan Points 81

Une façon simple de reproduire le bogue. Ouvrez eclipse (Indigo dans mon cas), et allez dans Aide/Recherche. Entrez une chaîne de recherche, vous remarquerez qu'eclipse se plante. Jetez un coup d'oeil au journal.

# 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:

4voto

mal Points 41

Le problème existe toujours au 2 décembre 2012. dans les deux JDK d'Oracle java -version Version de java "1.7.0_09". Java(TM) SE Runtime Environment (build 1.7.0_09-b05) Java HotSpot(TM) 64-Bit Server VM (build 23.5-b02, mode mixte) et openjdk version de java "1.7.0_09-icedtea Environnement d'exécution OpenJDK (fedora-2.3.3.fc17.1-x86_64) VM serveur OpenJDK 64-Bit (build 23.2-b09, mode mixte)

Il est étrange qu'individuellement, aucun des -XX:-UseLoopPredicate ou -XX:LoopUnrollLimit=1 empêchent le bug de se produire, mais lorsqu'elles sont utilisées ensemble, le JDK échoue. voir par exemple https://bugzilla.redhat.com/show_bug.cgi?id=849279

1voto

Caffeine Coma Points 10544

Deux ans plus tard, je crois que ce bogue (ou une variante de celui-ci) est toujours présent dans la version 1.7.0_25-b15 sous OSX.

Par des essais et des erreurs très douloureux, j'ai déterminé que l'utilisation de Java 1.7 avec Solr 3.6.2 et autocommit <maxTime>30000</maxTime> semble provoquer une corruption de l'index. Cela ne semble se produire qu'avec les versions 1.7 et 1.8. maxTime à 30000- si je passe à Java 1.6, je n'ai aucun problème. Si je diminue maxTime à 3000, je n'ai aucun problème.

La JVM ne se plante pas, mais RSolr meurt avec la trace de pile suivante en Ruby : https://gist.github.com/armhold/6354416 . Il le fait de manière fiable après avoir sauvegardé quelques centaines d'enregistrements.

Étant donné les nombreuses couches impliquées ici (Ruby, Sunspot, Rsolr, etc.), je ne suis pas sûr de pouvoir réduire ce problème à quelque chose qui prouve définitivement qu'il s'agit d'un bug de la JVM, mais j'ai l'impression que c'est ce qui se passe ici. Pour information, j'ai également essayé le JDK 1.7.0_04, et il présente également le problème.

-7voto

Bas Leijdekkers Points 2656

Si j'ai bien compris, ce bogue ne se trouve que dans la jvm du serveur. Si vous exécutez votre programme sur le jvm client, vous n'avez rien à craindre. Si vous exécutez votre programme sur le serveur jvm, la gravité du problème dépend du programme.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X