ArcGIS 10.x for Oracle (2014年10月发布)优化Open_Cursors的性

2014-12-29

由于Oracle在2014年10月份发布 Critical Patch Update 补丁的原因,ArcGIS不能直接从Oracle实例中获取Open_Cursors参数,除非当前连接的用户有访问v$parameter 视图的权限,但是一般情况下非管理员账户是没有对该视图访问的权限。

如果地理数据库没有对Open_Cursors值的访问权限,系统就会报:ORA-01000: maximum open cursors exceeded。为了提高Oracle地理数据库的性能以及可伸缩性,Oracle 建议的最佳做法是保持游标处于打开状态, 以避免系统挣用Oracle全局区 (SGA) 的游标。

ArcGIS在很多场景下都会使用Oracle游标,比如空间查询,编辑操作、读取字典表等

由于Oracle10月份的这个CPU补丁,ArcGIS在获取Open_Cursors值时,在执行dbms_utility.get_parameter_value会碰到一个错误,如果遇到该错误,ArcGIS会检查地理数据库管理员账户中的Server_Config表中是否包含Open_Cursors字段,如果参数不存在,ArcGIS默认设置该参数值为300.

如果ArcGIS客户端连接的是一个非地理数据库的Oracle实例,连接会话仍然会执行dbms_utility.get_parameter_value,如果碰到错误,ArcGIS也会自动的为Open_cursors设为300.

 

但是前提是Oracle地理数据库实例中的管理员账户的Server_config表中包含Open_Cursors的字段。所以我们需要在该表中添加该字段记录,默认是没有该记录的。

 

该问题涉及到ArcGIS版本包括:10.1, 10.2, 10.2.1, 10.2.2, 10.3

 

解决方法

1:打上ArcGIS发布的最新补丁,截止到博文发布,目前补丁只有ArcGIS 10.2.2,其他版本补丁还在调试当中。

 ArcGIS ‘Oracle Critical Patch Update – October 2014′ Connection Issue Patch

下载链接

2:直接使用SQL语句解决该问题(其他版本适用)

a):使用管理员账户,为地理数据库管理员对V$Parameter视图赋予权限。

 GRANT SELECT ON v$parameter TO SDE;
 GRANT SELECT ON v$parameter TO SDE
                 *
 1 行出现错误:
ORA-02030: 只能从固定的表/视图查询

 

其实该视图只是一个同义词,通过以下SQL语句来说的相关表名

select synonym_name,table_name from dba_synonyms where synonym_name='V$PARAMETER';
SYNONYM_NAME                   TABLE_NAME
------------------------------ ------------------------------
V$PARAMETER                    V_$PARAMETER

然后赋予地理数据库管理员选择该表的权限即可

GRANT SELECT ON v_$parameter TO SDE;

 

b):使用地理管理员用户连接,执行如下存储过程,目的就是往相关地理管理员账户的Server_Config表中添加Open_Cursors值

DECLARE
  rval        INTEGER;
  ival        INTEGER := 0;
  pname       VARCHAR2 (256) := 'OPEN_CURSORS';
  sval        VARCHAR2(256);
  gdb_name    NVARCHAR2(256);
  cprop_val   VARCHAR2(256) := NULL;
  c1          INTEGER;
  c1_status   INTEGER;
  sqlstmt     CLOB;

  CURSOR instances_curs IS
    SELECT instance_name 
    FROM sde.instances;
   
BEGIN
  rval := dbms_utility.get_parameter_value(pname, ival, sval);

  IF ival > 0 THEN
    OPEN instances_curs;
    FETCH instances_curs INTO gdb_name;

    WHILE instances_curs%FOUND
      LOOP
        sqlstmt :=
              'BEGIN '
            ||  gdb_name
            || '.svr_config_util.insert_server_config(:s1,:s2,:s3); ' 
            || 'EXCEPTION WHEN DUP_VAL_ON_INDEX THEN '
            ||  gdb_name 
            || '.svr_config_util.update_server_config(:s1,:s2,:s3); '
            || 'END;';

        IF NOT dbms_sql.is_open (c1) THEN
            c1 := dbms_sql.open_cursor;
        END IF;

        dbms_sql.parse (c1, TO_CHAR (sqlstmt), dbms_sql.native);
        dbms_sql.bind_variable (c1, ':s1', pname);
        dbms_sql.bind_variable (c1, ':s2', cprop_val);
        dbms_sql.bind_variable (c1, ':s3', ival);

        c1_status := dbms_sql.execute (c1);
        dbms_sql.close_cursor (c1);

        FETCH instances_curs INTO gdb_name;
    END LOOP;

    CLOSE instances_curs;
  END IF;
   
 EXCEPTION
   WHEN OTHERS THEN
      RAISE;
END;
/

 

c):然后再取消该地理管理员对V$PARAMETER的执行权限

REVOKE SELECT ON v_$parameter FROM SDE;

 

接下来,我们查看Server_Config表里面的值,发现已经有Open_Cursors项,当然默认的300可能比较少,根据情况可以直接增大到2000.

 

iarcgis.com,版权所有丨如未注明,均为原创丨本网站采用BY-NC-SA协议进行授权,转载请注明转自:http://www.iarcgis.com/?p=315