Ajout d'index sur un annuaire OpenLDAP

Introduction & contexte

Par défaut, les attributs d'un annuaire OpenLDAP ne sont pas indexés. Comme dans une base de données, ceci peut impacter les performances de l'annuaire, en introduisant des full scan qui balaient toutes les entrées. Il est possible, comme sur une base de données, de créer des index sur certains attributs, pour améliorer la vitesse de recherche.
Toutefois, les index ont également un inconvénient : lors des mises à jour, l'index doit être recalculé, et ceci peut être pénalisant, notamment lors de modifications en masse.

Les index LDAP peuvent être de plusieurs sortes :

  • pres : presence. Utilisé dans le cas de recherche attribut=*
  • eq : equality. Utilisé dans le cas d'une recherche de type employeenumber=Z099312 ou sn=smith
  • sub : substring. Utilisé pour des recherches avec une wildcard : sn=smi*
  • approx : approximation. Utilisé si on utilise une recherche de type sn~=smith

En règle générale, on utilise essentiellement les 3 premiers.

Nous allons voir ici les différentes étapes à suivre pour ajouter des index à bon escient. Ceci se fait en plusieurs phases :

  • déterminer les attributs candidats
  • identifier les index existants
  • ajouter ou modifier les index

Déterminer les attributs candidats

On peut déterminer quels sont les attributs qui gagneraient à être indexés en faisant une recherche dans les logs (slapd.log) :

La commande suivante va donner les indications sur les attributs candidats:

cd OPENLDAP_LOG_DIR
grep -i indexed slapd.log > indexes

On trouve par exemple des lignes telles que :

Aug  5 17:56:22 LNXIN99V0003 slapd[2152]: <= bdb_substring_candidates: (employeeNumber) not indexed
Aug  5 17:56:22 LNXIN99V0003 slapd[2152]: <= bdb_substring_candidates: (employeeNumber) not indexed
Aug  8 16:18:01 LNXIN99V0003 slapd[2152]: <= bdb_equality_candidates: (uniqueMember) not indexed
Aug  8 16:22:55 LNXIN99V0003 slapd[2152]: <= bdb_equality_candidates: (uniqueMember) not indexed

Ceci nous donne plusieurs indications :

  • le nom des attributs candidats
  • le type d'index à créer : égalité ou sous-chaîne (substring)

On peut affiner la recherche via des commandes shell. Par exemple, pour les attributs qui pourraient avoir un index "equality" :

grep bdb indexes | grep equality | cut -d ':' -f5 | sort | uniq -c
      3  (c) not indexed
     28  (iirDirectTelNr) not indexed
      7  (iirMgrEmpNumber) not indexed
     28  (iirShortPhoneNr) not indexed
     28  (mobile) not indexed
     76  (o) not indexed
     13  (ou) not indexed
      2  (uniqueMember) not indexed
     13  (userPassword) not indexed

De la même manière pour les attributs en "substring"

grep bdb indexes | grep substring | cut -d ':' -f5 | sort | uniq -c
    631  (displayName) not indexed
     23  (employeeNumber) not indexed
    170  (iirDutySite) not indexed
    104  (iirJobLabel) not indexed
    170  (iirMgtSite) not indexed
      1  (iirNLcn) not indexed
    623  (iirNLdisplayname) not indexed
    170  (iirNLDutySite) not indexed
      1  (iirNLgivenname) not indexed
    104  (iirNLJobLabel) not indexed
     34  (iirNLOUElement) not indexed
     34  (iirOUElement) not indexed
    104  (title) not indexed

L'ajout de l'option '-n' à la commande uniq ajoute le nombre d'occurences trouvées. Ceci permet de cibler plus efficacement les attributs à indexer. Dans notre exemple, on voit que les attributs iirNLcn et iirNLgivenname ne sont pas des candidats intéressants, car au final très peu recherchés, à la différence de l'attribut displayName.

Vérification des index existants

Il est possible d'avoir la liste des index existants de 2 manières :

  • soit via une requête LDAP
  • soit en regardant le fichier de paramétrage de l'OpenLDAP

Liste des index via ldapsearch

La requête LDAP pour récupérer les attributs actuellement indexés, et leur type d'indexation, est de la forme :

ldapsearch -x -D cn=admin,cn=config -w secret -b olcDatabase={3}hdb,cn=config olcDbIndex=* olcDbIndex -LLL
dn: olcDatabase={3}hdb,cn=config
olcDbIndex: employeenumber pres,eq
olcDbIndex: objectClass pres,eq
olcDbIndex: cn pres,eq,sub
olcDbIndex: uid pres,eq,sub
olcDbIndex: mail pres,eq,sub
olcDbIndex: sn pres,eq,sub
olcDbIndex: givenName pres,eq,sub
olcDbIndex: member pres,eq
olcDbIndex: entryCSN,entryUUID eq

Liste des index via le paramétrage

De la même manière, on peut avoir la liste en se plaçant dans le répertoire /etc/openldap/slapd.d/cn=config :

grep -i olcdbindex olcDatabase*.ldif
olcDatabase={3}hdb.ldif:olcDbIndex: employeenumber pres,eq
olcDatabase={3}hdb.ldif:olcDbIndex: objectClass pres,eq
olcDatabase={3}hdb.ldif:olcDbIndex: cn pres,eq,sub
olcDatabase={3}hdb.ldif:olcDbIndex: uid pres,eq,sub
olcDatabase={3}hdb.ldif:olcDbIndex: mail pres,eq,sub
olcDatabase={3}hdb.ldif:olcDbIndex: sn pres,eq,sub
olcDatabase={3}hdb.ldif:olcDbIndex: givenName pres,eq,sub
olcDatabase={3}hdb.ldif:olcDbIndex: member pres,eq
olcDatabase={3}hdb.ldif:olcDbIndex: entryCSN,entryUUID eq

Ajout des index

On va ensuite ajouter les index en mode dynamique, en utilisant l'entrée cn=config de l'annuaire, et donc via un fichier ldif.

Par exemple, si on veut ajouter les index sur les attributs suivants :

  • c / equality
  • displayname / substring

on va créer un fichier ldif contenant la définition des nouveaux attributs (ceux qui ne sont pas encore indexés) :

dn: olcDatabase={3}hdb,cn=config
add: olcDbIndex
olcDbIndex: c eq
olcDbIndex: displayname eq,sub

Note : le DN contient la base sur laquelle l'index sera créé. Par exemple, si mon rootSuffix est défini dans le fichier /etc/openldap/slapd.d/cn=config/olcDatabase={3}hdb.ldif, le DN sera : olcDatabase={3}hdb, cn=config.

L'ajout se fait via une commande ldapmodify :

ldapmodify -x -D cn=admin,cn=config -w secret -f index.ldif

Modification d'un index

Si on veut remplacer la valeur de l'index pour un attribut existant, il faut se caler à la syntaxe ldif, c'est à dire supprimer l'ancienne valeur de l'attribut puis ajouter la nouvelle valeur. Par exemple, si on veut ajouter la règle substring à l'attribut employeenumber qui est déjà indexé, il faudra créer un fichier ldif qui comprenne les lignes :

dn: olcDatabase={3}hdb,cn=config
changetype: modify
delete: olcDbIndex
olcDbIndex: employeenumber eq,pres
-
add: olcDbIndex
olcDbIndex: employeenumber eq,pres,sub

 

Activation / calcul des index

Le calcul des index est fait par OpenLDAP dès que l'on ajoute une entrée qui doit être indexée.

Si on ajoute un index non existant alors qu'il y a déjà des données dans l'annuaire, il faut calculer les index avec la commande slapindex.
Attention : cette commande doit être lancée lorsque l'annuaire est arrêté. Elle se lance avec le nom de la base en paramètre :

service slapd stop
slapindex -b dc=example,dc=com
service slapd start

L'option -q (quick) permet d'accélérer ce traitement.

Note : si on ajoute un index alors que des données sont déjà présentes, on peut avoir un effet de bord indésirable : la recherche sur l'attribut indexé ne renvoie qu'une partie des données, celles qui auront déjà été indexées.

 

Catégorie