获取业务用户列表

在接触一个新的系统,或对一个陌生的环境进行迁移备份时,需要了解这个数据库中业务用户是哪些,系统用户有哪些,以区别对待,但有时这个工作并不太容易。
最简单的办法莫过于直接询问对数据库了解的DBA或开发人员,但是有时如果数据库中用户众多,那么没有人可以确定所有的用户范围。同样的道理,通过检查程序也有可能遗漏。何况在有些情况下,并没有人对数据库用户十分了解,也就根本无从问起。
既然所有的用户都存储在数据库中,那么利用数据库本身的方法应该可以区分哪些是业务用户,哪些是系统用户。
如果对于Oracle的用户很熟悉,那么直接通过查询DBA_USERS获取用户名列表,就可以判断的八九不离十:

SQL> SELECT * FROM v$version;
BANNER
----------------------------------------------------------------
Oracle DATABASE 10g Enterprise Edition Release 10.2.0.5.0 - Prod
PL/SQL Release 10.2.0.5.0 - Production
CORE    10.2.0.5.0      Production
TNS FOR 32-bit Windows: Version 10.2.0.5.0 - Production
NLSRTL Version 10.2.0.5.0 – Production
SQL> SELECT username FROM dba_users;
USERNAME
------------------------------
OLAPSYS
SI_INFORMTN_SCHEMA
MGMT_VIEW
ORDPLUGINS
XDB
DIP
OUTLN
ANONYMOUS
CTXSYS
MDDATA
TSMSYS
ORACLE_OCM
WMSYS
DMSYS
EXFSYS
ORDSYS
MDSYS
SYSTEM
SYS
TEST
SYSMAN
U1
USER_A
DBSNMP
TEST2
已选择25行。

不过这种方法容易产生遗漏或误判,尤其是用户众多的时候,而且Oracle各个版本中的系统用户变化很大,在安装系统的时候不同的选件也会导致创建的用户不同,所以这种方法一是只对资深DBA有效,二是准确性不好控制。
其实DBA_USERS视图中还有很多其他信息可以用来辅助判断,比如创建时间和默认表空间:

SQL> ALTER SESSION SET nls_date_format = 'yyyy-mm-dd hh24:mi:ss';
会话已更改。
SQL> SELECT username, created FROM dba_users ORDER BY 2;
USERNAME                       CREATED
------------------------------ -------------------
TEST                           2010-12-24 14:22:44
USER_A                         2010-12-24 15:09:18
SYS                            2010-12-25 15:56:16
SYSTEM                         2010-12-25 15:56:17
OUTLN                          2010-12-25 15:56:18
DIP                            2010-12-25 15:59:19
TSMSYS                         2010-12-25 16:01:33
DBSNMP                         2010-12-25 16:02:23
ORACLE_OCM                     2010-12-25 16:02:26
WMSYS                          2010-12-25 16:02:51
EXFSYS                         2010-12-25 16:06:14
DMSYS                          2010-12-25 16:06:27
CTXSYS                         2010-12-25 16:06:41
ANONYMOUS                      2010-12-25 16:07:02
XDB                            2010-12-25 16:07:02
ORDSYS                         2010-12-25 16:08:00
MDSYS                          2010-12-25 16:08:00
ORDPLUGINS                     2010-12-25 16:08:00
SI_INFORMTN_SCHEMA             2010-12-25 16:08:00
OLAPSYS                        2010-12-25 16:12:20
MDDATA                         2010-12-25 16:13:06
SYSMAN                         2010-12-25 16:15:13
MGMT_VIEW                      2010-12-25 16:16:14
U1                             2011-08-16 15:17:08
TEST2                          2011-09-01 17:47:08
已选择25行。
SQL> SELECT username, default_tablespace FROM dba_users ORDER BY 2;
USERNAME                       DEFAULT_TABLESPACE
------------------------------ ------------------------------
OLAPSYS                        SYSAUX
SI_INFORMTN_SCHEMA             SYSAUX
DBSNMP                         SYSAUX
SYSMAN                         SYSAUX
MDSYS                          SYSAUX
ORDSYS                         SYSAUX
EXFSYS                         SYSAUX
DMSYS                          SYSAUX
WMSYS                          SYSAUX
CTXSYS                         SYSAUX
ANONYMOUS                      SYSAUX
XDB                            SYSAUX
ORDPLUGINS                     SYSAUX
MGMT_VIEW                      SYSTEM
SYS                            SYSTEM
OUTLN                          SYSTEM
SYSTEM                         SYSTEM
TEST2                          USERS
DIP                            USERS
TEST                           USERS
U1                             USERS
MDDATA                         USERS
TSMSYS                         USERS
ORACLE_OCM                     USERS
USER_A                         USERS
已选择25行。

由于大部分系统用户都是在数据库创建时刻创建,因此他们的创建时间比较接近,且与SYS和SYSTEM用户创建时间相去不远,这可以作为一个主要的判断依据。但是有些系统用户可能是在数据库运行一段时间后安装的,或者业务用户在创建数据库后马上创建,甚至是修改系统时间,都会导致仅根据创建时间来判断系统用户容易产生查漏,比如上面的例子中,就是由于系统时间变动,导致业务用户的创建时间甚至早于数据库的创建时间。
默认表空间信息同样可以起到辅助判断的作用,在9i以前,各个组件都会创建独立的表空间,而在10g以后,大部分组件的默认表空间都是SYSAUX,因此可以比较容易的判断大部分系统用户。不过默认表空间是可以修改的,而且虽然不推荐,但是并不能阻止业务用户将默认表空间设置为SYS或SYSAUX,此外,从上面的例子也可以看出,仍然有一部分系统用户的默认表空间不是SYS或SYSAUX,因此这个方法也不能作为唯一的依据。
除了上面几个方法外,在Oracle中,专门记录了每个组件对应的系统用户,可以通过下面的查询获取:

SQL> SELECT CID, CNAME, NAME 
  2  FROM 
  3  (SELECT CID, CNAME, SCHEMA# FROM SYS.REGISTRY$
  4  UNION ALL
  5  SELECT A.CID, CNAME, B.SCHEMA# FROM SYS.REGISTRY$ A, SYS.REGISTRY$SCHEMAS B
  6  WHERE A.CID = B.CID) A, 
  7  SYS.USER$ B
  8  WHERE A.SCHEMA# = B.USER#;
CID        CNAME                                         NAME
---------- --------------------------------------------- --------------------
XOQ        Oracle OLAP API                               SYS
APS        OLAP Analytic Workspace                       SYS
CATJAVA    Oracle DATABASE Java Packages                 SYS
XML        Oracle XDK                                    SYS
JAVAVM     JServer JAVA Virtual Machine                  SYS
CATPROC    Oracle DATABASE Packages AND Types            SYS
CATALOG    Oracle DATABASE Catalog Views                 SYS
CATPROC    Oracle DATABASE Packages AND Types            SYSTEM
CATPROC    Oracle DATABASE Packages AND Types            OUTLN
ODM        Oracle DATA Mining                            DMSYS
CATPROC    Oracle DATABASE Packages AND Types            DBSNMP
OWM        Oracle Workspace Manager                      WMSYS
RUL        Oracle Rules Manager                          EXFSYS
EXF        Oracle Expression FILTER                      EXFSYS
CONTEXT    Oracle Text                                   CTXSYS
XDB        Oracle XML DATABASE                           XDB
EM         Oracle Enterprise Manager                     SYSMAN
AMD        OLAP Catalog                                  OLAPSYS
ORDIM      Oracle interMedia                             ORDSYS
ORDIM      Oracle interMedia                             ORDPLUGINS
ORDIM      Oracle interMedia                             SI_INFORMTN_SCHEMA
SDO        Spatial                                       MDSYS
已选择22行。

虽然这种方法也没有包括所有的系统用户,但是这个信息无疑是最准确的,在配合用户名,系统表空间和创建时间,就可以比较轻易的判断所有非系统用户了:

SQL> SELECT USERNAME, CREATED, DEFAULT_TABLESPACE
  2  FROM DBA_USERS
  3  WHERE USERNAME NOT IN 
  4  (SELECT NAME 
  5  FROM 
  6  (SELECT SCHEMA# 
  7  FROM SYS.REGISTRY$
  8  UNION ALL
  9  SELECT B.SCHEMA# 
 10  FROM SYS.REGISTRY$ A, SYS.REGISTRY$SCHEMAS B
 11  WHERE A.CID = B.CID) A, 
 12  SYS.USER$ B
 13  WHERE A.SCHEMA# = B.USER#)
 14  ORDER BY 3, 2;
USERNAME                       CREATED             DEFAULT_TABLESPACE
------------------------------ ------------------- -----------------------
ANONYMOUS                      2010-12-25 16:07:02 SYSAUX
MGMT_VIEW                      2010-12-25 16:16:14 SYSTEM
TEST                           2010-12-24 14:22:44 USERS
USER_A                         2010-12-24 15:09:18 USERS
DIP                            2010-12-25 15:59:19 USERS
TSMSYS                         2010-12-25 16:01:33 USERS
ORACLE_OCM                     2010-12-25 16:02:26 USERS
MDDATA                         2010-12-25 16:13:06 USERS
U1                             2011-08-16 15:17:08 USERS
TEST2                          2011-09-01 17:47:08 USERS
已选择10行。

在这个例子中,业务用户只有TEST、USER_A、U1和TEST2。

This entry was posted in ORACLE and tagged , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *