在接触一个新的系统,或对一个陌生的环境进行迁移备份时,需要了解这个数据库中业务用户是哪些,系统用户有哪些,以区别对待,但有时这个工作并不太容易。
最简单的办法莫过于直接询问对数据库了解的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。