【SQL_TRACE】解決普通使用者無法執行SQL_TRACE跟蹤其他會話問題

secooler發表於2009-10-14
1.為了跟蹤一個異常的會話,偶然在sec使用者下執行了如下的SQL_TRACE語句對532會話進行跟蹤,不過報錯無法完成。故troubleshooting一下,記錄在此
sec@ora10g> exec dbms_system.set_sql_trace_in_session(532,2204,true);
BEGIN dbms_system.set_sql_trace_in_session(532,2204,true); END;

      *
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00201: identifier 'DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

2.從報錯的表面現象上分析,提示資訊提到找不到這個包,首先應該能想到,sec這個普通使用者沒有這個包的定義。這是顯然的
sec@ora10g> desc DBMS_SYSTEM
ERROR:
ORA-04043: object DBMS_SYSTEM does not exist

3.這個DBMS_SYSTEM包的主人是誰呢?這裡給出兩種檢視的方法
1)第一種方法是,我們使用dbms_metadata.get_ddl方法檢視一下
sys@ora10g> select dbms_metadata.get_ddl('PACKAGE','DBMS_SYSTEM') from dual;

DBMS_METADATA.GET_DDL('PACKAGE','DBMS_SYSTEM')
---------------------------------------------------------------------

  CREATE OR REPLACE PACKAGE "SYS"."DBMS_SYSTEM" wrapped
... 省略其他的內容 ...

2)第二種方法是透過dba_objects檢視得到這個物件的主人
sys@ora10g> col OWNER for a30
sys@ora10g> col OBJECT_NAME for a30
sys@ora10g> col OBJECT_TYPE for a30
sys@ora10g> select OWNER,OBJECT_NAME,OBJECT_TYPE from dba_objects where object_name = 'DBMS_SYSTEM';

OWNER                          OBJECT_NAME            OBJECT_TYPE
------------------------------ ---------------------- ----------------
SYS                            DBMS_SYSTEM            PACKAGE
SYS                            DBMS_SYSTEM            PACKAGE BODY

4.確認一下SYS使用者下是否存在這個包,答案是肯定的
sys@ora10g> desc DBMS_SYSTEM
PROCEDURE DIST_TXN_SYNC
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 INST_NUM                       NUMBER                  IN
PROCEDURE GET_ENV
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 VAR                            VARCHAR2                IN
 VAL                            VARCHAR2                OUT
PROCEDURE KCFRMS
PROCEDURE KSDDDT
PROCEDURE KSDFLS
PROCEDURE KSDIND
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 LVL                            BINARY_INTEGER          IN
PROCEDURE KSDWRT
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 DEST                           BINARY_INTEGER          IN
 TST                            VARCHAR2                IN
PROCEDURE READ_EV
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 IEV                            BINARY_INTEGER          IN
 OEV                            BINARY_INTEGER          OUT
PROCEDURE SET_BOOL_PARAM_IN_SESSION
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 SID                            NUMBER                  IN
 SERIAL#                        NUMBER                  IN
 PARNAM                         VARCHAR2                IN
 BVAL                           BOOLEAN                 IN
PROCEDURE SET_EV
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 SI                             BINARY_INTEGER          IN
 SE                             BINARY_INTEGER          IN
 EV                             BINARY_INTEGER          IN
 LE                             BINARY_INTEGER          IN
 NM                             VARCHAR2                IN
PROCEDURE SET_INT_PARAM_IN_SESSION
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 SID                            NUMBER                  IN
 SERIAL#                        NUMBER                  IN
 PARNAM                         VARCHAR2                IN
 INTVAL                         BINARY_INTEGER          IN
PROCEDURE SET_SQL_TRACE_IN_SESSION
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 SID                            NUMBER                  IN
 SERIAL#                        NUMBER                  IN
 SQL_TRACE                      BOOLEAN                 IN
PROCEDURE WAIT_FOR_EVENT
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 EVENT                          VARCHAR2                IN
 EXTENDED_ID                    BINARY_INTEGER          IN
 TIMEOUT                        BINARY_INTEGER          IN


5.於是,順理成章的我們加上使用者資訊(DBMS_SYSTEM是在SYS使用者中定義的)後再嘗試一次
sec@ora10g> exec sys.dbms_system.set_sql_trace_in_session(532,2204,true);
BEGIN sys.dbms_system.set_sql_trace_in_session(532,2204,true); END;

      *
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00201: identifier 'SYS.DBMS_SYSTEM' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

6.還是不能執行,這是為什麼呢?思前想後,難道是許可權的問題?
sec@ora10g> select * from session_roles;

ROLE
------------------------------
PLUSTRACE
DBA
SELECT_CATALOG_ROLE
HS_ADMIN_ROLE
EXECUTE_CATALOG_ROLE
DELETE_CATALOG_ROLE
EXP_FULL_DATABASE
IMP_FULL_DATABASE
GATHER_SYSTEM_STATISTICS
SCHEDULER_ADMIN
WM_ADMIN_ROLE

11 rows selected.

上面可以看到,我的這個sec使用者是一個包含DBA角色在內的超級許可權使用者。

7.這裡就不得不提一個需要重點注意的問題,也是導致上面問題的原因:即使使用者具有了DBA角色也同樣需要單獨去對特定包授權“物件許可權”。到此,問題原因已經浮出水面
我們單獨對sec使用者授予執行dbms_system的許可權
sys@ora10g> grant execute on dbms_system to sec;

Grant succeeded.

8.最後,我們再嘗試一次,可見:喜訊已到
sec@ora10g> exec sys.dbms_system.set_sql_trace_in_session(532,2204,true);

PL/SQL procedure successfully completed.

sec@ora10g> exec sys.dbms_system.set_sql_trace_in_session(532,2204,false);

PL/SQL procedure successfully completed.

9.如果想徹底的放開對sys.dbms_system包的訪問許可權,可以直接將它的執行許可權授權給PUBLIC
方法:
sys@ora10g> grant execute on dbms_system to public;

Grant succeeded.

10.小結
透過這個案例,我們應該充分的認識到Oracle的許可權控制的複雜性,不能想當然的認為一個使用者具有了DBA的許可權就可以為所欲為,Oracle的許可權控制策略還是很嚴格的,尤其是針對具體的“物件許可權”。在很多種場景下,都需要單獨的“顯示的”授予物件許可權。

-- The End --

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/519536/viewspace-616481/,如需轉載,請註明出處,否則將追究法律責任。

相關文章