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=Z099312ousn=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.