Error ORA-02049

En este caso me encuentro con un error en una de las bases de datos que administro un tanto extraño. El error en cuestión es ORA-02049 al intentar una operación de update como la siguiente:

UPDATE  TABLA
   SET  CAMPO01 = NULL
 WHERE  CAMPO02 = '1307919910302000001020061994'; 
UPDATE  TABLA
*
ERROR at line 1:
ORA-02049: timeout: transacción distribuida esperando bloqueo
ORA-02063: line precediendo a ENLACE_REMOTO

Una pequeña dificultad añadida es que la operación de update no se está haciendo sobre un objeto local, sino a través de un db_link sobre un objeto en una base de datos remota.

Tras comprobar que no hay bloqueos ni en la base de datos local ni el la remota, verificando así mismo el buen funcionamiento del db_link ENLACE_REMOTO, llego a la conclusión de que me encuentro ante un error con el que tengo que investigar un poco en google.

Lo primero es buscar el error en la base de datos Oracle Database Error Code. Allí encuentro lo siguiente:

ORA-02049:   timeout: distributed transaction waiting for lock
Cause:       exceeded INIT.ORA distributed_lock_timeout seconds waiting for lock.
Action:   treat as a deadlock

Como he comentado antes, bloqueos no hay en mis bases de datos; lo vuelvo a comprobar. De modo que sigo buscando por google, y encuentro la siguiente consulta (es grande):

SELECT se.username,
 NULL,
 se.sid,
 DECODE( se.command,
 0, 'No command',
 1, 'CREATE TABLE',
 2, 'INSERT',
 3, 'SELECT',
 4, 'CREATE CLUSTER',
 5, 'ALTER CLUSTER',
 6, 'UPDATE',
 7, 'DELETE',
 8, 'DROP CLUSTER',
 9, 'CREATE INDEX',
 10, 'DROP INDEX',
 11, 'ALTER INDEX',
 12, 'DROP TABLE',
 13, 'CREATE SEQUENCE',
 14, 'ALTER SEQUENCE',
 15, 'ALTER TABLE',
 16, 'DROP SEQUENCE',
 17, 'GRANT',
 18, 'REVOKE',
 19, 'CREATE SYNONYM',
 20, 'DROP SYNONYM',
 21, 'CREATE VIEW',
 22, 'DROP VIEW',
 23, 'VALIDATE INDEX',
 24, 'CREATE PROCEDURE',
 25, 'ALTER PROCEDURE',
 26, 'LOCK TABLE',
 27, 'NO OPERATION',
 28, 'RENAME',
 29, 'COMMENT',
 30, 'AUDIT',
 31, 'NOAUDIT',
 32, 'CREATE DATABASE LINK',
 33, 'DROP DATABASE LINK',
 34, 'CREATE DATABASE',
 35, 'ALTER DATABASE',
 36, 'CREATE ROLLBACK SEGMENT',
 37, 'ALTER ROLLBACK SEGMENT',
 38, 'DROP ROLLBACK SEGMENT',
 39, 'CREATE TABLESPACE',
 40, 'ALTER TABLESPACE',
 41, 'DROP TABLESPACE',
 42, 'ALTER SESSION',
 43, 'ALTER USER',
 44, 'COMMIT',
 45, 'ROLLBACK',
 46, 'SAVEPOINT',
 47, 'PL/SQL EXECUTE',
 48, 'SET TRANSACTION', 
 49, 'ALTER SYSTEM SWITCH LOG',
 50, 'EXPLAIN',
 51, 'CREATE USER',
 52, 'CREATE ROLE',
 53, 'DROP USER',
 54, 'DROP ROLE',
 55, 'SET ROLE',
 56, 'CREATE SCHEMA',
 57, 'CREATE CONTROL FILE',
 58, 'ALTER TRACING',
 59, 'CREATE TRIGGER',
 60, 'ALTER TRIGGER',
 61, 'DROP TRIGGER',
 62, 'ANALYZE TABLE',
 63, 'ANALYZE INDEX',
 64, 'ANALYZE CLUSTER',
 65, 'CREATE PROFILE',
 67, 'DROP PROFILE',
 68, 'ALTER PROFILE',
 69, 'DROP PROCEDURE',
 70, 'ALTER RESOURCE COST',
 71, 'CREATE SNAPSHOT LOG',
 72, 'ALTER SNAPSHOT LOG',
 73, 'DROP SNAPSHOT LOG',
 74, 'CREATE SNAPSHOT',
 75, 'ALTER SNAPSHOT',
 76, 'DROP SNAPSHOT',
 79, 'ALTER ROLE',
 85, 'TRUNCATE TABLE',
 86, 'TRUNCATE CLUSTER',
 88, 'ALTER VIEW',
 91, 'CREATE FUNCTION',
 92, 'ALTER FUNCTION',
 93, 'DROP FUNCTION',
 94, 'CREATE PACKAGE',
 95, 'ALTER PACKAGE',
 96, 'DROP PACKAGE',
 97, 'CREATE PACKAGE BODY',
 98, 'ALTER PACKAGE BODY',
 99, 'DROP PACKAGE BODY',
 TO_CHAR(se.command) ) command,
 DECODE(lo.type,
 'MR', 'Media Recovery',
 'RT', 'Redo Thread',
 'UN', 'User Name',
 'TX', 'Transaction',
 'TM', 'DML',
 'UL', 'PL/SQL User Lock',
 'DX', 'Distributed Xaction',
 'CF', 'Control File',
 'IS', 'Instance State',
 'FS', 'File Set',
 'IR', 'Instance Recovery',
 'ST', 'Disk Space Transaction',
 'TS', 'Temp Segment',
 'IV', 'Library Cache Invalidation',
 'LS', 'Log Start or Switch',
 'RW', 'Row Wait',
 'SQ', 'Sequence Number',
 'TE', 'Extend Table',
 'TT', 'Temp Table',
 'JQ', 'Job Queue',
 lo.type) ltype,
 DECODE( lo.lmode, 
 0, 'NONE', /* Mon Lock equivalent */
 1, 'Null Mode', /* N */
 2, 'Row-S (SS)', /* L */
 3, 'Row-X (SX)', /* R */
 4, 'Share (S)', /* S */
 5, 'S/Row-X (SSX)', /* C */
 6, 'Excl (X)', /* X */
 lo.lmode) lmode,
 DECODE( lo.request, 
 0, 'NONE', /* Mon Lock equivalent */
 1, 'Null', /* N */
 2, 'Row-S (SS)', /* L */
 3, 'Row-X (SX)', /* R */
 4, 'Share (S)', /* S */
 5, 'S/Row-X (SSX)', /* C */
 6, 'Excl (X)', /* X */
 TO_CHAR(lo.request)) request,
 lo.ctime ctime,
 DECODE(lo.block,
 0, 'No Block',
 1, 'Blocking',
 2, 'Global',
 TO_CHAR(lo.block)) blkothr,
 'SYS' owner,
 ro.name image
 FROM v$lock lo,
 v$session se,
 v$transaction tr,
 v$rollname ro
 WHERE se.sid = lo.sid
 AND se.taddr = tr.addr(+)
 AND tr.xidusn = ro.usn(+)
 ORDER BY sid

Lanzo esa consulta en la base de datos local, donde he recibido el error, y obtengo este resultado:

USERNAME        N  SID COMMAND              LTYPE                LMODE      REQUEST         CTIME BLKOTHR                   Owner IMAGE 
--------------- - ---- -------------------- -------------------- ---------- ---------- ---------- -------------------- ---------- --------------- 
CONCURSO            36 No command           Transaction          Excl (X)   NONE            14395 No Block             SYS        _SYSSMU10$
GESPER              44 No command           Transaction          Excl (X)   NONE             9670 No Block             SYS        _SYSSMU7$ 
GESPER              55 No command           Transaction          Excl (X)   NONE           163566 No Block             SYS        _SYSSMU1$ 
PETIPASO            58 No command           DML                  Row-X (SX) NONE            23985 No Block             SYS 
PETIPASO            72 No command           DML                  Row-X (SX) NONE            24883 No Block             SYS

Según esto, el usuario GESPER (que es el que a mi me interesa) tiene un bloqueo con dos sesiones. Aunque a mi no me aparecía ese bloqueo en el sistema de monitorización (Enterprise Manager Grid Control), ni siquiera con otros scrips pl/sql para detectar bloqueos, elimino esas sesiones: sin embargo, el problema sigue sin solucionarse. De modo que lanzo la misma consulta en la base de datos remota, obteniendo esto:

USERNAME        N        SID COMMAND         LTYPE                LMODE      REQUEST         CTIME BLKOTHR    OWN IMAGE
--------------- - ---------- --------------- -------------------- ---------- ---------- ---------- ---------- --- ---------------
PORTAL_ATRIL             414 No command      DML                  Row-X (SX) NONE           164010 Global     SYS _SYSSMU883$
PORTAL_ATRIL             414 No command      Transaction          Excl (X)   NONE           164010 Global     SYS _SYSSMU883$

Mismo caso que en la base de datos local. Pero esta vez al eliminar la sesión, el problema se soluciona. Ya se puede lanzar el update sin obtener el error.

3 Responses to Error ORA-02049

  1. Marvin dice:

    Me sirvio, tenia un problema similar, pero como sabes que es un bloqueo? perdon por mi ignorancia.

    • jop89s dice:

      Hola. El bloqueo lo verás claramente si tienes una herramienta como EMGC (Enterprise Manager Grid Control). Si no, hay algunos scripts para ‘sqlplus’ que te pueden ayudar. Si tengo tiempo, los publicaré en este mismo blog. Gracias por el comentario.

  2. Maria dice:

    Hola, tengo este mismo error pero eliminando los bloqueos generados al lanzar el update vuelve a producirse. Consigo hacer INSERT sin problema, pero el UPDATE no va… A parte de la solución, se podría conocer la causa?
    Gracias, María

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: