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