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 :
attribut=*employeenumber=Z099312 ou sn=smithsn=smi*sn~=smithEn 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 :
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 :
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.
Il est possible d'avoir la liste des index existants de 2 manières :
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
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
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 :
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
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
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.