Вы находитесь на странице: 1из 8

El �abrazo mortal� en Oracle

Fernando Garcia
Follow Fernando Garcia / 2.21.2015 at 4:30pm
De todo los posts que he publicado en Toad World, los dos primeros en el ranking de
lecturas giran en torno a un mismo tema: la concurrencia. Y hay una diferencia en
cantidad de lecturas bastante considerable con respecto al resto de los art�culos.
En los cursos de lenguaje SQL que he dictado hace un tiempo, tambi�n not� un
inter�s creciente de los participantes cuando habl�bamos acerca de concurrencia y
lockeos.

Es evidente que el tema de la concurrencia atrae a la audiencia. Y a m� me encanta


que mis art�culos sean le�dos. As� que hoy voy a volver a tocar este tema.

Lleg� el turno del "abrazo mortal".

El "abrazo mortal", tambi�n conocido como "deadlock", no es un tema propio de las


bases de datos Oracle. El "abrazo mortal" es una situaci�n inherente a la
programaci�n concurrente y tanto los motores de bases de datos como los sistemas
operativos y los desarrolladores de aplicaciones no pueden permanecer indiferentes
a esta circunstancia. Dicho esto, en esta ocasi�n veremos c�mo se comporta el motor
de base de datos Oracle frente a un escenario de "abrazo mortal".

Pero antes de sumergirnos en la resoluci�n de la situaci�n, hagamos una breve


introducci�n al problema.

Cuando hablamos de concurrencia, hablamos de situaciones de acceso simult�neo y


competencia por el uso de un recurso.

�Qu� es el "abrazo mortal"? El ejemplo que da Wikipedia es muy ilustrativo.


Supongamos que hay dos ni�os: uno rubio y uno moreno. Ambos quieren jugar a "los
indiecitos" pero hay solamente un arco y solamente una flecha. El ni�o rubio toma
el arco, el ni�o moreno toma la flecha. El ni�o rubio espera a que el moreno libere
la flecha para poder jugar. El ni�o moreno espera a que el rubio abandone el arco
para poder jugar. Ambos se quedan en una situaci�n de espera mutua por tiempo
indefinido. Y ninguno de los dos puede continuar con su entretenido pasatiempo. Ha
ocurrido un "abrazo mortal".

Reproduzcamos el juego de los "indiecitos" en nuestra base de datos Oracle, y


veamos qu� ocurre.

Comencemos simulando a los ni�os, creando un usuario "RUBIO" y un usuario "MORENO"

SQL> create user rubio identified by rubio


2 /

User created.

SQL> create user moreno identified by Moreno


2 /

User created.

SQL> grant create session to rubio, Moreno


2 /

Grant succeeded.

SQL>
Para simular los juguetes vamos a crear una tabla de JUGUETES con dos filas: una
para el arco y otra para la flecha.

SQL> create table juguetes


2 (juguete varchar2(10), estado char(1))
3 /

Table created.

SQL> insert into juguetes values ('ARCO', 'L')


2 /

1 row created.

SQL> insert into juguetes values ('FLECHA', 'L')


2 /

1 row created.

SQL> commit
2 /

Commit complete.

SQL> grant select, insert, update, delete on juguetes to rubio, Moreno


2 /

Grant succeeded.

SQL> create public synonym juguetes for fmgarcia.juguetes


2 /

Synonym created.

SQL>

A continuaci�n simulamos el intento de jugar a los "indiecitos". El ni�o rubio y el


moreno intentar�n quedarse con el arco y la flecha.

sqlplus rubio/rubio

sqlplus moreno/moreno

Ambos ni�os se conectan a la base

SQL> update juguetes


set estado = 'O'
where juguete = 'ARCO'
2 /

1 row updated.

SQL>

El ni�os rubio toma el arco


SQL> update juguetes
2 set estado = 'O'
3 where juguete ='FLECHA'
4/

1 row updated.

SQL>

El ni�o moreno toma la flecha

SQL> update juguetes


2 set estado = 'O'
3 where juguete = 'FLECHA'
4 /

El ni�o rubio intenta tomar la flecha. Sqlplus no retorna el prompt. El ni�o rubio
se queda esperando

SQL> update juguetes


2 set estado = 'O'
3 where juguete = 'ARCO'
4 /

El ni�o moreno intenta tomar el arco. Sqlplus no retorna el prompt. El ni�o moreno
se queda esperando

ERROR at line 2:

ORA-00060: deadlock detected while waiting for resource

SQL>

Oracle detecta la situaci�n de abrazo mortal, eligi� al ni�o rubio como �v�ctima�.

El ni�o moreno sigue esperando.

SQL> select * from juguetes


2 /

JUGUETE E
---------- -
ARCO O
FLECHA L

SQL>

Adicionalmente, Oracle hizo rollback de la �ltima sentencia del ni�o rubio (la
flecha no pas� a estado �O�).
SQL> rollback
2 /

Rollback complete.

SQL>

El ni�o rubio decide �abandonar� todo haciendo rollback.

1 row updated.

SQL>

Autom�ticamente el ni�o moreno recibe el prompt y Sqlplus le notifica que actualiz�


una fila

Con este peque�o ejemplo hemos visto que Oracle detecta y resuelve autom�ticamente
las situaciones de �abrazo mortal�, elige una v�ctima y hace rollback de la �ltima
sentencia de dicha v�ctima. Cuando la v�ctima hace COMMIT o ROLLBACK de la
transacci�n, la otra sesi�n bloqueada se libera.

�Podemos hacer algo para saber si en nuestra base de datos est�n ocurriendo
�abrazos mortales�? La respuesta es afirmativa. Cada vez que Oracle detecta un
abrazo mortal genera un archivo de trace con detalles de lo ocurrido. �D�nde queda
el archivo? La ubicaci�n est� determinada por el valor del par�metro
USER_DUMP_DEST:

SQL> show parameter user_dump_dest

NAME TYPE VALUE


--------------------- -------- ------------------------------
user_dump_dest string /u01/app/oracle/diag/rdbms/orc l/orcl/trace

SQL>

Luego buscamos el archivo en dicha ubicaci�n. He aqu� un extracto del archivo


generado a partir de la prueba que hemos hecho recientemente:

*** 2015-02-21 10:41:38.335

DEADLOCK DETECTED ( ORA-00060 )

[Transaction Deadlock]

The following deadlock is not an ORACLE error. It is a


deadlock due to user error in the design of an application
or from issuing incorrect ad-hoc SQL. The following
information may aid in determining the deadlock:

Deadlock graph:
---------Blocker(s)-------- ---------
Waiter(s)---------
Resource Name process session holds waits process
session holds waits
TX-00050010-000009E4-00000000-00000000 39 38 X 36 53
X
TX-0003001C-000009E4-00000000-00000000 36 53 X 39

Esto ha sido todo por hoy. Hemos visto qu� es un abrazo mortal, lo hemos generado
de manera �artificial� y pudimos ver el comportamiento de Oracle ante un escenario
de este tipo.

La seguimos en el pr�ximo art�culo!

Fernando.

El an�lisis forense de un �abrazo mortal�


Fernando Garcia
Follow Fernando Garcia / 3.2.2015 at 11:06pm
Este art�culo est� dedicado a Juan Dabarca y a todos los DBAs que est�n trabajando
en Zaragoza, Espa�a. Para aprovecharlo mejor, es altamente recomendable leer mi
post anterior titulado �El abrazo mortal en Oracle�

Por lo general, el DBA es quien descubre los vestigios de un abrazo mortal ocurrido
en la base de datos. �Por qu�? En su rutina de controles y verificaciones
peri�dicas el administrador de la base de datos tropieza con la evidencia del
abrazo mortal en los archivos de trace generados en el servidor. A partir de dicho
hallazgo el DBA iniciar� un an�lisis forense de las evidencias a fin de esclarecer
lo acontecido.

Hagamos entonces un peque�o an�lisis forense del archivo de trace generado a partir
del abrazo mortal provocado artificialmente en mi art�culo anterior.

Como parte de su rutina el DBA verifica si ha ocurrido un abrazo mortal en la base


de datos. Verifiquemos pues el archivo de alertas de la base.

[oracle@localhost trace]$ grep -i deadlock alert_orcl.log

ORA-00060: Deadlock detected. More info in file


/u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_2864.trc.

[oracle@localhost trace]$

De acuerdo con el archivo de alertas ha ocurrido un abrazo mortal (Deadlock


detected), y el archivo de trace lleva el nombre orcl_ora_2864.trc. Continuemos:

[oracle@localhost trace]$ ls -l orcl_ora_2864.trc

-rw-r-----. 1 oracle oracle 713118 Feb 21 10:41 orcl_ora_2864.trc

[oracle@localhost trace]$

Ya sabemos al menos dos cosas:

1) Que en nuestra base de datos ha ocurrido un abrazo mortal


2) Que el abrazo mortal ha ocurrido el 21 de febrero a las 10:41

Al abrir el archivo, una de las primeras cosas interesantes que encontramos es lo


siguiente.

*** 2015-02-21 10:41:38.335


*** SESSION ID:(38.177) 2015-02-21 10:41:38.335
*** CLIENT ID:() 2015-02-21 10:41:38.335
*** SERVICE NAME:(pdb1) 2015-02-21 10:41:38.335
*** MODULE NAME:(SQL*Plus) 2015-02-21 10:41:38.335
*** ACTION NAME:() 2015-02-21 10:41:38.335
*** CONTAINER ID:(3) 2015-02-21 10:41:38.335

En este punto es importante recalcar que si la aplicaci�n hubiese estado


instrumentada, esta porci�n del archivo habr�a sido trascendental para determinar
en qu� parte de la aplicaci�n se gener� el abrazo mortal. El tema de la
instrumentaci�n es muy interesante, y en el futuro me gustar�a escribir sobre este
tema. Lamentablemente encontrar aplicaciones instrumentadas es pr�cticamente tan
dif�cil como ganar la loter�a. Dicho esto, �qu� provecho podemos sacar de estas
l�neas? Gracias a La l�nea �SESSION ID� descubro que la sesi�n 38 fue la v�ctima.
Como hubo un abrazo mortal, puedo concluir que Oracle hizo rollback autom�tico de
la �ltima sentencia de una de las dos sesiones involucradas. Gracias a esta l�nea
s� que Oracle hizo rollback de la �ltima sentencia de la sesi�n 38; y
adicionalmente Oracle gener� este archivo de trace que estamos analizando y que
corresponde a la sesi�n 38.

Sigo observando el archivo y encuentro lo que se conoce como �gr�fico del abrazo
mortal�:

Deadlock graph:

---------Blocker(s)--------
---------Waiter(s)---------
Resource Name process session holds waits process
session holds waits
TX-00050010-000009E4-00000000-00000000 39 38 X 36 53
X
TX-0003001C-000009E4-00000000-00000000 36 53 X 39 38
X

Con estas l�neas comienza a develarse parte del misterio. �Qui�nes intervinieron
en el abrazo mortal? Las sesiones 38 y 53. �Y a qui�n corresponden estas sesiones?
M�s abajo en el archivo observo:

----- Information for the OTHER waiting sessions ----


Session 53:
sid: 53 ser: 329 audsid: 8660004 user: 123/MORENO

Como este trace corresponde a la sesi�n 38, el archivo de trace rotula a la sesi�n
53 como �la otra sesi�n� (OTHER). Ahora sabemos que la �otra sesi�n� era del
usuario MORENO.

�Y a qu� usuario pertenec�a la sesi�n 38? Si avanzamos un poco m�s en el archivo


encontramos:

��..
Information for THIS session:
�.

(session) sid: 38 ser: 177 trans: 0x75576920, creator: 0x78645628
flags: (0x45) USR/- flags_idl: (0x1) BSY/-/-/-/-/-
flags2: (0x40009) -/-/INC
DID: 0001-0027-00000007, short-term DID: 0000-0000-00000000
txn branch: (nil)
con_id/con_uid/con_name: 3/3345156736/PDB1
edition#: 133 user#/name: 122/RUBIO

Gracias a todo este an�lisis ya sabemos varias cosas:

1) Que en nuestra base de datos ha ocurrido un abrazo mortal

2) Que el abrazo mortal ha ocurrido el 21 de febrero a las 10:41

3) Que los actores del abrazo mortal fueron RUBIO y MORENO

4) Que la v�ctima elegida por Oracle fue RUBIO y que su �ltima sentencia fue
autom�ticamente �rollbackeada�

Si seguimos analizando el archivo nos toparemos tambi�n con las sentencias


intervinientes. Como en el ejemplo no hemos utilizado variables de binding,
simplemente mirando estas sentencias podremos determinar qu� tablas y qu� filas
constituyeron el origen del abrazo mortal. Pero para hacer el an�lisis m�s amplio,
y asumiendo que la mayor�a de las veces deber�amos encontrarnos con variables de
binding, continuamos el an�lisis en la siguiente secci�n del archivo de trace.

Rows waited on:


Session 38: obj - rowid = 000176BF - AAAXa/AANAAAACDAAB
(dictionary objn - 95935, file - 13, block - 131, slot - 1)
Session 53: obj - rowid = 000176BF - AAAXa/AANAAAACDAAA
(dictionary objn - 95935, file - 13, block - 131, slot - 0)

La sesi�n 38, es decir la del usuario RUBIO estaba esperando por la fila cuyo ROWID
era el AAAXa/AANAAAACDAAB y que pertenece al objeto 95935. Veamos:

SQL> select object_name


2 from dba_objects
3 where object_id = 95935
4 /

OBJECT_NAME
-----------
JUGUETES

SQL> select * from juguetes where rowid = 'AAAXa/AANAAAACDAAB';

JUGUETE E
--------- -
FLECHA O

Rubio estaba esperando por la flecha.

La sesi�n 53, es decir la del usuario MORENO estaba esperando por la fila cuyo
ROWID era el AAAXa/AANAAAACDAAA y que pertenece tambi�n al mismo objeto. Analicemos
entonces solamente el ROWID:

SQL> select * from juguetes where rowid = 'AAAXa/AANAAAACDAAA'


2 /
JUGUETE E
--------- -
ARCO O

SQL>

Moreno estaba esperando por la flecha.

Finalmente nos queda el escenario completo:

1) En nuestra base de datos ha ocurrido un abrazo mortal

2) El abrazo mortal ocurri� el 21 de febrero a las 10:41

3) Los actores del abrazo mortal fueron el ni�o rubio y el ni�o moreno

4) En el momento del abrazo mortal el ni�o rubio quiso tomar la flecha, que
estaba en poder del ni�o moreno.

5) En el momento del abrazo mortal el ni�o moreno quiso tomar el arco, que
estaba en poder del ni�o rubio

6) La v�ctima elegida por Oracle fue el ni�o rubio y su �ltima sentencia fue
autom�ticamente �rollbackeada�

Gracias al an�lisis forense del archivo de trace, hemos reconstruido la escena del
abrazo mortal.

Nos vemos!

Fernando.

Вам также может понравиться