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