操作方法

操作方法:识别 Oracle 中的游标泄漏

Last Published: February 10, 2024

描述

本文介绍如何识别导致以下 Oracle 错误的每次执行时未关闭或未重用的 Oracle 游标:

"ORA-01000: maximum open cursors exceeded."

能够诊断哪个游标正在被“泄漏”(未关闭)非常重要,这样才能确定应用程序的哪个部分负责管理游标:Oracle、ArcGIS 或应用程序开发人员。

解决方案或解决方法

以下说明演示了如何针对给定的 Oracle 会话,识别应用程序没有关闭或重用的游标。

  1. 通过 Oracle 用户名识别会话,检索 sid(会话 ID)值。 使用 SQL*Plus 以 SYS 或 SYSTEM 用户,或具有 DBA 权限的用户身份连接到 Oracle 实例。 执行以下 SQL 语句,获取会话的 sid 值:
SQL> SELECT sid FROM v$session WHERE username = 'TOM';

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

sid 值将在下一步中用于标识要调查的会话。

  1. 列出具有多个活动引用的会话的 SQL 语句地址。 使用上一步语句中的 sid 值,对 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

结果列出了会话多次打开的每个游标,并按打开次数降序排列。

  1. 获取步骤 2 中返回的每个地址的实际 SQL 语句。 这可以通过使用地址值查询 v$sql 视图来实现。
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

在本例中,结果是一个版本化的空间查询。 根据应用程序正在执行的操作(可能是自定义的 ArcObjects),对这条 SQL 语句有三个引用。 可能存在以下两种情况:一是应用程序主动创建了三个显式引用;二是 ArcGIS 应用程序未能有效地重用初始 SQL 语句。
如需进一步分析问题原因,请联系 ESRI 技术支持部门。

文章 ID: 000010136

获得人工智能支持

使用 Esri Support AI Chatbot 快速解决您的问题。

立即开始聊天

相关信息

发现关于本主题的更多内容

获取来自 ArcGIS 专家的帮助

联系技术支持部门

立即开始聊天

转至下载选项