Latches & Enqueues /*+ 1. Latches */

Qu’est-ce qu’un « latch » et et à quoi les différents « latches » servent-ils ?

Un latch est un MutEx (i.e. Mutual Exclusion), c’est à dire un mécanisme qui permet d’assurer qu’un seul processus (ou thread) manipule une ressource particulière à un moment donné… Leur ensemble permet de protéger les différentes structures de la SGA (la mémoire partagées d’Oracle) ainsi un process qui lit ou modifie une structure mémoire a la garantie qu’aucun autre process ne modifiera la même structure. C’est un peu comme si les latches étaient des clés unique pour chacune des structures de la SGA et que avant de les manipuler, le process devait obligatoirement prendre cette clé. De cette manière, les structures mémoire sont protégées contre d’éventuelles erreurs dues à des manipulations concurrentes.

Comment un process acquière-t-il un latch ?

Les latches sont donc des points de sérialisation de l’instance Oracle; ils ne permettent pas des sérialisation au niveau de plusieurs instances dans le cas de RAC, dans ce cas, ce sont des enqueues qui seront utilisés. Que se passe-t-il donc si un process veut acquérir un latch et qu’il est déjà pris ? Avant tout, il faut préciser qu’il y a 2 manières de tenter d’acquérir un latch soit (willing to wait) avec l’intention d’attendre soit (no wait) sans l’intention d’attendre. La seconde méthode est explicite et c’est notamment le cas des latchs associés au log buffer : si un process n’arrive pas à prendre le latch, alors il essaiera d’accéder à un autre latch du même type.

Dans le cas où un process veut accéder à un latch avec l’intention de l’acquérir quoiqu’il arrive, il se passe ce qui est illustré ci-dessous :

  1. Avant d’accéder à une structure protégée par un latch, le process réclame le latch
  2. Si aucun process ne l’utilise, il le récupère et peut manipuler la structure
  3. Si, au contraire, un autre process utilise le latch, il va tenter plusieurs fois de récupérer le latch. On dit qu’il « spin » ! Le nombre de tentative dépend du paramètre caché _spin_count que vous pouvez récupérer la valeur avec la requête suivante : select b.ksppstvl value
    from sys.x$ksppi a, sys.x$ksppsv b where a.indx = b.indx and a.ksppinm like ‘_spin_count’ escape ‘’;
  4. Si au bout du nombre maximal de tentative, il échoue toujours, le processus dort pendant quelques millisecondes
  5. Le process peut alterner les phases de spin et d’endormissement jusqu’à ce que le latch soit disponible
  6. Lorsqu’il le peu, le process acquiert le latch et manipule la structure sous-jascente

Remarques :
Les opérations sur les structures de la SGA qui requièrent l’utilisation d’un latch sont très courtes (quelques ms). Pour une opération plus longue comme le vérouillage d’une table, Oracle utilise les enqueues.
Dans le cas des latchs, l’ordre d’arrivée n’est pas équivalent à l’ordre d’utilisation. Il est possible qu’un process arrive après un autre process pour prendre un latch et que pourtant, il profite du temps pendant lequel le premier dort pour prendre le latch et utiliser la structure sous-jacente.

Comment en savoir plus sur les latchs utilisés par vos instances ?

La liste des différents types de latches est disponible dans la vue V$LATCHNAME.

Pour plus de détails sur les statistiques associées à chacun des types de latches, consultez V$LATCH qui contient

  • le nombre de latches obtenus (GETS),
  • le nombre de demandes de latches échouées (MISSES)
  • le nombre de fois qu’un process a dormi (SLEEP).

Cette table contient également les valeurs pour les latches avant utilisés la méthode « no wait » :

  • le nombre de latches obtenus (IMMEDIATE_GETS),
  • le nombre de demandes de latches échouées (IMMEDIATE_MISSES)

La vue V$LATCH_CHILDREN contient les adresses de chacun des latches par type. Lorsqu’un process réserve un latch, ce latch est réalité identifié par une adresse correspondant à une valeur dans cette vue. Cela permet de découper un type de ressource en nombreux morceaux et ainsi faciliter les accès concurrents. Par exemple, le latch « Cache Buffers Chains » qui protège les accès aux « cache buffers » est en fait constitué de plusieurs centaines d’adresses dans lesquelles les blocs sont répartis au moyen d’un algorithme de hash. De cette manière plusieurs process peuvent accéder de manière concurrente au buffer cache tout en garantissant qu’il ne se géneront pas mutuellement.

D’autres vues dynamiques permettent également d’en savoir plus sur les latchs :

  • V$LATCH_PARENT est identique à la vue V$LATCH
  • V$LATCH_MISSES contient plus d’informations sur les tentatives d’acquisition de latches ayant abouti à ce que le process dorme
  • V$LATCHHOLDER contient des informations sur les process qui possèdent actuellement un latch
  • Les vues GV$xxx qui permettent de visualiser les mêmes données pour toutes les instances du RAC

Mais également l’ensemble des interfaces wait events; Pour connaître les temps associées aux latches de l’instance depuis son démarrage, exécutez la requête suivante :
select *
from v$system_event
where event like ‘latch%’;

Et biensûr les vues qui contiennent les clichés des vues précédentes et qui permettent de voir les tendances ou identifier un problème passé :

  • STAT$LATCH, STAT$LATCH_MISSES_SUMMARY, STAT$LATCH_CHILDREN, STAT$LATCH_PARENT pour Oracle Statspack
  • DBA_HIST_LATCH_NAME, DBA_HIST_LATCH, DBA_HIST_LATCH_CHILDREN, DBA_HIST_LATCH_PARENT, DBA_HIST_LATCH_MISSES_SUMMARY pour Automatic Workload Repository (AWR nécessite les licences Diagnostic Pack)

Conclusion
Si vous pensez que cette série à propos des latchs et des enqueues à un quelconque intérêt et que vous voulez que je la continue, faîtes le moi savoir : je peux descendre dans le détail de plusieurs type de latch, discuter des enqueues ou parler de l’influence de ces derniers sur RAC; Qu’en pensez-vous ?

-GarK!

1 réflexion sur “Latches & Enqueues /*+ 1. Latches */”

Les commentaires sont fermés.