Pourquoi les latches ne suffisent-ils pas ?
Dans un Post précédent nous avons discuté des latches et de leur utilité pour empêcher que plusieurs process (processus ou threads) accèdent simultanément à une structure de la SGA. Les latches ont toutefois beaucoup de limites pour assurer l’utilisation concurrentes de nombreuses opérations d’une base de données et par exemple :
- Quelle serait la CPU utilisée si 10 process attendaient pendant plusieurs secondes un latch ?
- Comment garantir qu’une ressource est utilisée dans l’ordre dans laquelle elle a été demandée ?
- Comment protéger une ressource qui pourrait être utilisée depuis plusieurs noeuds d’un RAC ?
- Comment gérer des règles complexes comme les différents niveaux de verrous ?
- Comment détecter des deadlocks ?
C’est parce que les latches ne répondent pas à tous ces besoins qu’un autre mécanisme interne est implémenté qui permet de répondre à tous ces besoins : les enqueues !
Enqueues : qu’est-ce que c’est ?
Les enqueues sont supportées par des structures mémoires gérées dans la shared pool lorsqu’elles sont nécessaires. La structure mémoire ressemble au schéma ci-dessous :
Les informations que chacune des structures contient sont (de manière non exhaustive) :
- Un identifiant de l’enqueue constitué par son type (e.g. TM, TX, HW), et 2 identifiants ID1 et ID2 qui permettent d’identifier précisémment l’enqueue. Par exemple dans le cas des verrous de tables, ID1 est égal à OBJECT_ID et ID2 est égal à zero. Pour en savoir plus :
- sur les code des enqueues, reportez au manuel de référence d’Oracle 10.2 ou supérieur
- sur la signification des ID1 et ID2 pour certains enqueues à un très ancien document d’Anjo Kolk
- 3 listes ordonnées de sessions (au sens SID de la vue V$SESSION qui peuvent donc être des background process ou des PX). Ces listes indiquent :
- Les propriétaires (owners) de l’enqueue et leur niveau de verrouillage
- Les process en attente (waiters) de l’enqueue et leur niveau de verrouillage
- Les process en attentes de changement (converters) de niveau de verrouillage et le niveau associé
Enqueues : comment ça marche ?
Nous discuterons dans un prochain post de comment Oracle utilise certains enqueues en particulier. Retenez simplement ce qui suit :
- Les structures mémoire des enqueues ne sont allouées que lorsqu’elles sont nécessaires. Par exemple, s’il n’y a pas de verrou sur une table, il n’y a aucun enqueue associé dans la mémoire.
- C’est le process qui utilise un enqueue qui met à jour la structure correspondante avant de manipuler la structure associées éventuellement (e.g. avant d’ajouter les identifiants de transaction dans les blocs modifiés par une nouvelle transaction, le process server créera un enqueue TX, i.e. transaction)
- Pour éviter que plusieurs process manipulent simultanément les structures, les enqueues sont protégés par un ensemble de latches dit « Enqueue Latch Chain »
- Si un process devient waiter d’un enqueue, il sera notifié d’un changement de statut et ne consomme donc pas de CPU. Ce ne serait pas le cas si le process effectuer du pooling de ressource comme dans le cas des latches.
Notes à propos des deadlocks :
Si vous n’utilisez pas RAC, les deadlocks sont vérifiés à chaque fois qu’un process utilise un enqueue TM ou TX et devient « waiter » ou « convertors ». Dans ce cas, le process parcourt les sessions après lesquelles il attend et celles après qui elles-mêmes attendent et ainsi de suite pour valider qu’il ne fait pas attendre une des sessions après qui lui même attend : c’est à dire qu’il n’y a pas de deadlock
En interne Oracle utilise toujours les enqueues (et latches) dans le même ordre et une seule fois. De cette manière, il n’est théoriquement pas possible (sauf algorithme mathématique erroné) qu’il y ait des deadlocks internes (Ah, si les développeurs faisaient pareils !)
Comment vont vos enqueues ?
De nombreuses vues permettent de suivre l’évolution des enqueues de vos instances :
- V$LOCK pour l’ensemble des enqueues de type TX et TM
- V$TRANSACTION_ENQUEUE est la même vue que V$LOCK mais que pour les enqueues TX
- V$LOCKED_OBJECT contient la liste des enqueues TM avec les objets associés et quelques informations sur les sessions associées.
- V$ENQUEUE_LOCK pour les autres types d’enqueues
- DBA_LOCKS, DBA_LOCK_INTERNAL ou DBA_LOCK affichent la liste des verrous ou latch de manière amical (e.g. nom du lock plutôt que les identifiants correspondants)
- DBA_DDL_LOCKS et DBA_DML_LOCKS affichent respectivement les verrous TM et les verrous TX
- DBA_LOCK_ALLOCATED est une table qui permet de visualiser les verrous allour par les utilisateurs pour une gestion plu détaillée et générée avec la procédure DBMS_LOCK.ALLOCATE_UNIQUE
- DBA_WAITERS and DBA_BLOCKERS affichent les sessions qui attendent et celles qui bloquent d’autres sessions. Dans le premier cas, elle présente également le détail des locks associés aux process qui attendent
Biensûr, la plupart des enqueues peuvent générer des attentes et ont donc des évènements et des statistiques associés. Vous pouvez comme dans le cas des latches requêter certaines vues comme celle-ci pour avoir plus de détails sur les enqueues qui peuvent être une source de préoccupation pour vos environnements : V$SYSTEM_EVENT, V$SESSION_EVENT, V$SESSION_WAIT, V$SYSSTAT, DBA_HIST_SYSTEM_EVENT
Conclusion : voulez-vous en savoir plus sur RAC ?
Dans le cas de RAC, les enqueues deviennent « Global Enqueues » et font l’objet d’échanges entre les instances via l’interconnect comme les données des caches. Les enqueues doivent alors, plus encore que dans le cas d’une single instance, faire l’objet d’une attention particulière. Si ça vous intéresse d’en savoir plus sur ce sujet, faites-le savoir et ce pourrait être le sujet d’un prochain Post. Mais cela vous intéresse-t-il ?
-GarK!
2 réflexions sur “Latches & Enqueues /*+ 2. Enqueues */”
Il va falloir patienter quelques jours parce que moi, je déménage Mercredi à Ottawa !
GarK!
Moi, cela m’intéresse. Enfin ce que j’en dis, c’est que la série est topissime.
Les commentaires sont fermés.