Translate

jeudi 19 juillet 2018

OracleText - Solaris - HAS (BUG)



Chez un de mes clients on avait un problème avec l'indexation de documents en français, apparemment on n'avait aucun erreur mais l'indexation ne se faisait pas correctement.

  • Oracle database : 12.1.0.2.0
  • Solaris Sparc 64bits : 5.11
  • HAS

Tout a commencé avec des tokens générés incorrectement pour la plupart de documents, sauf pour les document Word 2003. pour tester je me suis crée une table et j'ai chargé quelques documents dans une colonne BLOB.

Comme la vraie table allait contenir plutôt de documents en français, j'ai fait mes test avec un PDF rédigé à 99% en français.

Le résultat des tokens une fois l'index créé pour ce fichier PDF donnait un résultat comme celui ci-dessous; pour valider si le mot ÉVOLUTION était indexé :

SELECT DISTINCT TOKEN_TEXT  FROM DR$EVTABLOBIDX$I A
 WHERE A.TOKEN_TEXT LIKE '%VOLUTION'
 ORDER BY A.TOKEN_TEXT ;

...
VOLUTION

... 

Ce qui était évident pour moi que mon document n'était pas correctement indexé.

Par contre si je faisais le même test avec un document word 2003 avec le même contenu, j'avais cet autre résultat:

SELECT DISTINCT TOKEN_TEXT  FROM DR$EVTABLOBIDX$I A 
 WHERE A.TOKEN_TEXT LIKE '%VOLUTION' 
 ORDER BY A.TOKEN_TEXT ; 

... 
EVOLUTION
... 

En essayant de trouver la cause je me suis rendu compte que ce problématique affectait surtout les mot accentués, d'autres mots sans accents étaient correctement reconnus dans la presque totalité.

Mes préférences avaient considéré la restriction de la langue, mais malgré tout, l'indexation n'était pas correcte.

BEGIN 
  CTX_DDL.CREATE_PREFERENCE('UCM_EVTA_LEXER', 'BASIC_LEXER'); 
  CTX_DDL.SET_ATTRIBUTE('UCM_EVTA_LEXER', 'BASE_LETTER', 'YES' ); 
  CTX_DDL.SET_ATTRIBUTE('UCM_EVTA_LEXER','PRINTJOINS','@&_|/\''#().'); 
END ; 


J'ai même vérifié que les librairies étaient correctement initialisées et même configurées pour la bd et le(s) listeners.

LD_LIBRARY_PATH=$ORACLE_HOME/ctx/lib:$ORACLE_HOME/lib

mais toujours rien, une fois le support d"Oracle contacté, on m'a confirmé qu'avec Solaris cette variable semble ignorées (des fois, pas toujours) et que la variable à utiliser serait plutôt LD_LIBRARY_PATH_64

Donc, modification faite, je constate qu'on a toujours le même problème.

Voici mon script de création de l'index :

CREATE INDEX EVTABLOBIDX ON EVTABLOB(OTSCONTENT) INDEXTYPE IS CTXSYS.CONTEXT 
 PARAMETERS('LEXER UCM_EVTA_LEXER FILTER UCM_EVTA_FILTER WORDLIST UCM_EVTA_WLIST MEMORY 350M SYNC(MANUAL)') ; 


J'ai essayé donc de tracer au niveau du système d'exploitation le moment juste de la création d'index, afin de voir si je pouvais collecter plus d'information, et voici ce que j'ai découvert avec cette trace.

...
2068/1:         memcntl(0xFFFFFFFF75600000, 10960, MC_ADVISE, MADV_WILLNEED, 0, 0) = 0
2068/1:         stat("/usr/ccs/lib/sparcv9/librt.so.1", 0xFFFFFFFF7FFFE080) Err#2 ENOENT
2068/1:         mmap(0x00000000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0) = 0xFFFFFFFF7CB00000
2068/1:         stat("/lib/64/libclntshcore.so.12.1", 0xFFFFFFFF7FFFE080) Err#2 ENOENT
2068/1:         stat("/usr/lib/64/libclntshcore.so.12.1", 0xFFFFFFFF7FFFE080) Err#2 ENOENT
2068/1:         open("/usr/lib/locale/en_US.UTF-8/LC_MESSAGES/SUNW_OST_SGS.mo", O_RDONLY) Err#2 ENOENT
2068/1:         open("/usr/lib/locale/en_US.UTF-8/LC_MESSAGES/SUNW_OST_OSLIB.mo", O_RDONLY) Err#2 ENOENT
2068/1:         write(2, 0xFFFFFFFF7DD48A60, 85)                = 85
2068/1:            l d . s o . 1 :   c t x h x :   f a t a l :   l i b c l n t s h
2068/1:            c o r e . s o . 1 2 . 1 :   o p e n   f a i l e d :   N o   s u
2068/1:            c h   f i l e   o r   d i r e c t o r y\n
2068/1:         lwp_self()                                      = 1
1778/1:         waitid(P_PID, 2068, 0xFFFFFFFF7FFE8D40, WEXITED|WTRAPPED) = 0
1778/1:               siginfo: SIGCLD CLD_KILLED pid=2068 status=0x0009
...

Ceci me montre qu'une de librairies n'est pas retrouvée, cependant ce qui est le plus étrange c'est l'endroit où Oracle la cherche malgré le contenu des variables.

Pour tester que c'était la cause, je me suis permis de créer un lien symbolique là, où il la cherchait le fichier; cette fois mon index a bien reconnu les mots.
Avec cette information Oracle a reconnu la présence d'une bogue et le contournement passerait par modifier les références contenues dans le fichier libnnz12.so qui se trouve dans le $ORACLE_HOME/lib

Avant de la modification le fichier  libnnz12.so affiche : 

$ elfdump -d libnnz12.so

Dynamic Section:  .dynamic
index  tag          value
  [0]  NEEDED       0x36e4    libclntshcore.so.12.1
  [1]  INIT         0x27e8d0
  [2]  FINI         0x27e8e0
  [3]  SONAME       0x36d8    libnnz12.so
  [4]  HASH         0x380
  [5]  STRTAB       0x7068
  [6]  STRSZ        0x38fa
  [7]  SYMTAB       0x1ed8
  [8]  SYMENT       0x18
  [9]  CHECKSUM     0x8f21
[10]  VERDEF       0xa968
[11]  VERDEFNUM    0x1
[12]  RELACOUNT    0x348f
[13]  PLTRELSZ     0xea0
[14]  PLTREL       0x7
[15]  JMPREL       0x59e50
[16]  RELA         0xb058
[17]  RELASZ       0x4fc98
[18]  RELAENT      0x18
[19]  REGISTER     0x194
[20]  REGISTER     0x1a0
[21]  SYMBOLIC     0
[22]  FLAGS        0x2       [ SYMBOLIC ]
[23]  FLAGS_1      0         0
[24]  SUNW_STRPAD  0x200
[25]  SUNW_LDMACH  0x2b      EM_SPARCV9
[26]  PLTGOT       0x578f00
 [27-37]  NULL         0

Une fois modifié avec cette commande (Un arrêt/départ est nécessaire): 

elfedit -e 'dyn:runpath /mon/oraclehome/lib' libnnz12.so

elfdump -d libnnz12.so
Dynamic Section:  .dynamic
index  tag          value
  [0]  NEEDED       0x36e4    libclntshcore.so.12.1
  [1]  INIT         0x27e8d0
  [2]  FINI         0x27e8e0
  [3]  SONAME       0x36d8    libnnz12.so
  [4]  HASH         0x380
  [5]  STRTAB       0x7068
  [6]  STRSZ        0x38fa
  [7]  SYMTAB       0x1ed8
  [8]  SYMENT       0x18
  [9]  CHECKSUM     0x8f21
[10]  VERDEF       0xa968
[11]  VERDEFNUM    0x1
[12]  RELACOUNT    0x348f
[13]  PLTRELSZ     0xea0
[14]  PLTREL       0x7
[15]  JMPREL       0x59e50
[16]  RELA         0xb058
[17]  RELASZ       0x4fc98
[18]  RELAENT      0x18
[19]  REGISTER     0x194
[20]  REGISTER     0x1a0
[21]  SYMBOLIC     0
[22]  FLAGS        0x2       [ SYMBOLIC ]
[23]  FLAGS_1      0x200000  [ EDITED ]
[24]  SUNW_STRPAD  0x1d8
[25]  SUNW_LDMACH  0x2b      EM_SPARCV9
[26]  PLTGOT       0x578f00
[27]  RUNPATH      0x36fa    /mon/oraclehome/lib
 [28-37]  NULL         0


Après ces modifications l'indexation se fait correctement.

Cette situation semble se produire seulement si on utilise le GI (HAS)  et non pas dans un GI en RAC.
Il faudrait juste faire attention aux prochains patchs et s'assurer que ce fichier ne serait pas remplacé, tout ça en attendant une patch qui corrigera le problème.