CÓMO

Identificar una fuga de cursor en Oracle

Last Published: February 10, 2024

Descripción

En este artículo se describe cómo identificar qué cursor de Oracle no se cierra ni se reutiliza en cada ejecución que conduce al siguiente error de Oracle:

"ORA-01000: maximum open cursors exceeded."

Es importante poder diagnosticar qué cursor se está "filtrando" (no cerrado) para identificar qué parte de la aplicación es responsable de administrar el cursor, Oracle, ArcGIS o el desarrollador de la aplicación.

Solución o solución alternativa

Las instrucciones proporcionadas demuestran cómo identificar los cursores que una aplicación no está cerrando o reutilizando durante una sesión de Oracle determinada.

  1. Identifique la sesión por su nombre de usuario de Oracle para recuperar el valor sid. Conéctese a la instancia de Oracle como SYS o SYSTEM o a un usuario con privilegios de DBA mediante SQL*Plus. Ejecute la siguiente instrucción SQL para obtener el valor sid de la sesión:
SQL> SELECT sid FROM v$session WHERE username = 'TOM';

SID
----------
135

El valor sid se utiliza en el paso siguiente para identificar la sesión que se va a investigar.

  1. Enumere las direcciones de instrucciones SQL de la sesión, que tienen más de una referencia activa. Con el valor sid de la instrucción anterior, ejecute una consulta en la vista v$open_cursor.
SQL> SELECT COUNT(*), address
2 FROM v$open_cursor
3 WHERE sid = 135
4 GROUP BY address HAVING COUNT(address) > 1 ORDER BY COUNT(*);

COUNT(*) ADDRESS
---------- --------
2 35E6083C
2 35B77834
2 35E686B4
3 35F97908

En el resultado se enumera cada cursor que ha sido abierto por la sesión más de una vez en orden descendente.

  1. Obtenga la instrucción SQL real de cada dirección devuelta en el paso 2. Esto se puede lograr consultando la vista v$sql mediante el uso del valor de dirección.
SQL> SELECT sql_fulltext
2 FROM v$sql
3 WHERE address = '35F97908';

SQL_FULLTEXT
-------------------------------------------------------------------------------
SELECT OBJECTID, SEG_ID, SYMBOL, PIPE_SIZE, SLOPE, US_INV,
DS_INV, ACC_NO, SEW_NO, MATERIAL, SEW_SHAPE, HEIGHT, WIDTH,
INST_YEAR, TV_LAST, DRAIN_AREA, MEAS_REF, SEP_COMB, PUB_PRI,
QUEST, SEG_TYPE, SSAD_LEN, V__43.st_SHAPE$, V__43.st_len$,
V__43.st_points, V__43.st_numpts, V__43.st_entity, V__43.st_minx,
V__43.st_miny, V__43.st_maxx,V__43.st_maxy, V__43.st_area$,
V__43.st_len$, V__43.st_rowid FROM
(SELECT b.OBJECTID, b.SEG_ID, b.SYMBOL, b.PIPE_SIZE, b.SLOPE, b.US_INV,
b.DS_INV, b.ACC_NO, b.SEW_NO, b.MATERIAL, b.SEW_SHAPE,
b.HEIGHT, b.WIDTH, b.INST_YEAR, b.TV_LAST, b.DRAIN_AREA,
b.MEAS_REF, b.SEP_COMB, b.PUB_PRI, b.QUEST, b.SEG_TYPE,
b.SSAD_LEN, 1 st_SHAPE$, b.SHAPE.points as st_points,
b.SHAPE.numpts as st_numpts, b.SHAPE.entity as st_entity, b.SHAPE.minx as st_minx,
b.SHAPE.miny as st_miny, b.SHAPE.maxx as st_maxx, b.SHAPE.maxy as st_maxy,
b.SHAPE.area as st_area$, b.SHAPE.len as
st_len$, b.rowid as st_rowid FROM TOM.sewers b
WHERE SDE.ST_EnvIntersects(b.SHAPE,:1,:2,:3,:4) = 1
AND b.OBJECTID NOT IN (SELECT /*+ HASH_AJ */ SDE_DELETES_ROW_ID
FROM TOM.D43 WHERE DELETED_AT IN (SELECT l.lineage_id
FROM SDE.state_lineages l WHERE l.lineage_name = :lineage_name1 AND l.lineage_id <= :state_id1)
AND SDE_STATE_ID = 0) UNION ALL SELECT a.OBJECTID, a.SEG_ID, a.SYMBOL, a.PIPE_SIZE, a.SLOPE,
a.US_INV, a.DS_INV, a.ACC_NO, a.SEW_NO, a.MATERIAL, a.SEW_SHAPE,
a.HEIGHT, a.WIDTH, a.INST_YEAR, a.TV_LAST, a.DRAIN_AREA,
a.MEAS_REF, a.SEP_COMB, a.PUB_PRI, a.QUEST, a.SEG_TYPE, a.SSAD_LEN, 2
st_SHAPE$ ,a.SHAPE.points as st_points, a.SHAPE.numpts as st_numpts,
a.SHAPE.entity as st_entity, a.SHAPE.minx as st_minx, a.SHAPE.miny as st_miny,
a.SHAPE.maxx as st_maxx, a.SHAPE.maxy as st_maxy, a.SHAPE.area as st_area$,
a.SHAPE.len as st_len$, a.rowid as st_rowid FROM TOM.A43 a, SDE.state_lineages SL
WHERE SDE.ST_EnvIntersects(a.SHAPE,:5,:6,:7,:8) = 1
AND (a.OBJECTID, a.SDE_STATE_ID) NOT IN (SELECT /*+ HASH_AJ */ SDE_DELETES_ROW_ID, SDE_STATE_ID
FROM TOM.D43 WHERE DELETED_AT IN (SELECT l.lineage_id FROM
SDE.state_lineages l WHERE l.lineage_name = :lineage_name2 AND l.lineage_id <= :state_id2)
AND SDE_STATE_ID > 0) AND a.SDE_STATE_ID = SL.lineage_id AND SL.lineage_name
= :lineage_name3 AND SL.lineage_id <= :state_id3) V__43

El resultado, en este escenario, es una consulta espacial versionada. En función de lo que esté haciendo la aplicación, posiblemente ArcObjects personalizados, hay tres referencias a esta instrucción SQL. La aplicación está abriendo tres referencias explícitas o la aplicación de ArcGIS no está reutilizando la instrucción SQL inicial.
Si necesita más ayuda para identificar la causa del problema, póngase en contacto con el soporte técnico de ESRI.

Id. de artículo: 000010136

Obtenga soporte con IA

Resuelva su problema rápidamente con el chatbot de inteligencia artificial de soporte de Esri.

Empieza a chatear ahora

Obtener ayuda de expertos en ArcGIS

Contactar con el soporte técnico

Empieza a chatear ahora

Ir a opciones de descarga