Vous êtes sur la page 1sur 8

Les diffrents modes de verrous sous Oracle

Les diffrents modes de verrous sous Oracle


Les verrous sont indispensable ds quon manipule des donnes par plusieurs sessions en parallle. Sous Oracle, leur implmentation est assez performante, mais leur comprhension est assez complexe. Essayons dclaircir cela.
Cet article explique :
Les modes de verrous et leur nommage. Comment comprendre la matrice de compatibilit des verrous. Quelles oprations posent quels verrous. Comment voir les verrous poss partir des vues du dictionnaire.

Ce quil faut savoir :


Le fonctionnement des insert, delete, update, select et select for update. Les problmatiques de modification concurrentes.

Les verrous sous Oracle

La pose de verrous (locks) sous Oracle parat simple au premier abord. La plupart du temps, on na pas utiliser de verrouillage explicite (lock table). Le verrouillage implicite des ordres DML (insert, update, delete, merge, select for update) est transparent et efficace. Un select (sans le for update) ne pose aucun verrou. Les verrous inter-bloquants (deadlocks) sont rares et les attentes sur les wait events enqueue ne sont pas si frquentes. Mais lorsquon veut aller plus loin, pour comprendre une situation de deadlock, ou pourquoi une session est bloque, ou pour viter les problmes de performance sur la vrification de lintgrit rfrentielle, alors les choses deviennent plus complexes. Le mcanisme dOracle nest pas facile comprendre et les diffrents nommage des modes de verrous rendent les choses plus difficiles. Un exemple: le mode 3 par exemple peut sappeler Row Exclusive aussi bien que Sub Exclusive, abrg en Row-X, Sub-X, RX ou SX. Et il ne vrouille pas une ligne (row) - dailleurs les verrous au niveau ligne ne sappellent pas row mais TX comme transaction - et il nest pas si exclusif que a puisque plusieurs session peuvent lacqurir sur la mme ressource... Pas de panique, on va tout expliquer. La signification des modes de verrouillage, leurs nommage, et leur matrice de compatibilit. Un verrou a un type, un mode et un identifiant de la ressource verrouille.

Types de verrous

Un verrou (lock ou enqueue) est un mcanisme qui sert srialiser laccs une ressource. Oracle utilise des verrous pour protger soit des donnes de la base (tables, lignes, index,...), soit des meta-donnes (verrous dictionnaire Data Dictionary Lock), soit des structures internes en mmoire (ce sont les latches). Ici, nous parlerons seulement des donnes. Les verrous sur les donnes sappellent aussi DML locks car ils sont souvent utiliss par le langage de manipulation de donne (DML Data Manipulation Language), mais ils sont aussi utiliss par le langage de dfinition de donne (DDL Data Definition Language) lorsque celui-ci doit accder aux donnes. Il y a 3 types de verrous sur les donnes: les verrous de niveau ligne (row) sont appels transaction locks (TX) car ils sont poss lorsquil y a un accs concurrent sur une ligne, et la ressource verrouille est la transaction : les verrous TX nattendent pas sur une ligne mais sur la fin de la transaction qui a mis jour la ligne. les verrous au niveau table sont appels table locks (ou TM locks) et la ressource verrouille est un ob-

HORS SRIE

phpsolmag.org/fr

Les diffrents modes de verrous sous Oracle

jet de la base de donnes : une table, un index, une partition de table, ... Ces verrous TM peuvent tre poss de manire implicite par le DML ou le DDL, et ils peuvent aussi tre acquis explicitement par linstruction LOCK TABLE Les verrous dfinis par lutilisateur (user defined lock UL) pour lesquels la ressource nest pas un objet de la base de donnes, mais un simple identifiant qui na de signification que pour lapplication. Ils sont grs par le package dbms_lock. Dans ce document, je vais surtout parler des verrous table (TM) mais jexpliquerai aussi rapidement les verrous TX, pour clarifier la confusion quil y a souvent entre les verrous de niveau table et de niveau ligne.

Et il y a pire. Pour les vnements dattentes (enqueue wait events) associs aux verrous table (enq: TM) on devra consulter le paramtre P1 pour retrouver le type de verrou et son mode (Table 2). Comment se souvenir de ces numros, et ces noms sans les confondre ? Et deviner les ordres DML qui peuvent les causer ? Et la matrice de compatibilit qui montre ce qui est permis ou bloqu par un verrou donn ? Cest pourtant possible: je vais vous expliquer la signification de Share et Exclusive, et celle de Row ou Sub ou Intended, et tout va devenir clair. Un verrou exclusif (X Exclusive Lock) empche de partager une ressource: il empche toute autre session de poser un verrou partag (S Share Lock). Un verrou partag(S Share Lock) permet de partager une ressource: plusieurs session peuvent poser un verrou partag (S) sur la mme ressource. Mais il empche par contre une autre session de poser un verrou exclusif (X) sur la mme ressource. Nous avons donc les premiers lments pour construire la matrice de compatibilit. Pour les verrous X et S, la matrice montre que la combinaison S/S est compatible mais S/X, et X/X sont incompatibles. Lide gnrale, cest que pour modifier une donne, on pose un verrou exclusif (Exclusive Lock). Et pour seulement lire une donne on pose un verrou partag (Share Lock) si on veut sassurer que personne ne la modifie en mme temps. Si quelquun est dj en train de la modifier (et donc a acquis un verrou X) alors il faudra attendre de savoir si sa modification concurrente est valide (commit) ou non (rollback).

Share et Exclusive

Modes de verrous

On pense souvent deux modes de verrouillage: exclusif (exclusive) pour empcher tout accs concurrent, partag (shared) pour nempcher que les accs exclusifs. Mais Oracle dfinit six modes de verrous. Ils ont chacun un numro, et diffrents noms, que lon va retrouver dans les vues V$, dans la documentation, dans des fichiers de trace, dans Entreprise Manager,...
Table 1. Modes de verrous et leurs noms et abrviations

mode Diffrents noms


1 2 3 4 5 6 Null Row Share, Sub-Share, Intended Share, SS, RS, Row-S Row Exclusive, Sub-Exclusive, Intended Exclusive, SX, RX, Row-X Share, S S/Row-X, Share Row, Exclusive, Share-SubExclusive, SSX, SRX Exclusive

Sub et Row

Ce nest donc vraiment pas facile de sy retrouver et de retenir les noms et abrviations des modes de verrous. Je vais vous expliquer la signification de chacun de ces noms, afin den comprendre leur sens.
Table 2. Types et modes de verrous dans les paramtres des wait event

On a vu quil y a parfois deux noms et deux abrviations: Sub(S) et Row(R). Ils veulent dire la mme chose mais dans un contexte diffrent. Prenons le cas des verrous de tables (TM locks). La ressource qui est verrouille par Share (S) et Exclusive (X) est une table. P1
1414332417 1414332418 1414332419 1414332420 1414332421 1414332422 1415053316 1415053318

Type et mode
TM mode 1 TM mode 2 TM mode 3 TM mode 4 TM mode 5 TM mode 6 TX mode 4 TX mode 6

P1TEXT
name/mode name/mode name/mode name/mode name/mode name/mode name/mode name/mode

P1RAW
544D0001 544D0002 544D0003 544D0004 544D0005 544D0006 54580004 54580006

phpsolmag.org/fr

HORS SRIE

Les diffrents modes de verrous sous Oracle

Mais Oracle a aussi la possibilit de poser un verrou qui concerne un sous-ensemble (subpart) de la ressource verrouille. Lorsquil sagit dune table, le sous-ensemble, cest un ensemble de lignes de la table (Row). Par exemple, si on modifie un ou plusieurs lignes dune table (insert, update, merge ou delete) - donc une criture - ce nest pas un verrou X qui est pos, car celui-ci verrouillerait toute la table, mais un verrou Row-X (Row Exclusive - RX) pour dire quon modifie des lignes de la table. De mme, si lon veut poser un verrou en lecture sur quelques lignes, comme avec un select for update, ce nest pas un verrou S qui est pos sur la table, mais un verrou Row-S (Row Share - RS). En ralit, sur les versions rcentes dOracle, un select for update est trait comme une modification, et pose un Row-X, mais nous verrons a plus loin. Nous sommes sur une table, et nous posons un verrou RX ou RS pour la modification ou la lecture de lignes. Voil la raison du double nommage Sub et Row: dans le cas dun verrou TM, verrou au niveau table, puisque le sous ensemble concerne des lignes (Row), on peut parler de Row-S (RS) et Row-X (RX). Mais dans le cas gnral, pour un verrou pos sur un sous-ensemble (Subpart) dune ressource, sappelle Sub-Share (SS) et Sub-eXclusive (SX). Et mme pour pour une table, si elle est partitione, alors un verrou X peut tre pos sur une partition seulement, et un Sub-X sera pos sur la table (le sous-ensemble tant une partition, il ny a pas lieu dutiliser le nommage ligne Row-X ici). Tout cela, cest seulement une question de nommage. Le comportement du verrou est le mme pour un mode donn. Mais ces explications sont indispensables pour comprendre ces diffrents modes de verrous. Dans cet article, je vais continuer en raisonnant sur une table, et donc utiliser le nommage Row plutt que Sub. Pourtant Sub serait plus gnral. Mais la vrai raison, cest que je prfre dviter Sub car elle a la mme abrviation que Share, et a rajoute une source de confusion...

(cest dire sur son entre de la table des transactions du tablespace undo). Cest un verrou au niveau ligne (row lock) mais la ressource verrouille est en fait la transaction complte, et cest pour cela quil sappelle TX: une transaction qui voit une ligne verrouille va demander un verrou sur la transaction qui a modifi la ligne, et cest la fin de cette transaction quil va attendre. Et ce verrou est toujours exclusif: Oracle na pas de verrou partag au niveau ligne (dautres SGBD les utilisent pour lisolation des transactions, mais Oracle nen a pas besoin puisque, grce aux undo, il fait des lectures consistantes sans devoir poser de verrous). Alors, nous avons des verrous TM qui concernent toute la table (en mode S et X), et des verrous ligne qui concernent une ligne. Alors pourquoi avoir besoin des des verrous table concernant des lignes (TM en mode RS et RX) ? Une table peut avoir un grand nombre de lignes. Si nous avons besoin de verrouiller la table en mode partag (TM en mode S), ce ne serait pas trs performant daller voir tous les lignes de la table dans le but de savoir si il y en a un qui est verrouill. Et dans lautre sens, poser un verrou exclusif sur toute la table lorsque modifie seulement quelques lignes poserait de gros problmes de concurrence daccs et de scalabilit. Cest l que sont utiliss les verrous Sub: une transaction qui a lintention de modifier quelques lignes va commencer par poser un verrou Row-X sur la table, et il ny a plus besoin daller voir toutes les lignes pour vrifier la compatibilit avec S ou X. Cette intention explique le troisime synonyme que lon trouve moins souvent pour les Sub/Row: Intended Share (IS) et Intended eXclusive (IX).

Lecture ou criture

Verrou table et verrou ligne

Attention, jai parl ici de verrou TM pos sur une table (table lock) pour dire que toute une table, ou quun ensemble de lignes est modifi. En plus de cela, le DML (insert, update, delete, merge ou select for update) doit poser un verrou sur chaque ligne modifie. Deux sessions peuvent chacune modifier une ligne de la table tant quil ne sagit pas de la mme ligne. Par contre, chaque session va aussi poser un verrou sur la ligne: dans le bloc de donne, la ligne aura un pointeur sur lentre ITL, qui elle mme pointe sur la transaction

Nous avons vu que dans lide gnrale un verrou exclusif (X ou RX) correspond une criture et un verrou partag (S ou RS) correspond une lecture qui veut empcher des critures concurrentes. Mais avec Oracle, je dois prciser un peu cela. Oracle effectue par dfaut des lectures non bloquantes, o on peut lire des donnes de manire cohrente sans avoir bloquer les critures concurrentes. Oracle utilise les undo (rollback segments) pour avoir une image cohrente des donnes telles quelles taient au moment o on a excut la requte. Et il na rien besoin de verrouiller dans ce cas : on laisse les autres modifier puisquon ne verra pas ces modifications. Ce principe peut mme aller trs loin : il est possible de lire les donnes dune table quon vient de supprimer (drop table) du moment que le select ait dmarr avant le drop. Lorsque on veut faire une lecture bloquante, on utilise un select for update, qui verrouille sans modifier (mme

HORS SRIE

phpsolmag.org/fr

Les diffrents modes de verrous sous Oracle

si cest souvent dans le but de modifier ultrieurement comme son nom lindique). Jusqu la 9i, Oracle posait un verrou partag (RS), ce qui correspond bien lide de lecture bloquante. Mais depuis la 9i, suite la correction dun bug en RAC, cest un verrou exclusif qui est pos, exactement comme un update. Dailleurs au niveau ligne (TX) le select for update a toujours t un verrou exclusif. On peut donc rester sur lide que shared est pour la lecture et exclusive pour lcriture. Mais il faut alors garder lesprit que sous Oracle les lectures non bloquantes ne posent pas de verrous, et que le select for udpate ressemble plutt une criture (dailleurs vous ne pouvez pas le faire sur une base en read-only). Le DDL aussi peut poser des verrous table (TM). Un alter table va poser un verrou X sur la table: il crit et doit empcher les lectures bloquantes (S,RS) et les critures (X,RX). Un create index, par contre ne modifie pas la table, mais il doit lire des donnes stables. Il pose un verrou S de lecture bloquante pour quil ny ait pas dcriture dans la table durant la cration de lindex. Lintgrit rfrentielle aussi pose des verrous TM. Par exemple, le problme connu des foreign key non indexes se traduit par un verrou S sur la table fille lorsque la table parent subit un delete ou un update de la cl. Pourquoi ? Parce que pour dempcher un insert qui violerait lintgrit rfrentielle, sans index Oracle na pas une ressource de plus bas niveau verrouiller. Lorsque la cl trangre est au dbut dun index, alors la premire entre dindex avec la valeur du parent peut tre utilise comme ressource unique verrouiller avec un verrou TX. Et maintenant si lintgrit rfrentielle saccompagne dun delete cascade? en plus du mode S, il y a lintention de modifier des lignes dans la table fille, comme avec un Row-X. Cest l quintervient le mode share row exclusive (SRX). Cest finalement simple: S+RX=SRX.

faut vrifier lexistence du parent avec une lecture bloquante (si ce ntait pas le cas, lenregistrement parent pourrait tre supprim avant notre commit, et lintgrit serait viole). Cette vrification est identique un select for update et elle pose donc un Row-X (ctait un RowS avant la 9i). Dans lautre sens, lorsquon supprime un enregistrement parent, ou lorsquon modifie la valeur rfrence (sa cl), il faut empcher des insert dans la table fille. Cest un Row-X (Row-S avant la 9i) sil y a un index qui peut supporter le verrou ligne pour la valeur de lenregistrement parent, mais sinon, cest un verrou TM en mode S pour bloquer tous les insert. Pour viter ces verrous TM-Share, il faut soit que les colonnes de la foreign key soient indexes ou en tte dun index. Soit quil ny ait pas dintentions de delete sur la table mre ou de update des colonnes rfrences. Un insert en mode direct (direct-path) doit empcher les modifications concurrentes car il crit directement sur disque sans passer par les buffers partags, donc il doit poser un verrou X sur la table pour empcher toute modification concurrente. Si une partition spcifique est prcise avec le nom de la table, alors il pose un seulement un Sub-X sur la table car il a lintention dcrire dans une sous-partie, et un verrou X sur la partition en question. Ces verrous sont acquis jusqu la fin de la transaction. Sauf le TM-Share des foreign key non indexes qui est relch au plus vite. Le DDL peut aussi poser des verrous, pour toute lopration, ou pour un court instant (et lopration peut alors tre considre comme online). Si vous voulez faire des lectures rptables (repeatable reads) pour viter le problme des lignes fantmes (phantom reads) lorsque un insert concurrent a chang votre rsultat, alors on ne peut pas compter sur les verrous lignes pour la simple raison quon ne peut pas verrouiller une ligne qui nexiste pas encore (il ny a pas de range lock sous Oracle). Alors il faut verrouiller la table et cela se fait avec un verrou S. Par exemple, la cration ou la reconstruction offline dun index pose un verrou S sur la table. Lorsquun DLL doit avoir un accs exclusif pour crire dans la table, comme un ALTER TABLE MOVE, cest un verrou X qui est pos. Jai seulement donn des exemples. il y a de nombreuses situations que je ne peux pas expliquer ici (rflchissez ce qui ce doit se passer lors dun MERGE avec intgrit rfrentielle, ou un trigger before row insert, ou un update restart. Et le comportement change avec les versions dOracle. Mais en rflchissant ce qui est modifi et ce qui a besoin dtre lu avec des lectures bloquantes, on peut arriver comprendre ce quil

Oprations sur les tables

Un SELECT simple, sans for update, est une lecture non-bloquante, qui na besoin daucun verrou sous Oracle. Vous pouvez mme supprimer une table pendant que vous tes en train de la lire. INSERT, UPDATE, DELETE, MERGE crivent des lignes, donc ils posent un verrou TM en mode RowX (en plus du verrouillage ligne TX des lignes effectivement modifies). Cest un verrou dintention, avant mme daller voir les lignes, mme si la requte ne touche aucune ligne. SELECT FOR UPDATE fait des lectures non bloquantes sur des lignes, donc il posait un Row-S avant la 9i. Mais maintenant, il a le mme comportement quun update : Row-X aussi. Lintgrit rfrentielle a besoin de plus de verrous. Par exemple pour faire un insert dans une table fille, il

phpsolmag.org/fr

HORS SRIE

Les diffrents modes de verrous sous Oracle

se passe. Et il y a aussi la possibilit de le tester nous le verrons plus loin. En plus de ces oprations, vous pouvez poser des verrous avec linstruction LOCK TABLE avec les modes suivants: ROW SHARE, ROW EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE Et vous vous trouvez quil ny a pas assez de synonmes pou Row-S ? Et bien vous pouvez en poser un avec LOCK TABLE IN SHARE UPDATE MODE aussi...

Et comme S (et le S de SRX) nest pas compatible avec le RX de SRX, alors S/SRX et SRX/SRX se sont pas compatible non plus. Par contre, il ny a pas dincompatibilit avec RS/SRX On a donc retrouv la matrice facilement. Pas besoin de la retenir.

Vues du dictionnaire

Matrice de compatibilit

La raison dtre de tous ces modes, cest de permettre ou bloquer des accs concurrents. La table 3 montre ce quon trouve dans la documentation Oracle (je nai pas mis le verrou null qui est compatible avec tout).
Table 3. Compatibilit des modes de verrou

On a vu assez de thorie pour passer maintenant la pratique. Comment voir ces verrous. Je vais faire une opration DML et voir tous les informations quon a dans les vues du dictionnaire.

SESSION1> select sid from v$mystat where rownum=1; SID 13

modes compatible ?
SS,RS SX,RX S SSX, SRX X

SS,RS SX,RX
oui oui oui oui non oui oui non non non

S
oui non oui non non

SSX,SRX
oui non non non non

X
non non non non non

----------

SESSION1> update test set dummy=Y; 1 row updated.

Avez-vous dj essay de retenir cette table ? Aprs avoir compris la signification de chaque mode, voyons si cest toujours aussi difficile. On la vu pour X et S, par dfinition, la matrice donne: S/S compatible mais S/X et X/X incompatible. Pour les sous-ensembles (Sub/Row), cest diffrent. Modifier quelques lignes dune table nempche pas une autre session de modifier quelques (autres) lignes de la mme table. Le conflit ligne ligne est gr par les verrous au niveau ligne (TX). Ici, nous parlons ici de verrous table (TM). On rajoute donc dans la matrice: RS/RS, RX/RX, RS/ RX possibles. Par contre, entre une ressources et ses sous-ressources, il peut y avoir conflit. Si toute la table a un verrou exclusif (X) pos par une autre session, alors il est impossible de poser un verrou mme sur quelques lignes (RX). Et si il y a un verrou exclusif sur quelques lignes (RX) alors cela empche de poser un verrou partag sur toute la table (S). On rajoute donc la matrice: X/RX et S/RX incompatibles. Mais, S/RS sont partags, donc compatibles. Il nous reste Share Row eXclusive (SRX). en fait cest un S+RX: la table a un verrou partag mais un sous ensemble de lignes a un verrou exclusif. Comme X ou RX nest pas compatible avec le S de SRX, alors X/SRX et RX/SRX ne sont pas compatibles.

Donc je suis dans la session 1 (SID=13) et jai fait un update dune ligne de la table TEST.

DBA_LOCKS montre tous les types de verrous


SESSION1> select * from dba_locks where session_ id=13;

SESSION_ID LOCK_TYPE

LOCK_ID1 LOCK_ID2 LAST_CONVERT BLOCKING_OTHERS

MODE_HELD

MODE_REQUESTED

---------- ------------ -------------- ------------- -------- -------- ------------ ----------------723764 524303 13 DML 0 Row-X (SX) Exclusive 1 Not Blocking 1 Not Blocking None None

13 Transaction 43037

Ma transaction a acquis 2 types de verrous: un verrou transaction (TX) en mode exclusif pos lorsque notre transaction a dmarr. LOCK_ ID1 and LOCK_ID2 identifient la transaction (USN/ SLOT/SQN sont cods en 2 entiers) in verrou table (DML) en mode Row-X pos par lordre update vu quil a lintention de verrouiller des lignes. LOCK_ID1 est lobject_id de la table.

HORS SRIE

phpsolmag.org/fr

Les diffrents modes de verrous sous Oracle

DBA_DML_LOCKS ne montre que les verrous TM


SESSION1> select sid from v$mystat where rownum=1; SESSION1> select * from dba_dml_locks where session_ id=13; ---------SESSION2> lock table test in share mode; 47 SID

SESSION_ID OWNER

LAST_CONVERT BLOCKING_OTHERS

NAME

MODE_HELD

MODE_REQUESTED

---------- -------- -------- -------------- ------------------- ------------ -------------------13 E_FRANCK TEST 1 Not Blocking Row-X (SX) None

Cette deuxime session (SID=47) est en attente et jouvre une autre session pour voir le blocage.

SQL> select * from dba_locks where session_id=13; SESSION_ID LOCK_TYPE MODE_HELD MODE_REQUESTED

Ici object_id a t traduit en owner et object_name. Si lon va voir la vue ALL_OBJECTS, le OBJECT_ID de la table E_FRANCK.TEST est 723764 ce qui correspond au LOCK_ID1 donn par DBA_LOCKS. LAST_CONVERT montre que la transaction a dmarr il y a 1 seconde et que lUPDATE a dmarr il y a une seconde aussi. Nous verrons plus loin le moment exact o les verrous sont poss.

LOCK_ID1 LOCK_ID2 LAST_CONVERT BLOCKING_OTHERS

---------- ------------ -------------- ------------- -------- -------- ------------ ----------------723764 524303 13 DML 0 Row-X (SX) Exclusive 10 Blocking 10 Not Blocking None None

13 Transaction 43037

V$LOCKED_OBJECTS montre aussi les verrous TM


SESSION1> select * from v$locked_object where session_id=13; XIDUSN

La premire session (SID=13) a toujours les mmes verrous, mais maintenant le verrou DML bloque une autre session.

ORACLE_USERNAME OS_USER_NAME

XIDSLOT

XIDSQN

OBJECT_ID SESSION_ID PROCESS LOCKED_MODE

SQL> select * from dba_locks where session_id=47; SESSION_ID LOCK_TYPE BLOCKING_OTHERS MODE_REQUESTED LOCK_ID1 LOCK_ID2 LAST_CONVERT ---------- ------------ -------------- ------------- -------- -------- ------------ ----------------723764 47 DML 0 None 10 Not Blocking Share MODE_HELD

---------- ---------- ---------- ---------- --------- --------------- ------------- ------- ----------8 FRANCK 15 e_FRANCK 43037 723764 6674 13 E_ 3

Il y a ici de nouvelles informations Commenons par lidentifiant de transaction (XIDUSN,XIDSLOT,XIDSQN). Regardons les LOCK_ID1 and LOCK_ID2 que nous avions pour le verrou TX: LOCK_ID1= XIDUSN*65536+XIDSLOT and LOCK_ ID2=XIDSQN Ce qui veut dire que les verrous TX et TM sont poss par la mme transaction. Nous aussi avons le username Oracle ainsi que le username et PID de lOS Le mode de verrou est ici identifi par son numro. Le mode 3 correspond Row-X. Voil les verrous poss par ma session. Maintenant jouvre une autre session et jessaie de verrouiller la table TEST en mode partag:

La deuxime session (SID=47 qui a fait le lock table) na pas encore acquis (HELD) de verrou. Elle est en attente (REQUESTED) pour pouvoir poser le verrou en mode Share sur la table (object_id 723724).

DBA_BLOCKERS donne les sessions qui en bloquent dautres


SESSION1> select * from dba_blockers; HOLDING_SESSION --------------13

phpsolmag.org/fr

HORS SRIE

Les diffrents modes de verrous sous Oracle

DBA_WAITERS donne plus dinformation sur les sessions qui sont bloques
SESSION1> select * from dba_waiters; MODE_HELD MODE_REQUESTED

V$SESSION_EVENT donne les statistiques cumules des wait events sur une session
SQL> select * from v$session_event where sid=47 and

WAITING_SESSION HOLDING_SESSION LOCK_TYPE

--------------- --------------- ------------ --------------- ---------------- ---------- -----------------47 13 DML Row-X (SX) Share 723764 0

LOCK_ID1

LOCK_ID2

event like enq%; SID EVENT

TOTAL_TIMEOUTS TIME_WAITED AVERAGE_WAIT

TOTAL_WAITS MAX_WAIT

---------- ----------------------------- ------------------------ ----------- ------------ -----------47 enq: TM - contention 296 281 86490 292.2 295

La deuxime session (SID=47) qui a demand le verrou TM en mode Share sur la table TEST (object_id 723764) est bloque, en attente de la session 13 qui a acquis le verrou sur la table en mode Row-X.

UTLLOCKT.SQL fournit la mme information

(script disponible dans ORACLE_HOME/rdbms/admin)

SQL>@ ?/rdbms/admin/utllockt.sql
WAITING_SESSION ----------------------------LOCK_TYPE MODE_REQUESTED MODE_HELD LOCK_ID1 LOCK_ID2 --------- -------------- --------- -------- ---------------- -------------- --------- -------- --------

13 47

None DML Share Row-X(SX) 723764

On voit mon verrou TM sur lequel ma session a attendu 86490 centisecondes (865 seconds, jai lanc cette requte une minute aprs la prcdente). Je sais quil ny a eu quune seule demande pour ce verrou, mais on voit 296 attentes sur le wait event enqueue. Cest parce que lattente sur un verrou nest pas faite avec un seul wait event. Lattente a un timeout au bout de 3 secondes (et lon voit a dans AVERAGE_WAIT la dure moyenne de chaque wait est de 3 secondes environ et par le nombre de timeouts qui atteint presque le nombre de waits). Cest le mode de fonctionnement: aprs avoir attendu 3 secondes, le process reprends la main, vrifie que lon est pas dans une situation de deadlock, puis attends nouveau 3 secondes.

Ici, on a la mme information, mais formate avec la hirarchie des sessions qui attendent.

V$SESSION_WAITS donne tous les wait events

Nous sommes intresss par les enqueues.

On a vu dans DBA_LOCKS que les verrous TM et TX sont arrivs en mme temps parce que notre transaction a dmarr avec lupdate. En vrit, cest le TM qui a t pos en premier pour la raison suivante: le verrou TM est au niveau table, il est pos ds que lupdate est excut et avant quil commence lire des lignes. le verrou TX et au niveau ligne, Mme si la ressource est la transaction, il est pos lorsquon lit une ligne. Je vais prouver cela. Je lance nouveau un update, mais cette fois il ne va modifier aucune ligne.

Les verrous ligne une fois de plus, les intentions et les transactions

SQL> select * from v$session_wait where event like enq%; SID EVENT P1TEXT P1RAW P2TEXT P2SECONDS_IN_WAIT

---------- -------------------- ---------- --------------- ---------- ---------object # 723764 47 enq: TM - contention name|mode --------------------00000000544D0004 802

Ici la deuxime session (SID=47) est en train dattendre sur un verrou TM. Elle attend depuis 802 secondes (jai lanc cette requte un peu plus tard). P2 est le object_ id (object #) et P1 donne le type et le mode du verrou (name|mode) en hexadecimal: 544D est le code ascii de TM and 4 is the lock mode (Share). Donc on a toute les informations partir des wait events: la session 47 attends depuis 802 seconds pour poser un verrou TM en mode S sur la table TEST.

SESSION1> select sid from v$mystat where rownum=1; ---------SESSION1> update test set dummy=Y where 0 = 1; 0 row updated. 18 SID

HORS SRIE

phpsolmag.org/fr

Les diffrents modes de verrous sous Oracle

Je suis dans la session 18, jai lanc un update qui na modifi aucune ligne.

SESSION1> select * from dba_locks where session_ id=18; SESSION_ID LOCK_TYPE MODE_HELD MODE_REQUESTED

LOCK_ID1 LOCK_ID2 LAST_CONVERT BLOCKING_OTHERS

---------- ------------ ---------------- ------------- -------- -------- ------------ ----------------18 DML 723764 0 Row-X (SX) 1 Not Blocking None

Mme si je nai modifi aucune ligne, jai acquis un Row-X en excutant lupdate, seulement par mon intention de modifier des lignes. Mais en fait, aucune ligne na t modifie, et il ny a donc pas encore de verrou TX. Je nai pas encore de verrou TX, mais je sais que je suis dans une transaction parce que mon verrou TM est li une transaction (et il sera relch lorsque je ferais un commit ou un rollback). Un doute l dessus ? Je vais vrifier dans V$LOCKED_OBJECT puisquil y a linformation de transaction (USN/SLOT/SQN) de mon verrou TM.

Ma transaction na pas de USN/SLOT/SQL ils sont tous zro - parce quil ny a pas encore dentre dans la table de transaction du tablespace undo (vu quaucune modification de donne na encore eu lieu). Et si je regarde V$TRANSACTION je ne verrais rien non plus. Par contre, dans V$SESSION il y a ladresse de ma transaction dans TADDR. Quest-ce que cela veut dire ? Je suis dans une transaction (je nai aucun doute l dessus parce que jai fait un update et cest une opration qui se fait dans une transaction). Ma transaction a une adresse, mais aucune entre dans la table des transactions. Donc, la ressource verrouille par le verrou TX est une entre de la table des transactions plutt quune transaction, et V$TRANSACTION montre les entres de la table des transactions plutt que des transactions. Je nai rien crit encore, mais mon intention dcrire dans la table TEST est reste marque par le verrou en mode Row-X, et elle restera jusqu la fin de ma transaction.

Conclusion

SESSION1> select * from v$locked_object where session_id=13; XIDUSN XIDSLOT XIDSQN OBJECT_ID SESSION_ID PROCESS LOCKED_MODE

Cet article a pour but de clarifier la logique et la signification quil y a derrire les verrous sous Oracle afin de mieux comprendre pourquoi des verrous sont poss, et ce quils bloquent ou non. Le but est de prvoir, ds le dveloppement, les problmes quon peut rencontrer en production avec de multiples sessions concurrentes. Car les problmes peuvent avoir de grosses consquences : utilisateurs bloqus, deadlocks, etc.

ORACLE_USERNAME OS_USER_NAME

---------- ---------- ---------- ---------- ------------------------ ------------- ------- ---------------0 18 E_FRANCK 0 e_FRANCK 0 723764 11210 3

FRANCK PAChOT
Franck Pachot est DBA, consultant pour Trivadis en Suisse Romande. Aprs plus de 15 ans travailler sur diffrents SGBD, aussi bien en dveloppement /modlisation quen exploitation, il est aujourdhui expert en performance Oracle. Contact : franck.pachot@trivadis.com

phpsolmag.org/fr

HORS SRIE

Vous aimerez peut-être aussi