暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

oracle深入解析中的数据字典讲解

原创 time 2022-09-29
861

数据字典
Oracle 通过数据字典来管理和展现数据库信息,数据字典通常存储数据库的元数据,是数
据库的“数据库”,其中存储的信息至关重要。正确理解这部分内容会有助于ᨀ高大家对 Oracle
数据库的认知,加强自学习能力。本章对 Oracle 的数据字典进行探讨。
4.1数据字典概述
数据字典(Data Dictionary)是 Oracle 数据库的一个重要组成部分,是元数据(Metadata)
的存储地点。Oracle RDBMS 使用数据字典记录和管理对象信息和安全信息等,用户和数据库
系统管理员可以通过数据字典来获取数据库相关信息。
数据字典包括以下内容:
u 所有数据库 Schema 对象的定义(表、视图、索引、聚簇、同义词、序列、过程、
函数、包、触发器等等)
u 数据库的空间分配和使用情况
u 字段的缺省值
u 完整性约束信息
u Oracle 用户名称、角色、权限等信息
u 审计信息
u 其他数据库信息
总之,数据字典是数据库核心,通过数据字典,Oracle 数据库基本上可以实现自解释。
一般来说,数据字典是只读的,通常不建议对任何数据字典表中的任何信息进行手工更
新或改动,对于数据字典的修改很容易就会导致数据库紊乱,造成无法恢复的后果,而
且 Oracle 公司不对此类操作带来的后果负责。
通常所说的数据字典由四部分组成:内部 RDBMS(X $)表、数据字典表、动态性能(V$)
视图和数据字典视图。作为数据字典的辅助管理,还可以为对象创建同义词。
4.2内部 RDBMS(X$)表
X$表是 Oracle 数据库的核心部分,这些表用于跟踪内部数据库信息,维持数据库的正常
运行。X$表是加密命名的,而且 Oracle 不作文档说明,这部分知识是 Oracle 公司的技术机密,
Oracle 通过这些 X$建立起其他大量视图ᨀ供用户查询管理数据库之用。但是由于 X$表记录了
大量有用的信息,所以也不停的被全球 DBA 不懈的探索着,最为人所熟知的有:X$BH,
X$KSMSP 等。
书名书名书名书名书名书名书名书名书名书名书名书名书名书名
·2·
X$表的本质上是一系列的 C 结构体,是 Oracle 数据库的运行基础,在数据库启动时由
Oracle 应用程序动态创建。这部分表对数据库来说至关重要,所以 Oracle 不允许 SYSDBA 之
外的用户直接访问,显示授权不被允许。
如果显式授权会收到如下错误:
SQL> grant select on x$ksppi to eygle;
grant select on x$ksppi to eygle
*
ERROR at line 1:
ORA-02030: can only select from fixed tables/views
Oracle 的解释是:
ORA-02030 can only select from fixed tables/views
Cause: An attempt is being made to perform an operation other than a retrieval from a fixed
table/view.
Action: You may only select rows from fixed tables/views.
一句话,这些对象你最好只是查询。
发现、观察、研究 X$表的一个好办法是借用 Oracle 的 AUTOTRACE 功能,当我们查询
一些常用视图的时候,我们可以通过 AUTOTRACE 功能发现这些 View 的底层表。
以下是 Oracle10gR2 中的一个示例:
SQL> set autotrace trace explain
SQL> select * from v$parameter;
Execution Plan
----------------------------------------------------------
Plan hash value: 1128103955
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 926 | 1 (100)| 00:00:01 |
|* 1 | HASH JOIN | | 1 | 926 | 1 (100)| 00:00:01 |
|* 2 | FIXED TABLE FULL| X$KSPPI | 1 | 249 | 0 (0)| 00:00:01 |
| 3 | FIXED TABLE FULL| X$KSPPCV | 100 | 67700 | 0 (0)| 00:00:01 |
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("X"."INDX"="Y"."INDX")
filter(TRANSLATE("KSPPINM",'_','#') NOT LIKE '#%' OR
"KSPPSTDF"='FALSE' OR BITAND("KSPPSTVF",5)>0)
2 - filter("X"."INST_ID"=USERENV('INSTANCE') AND
TRANSLATE("KSPPINM",'_','#') NOT LIKE '##%')
这些研究和探索是极有趣味的,如果你能就此深入下去,一定能够时常发现意外的收获。
第 1 章 章名章名章名章名章名
·3·
顺便介绍一个有意思的 X$表,也许你曾经关注过:X$KVIT 。
其名称含义为:
X$KVIT-[K]ernel Layer Performance Layer [V] [I]nformation tables
[T]ransitory Instance parameters
这个视图记录的是和实例相关的一些内部参数设置,你可以看到一些很有意思的内容:
SQL> select * from v$version where rownum <2;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
SQL> select kvittag,kvitval,kvitdsc from x$kvit;
KVITTAG KVITVAL KVITDSC
---------------- ---------- -------------------------------------------------------
ksbcpu 4 number of logical CPUs in the system used by Oracle
ksbcpucore 0 number of physical CPU cores in the system used by Oracle
ksbcpusocket 2 number of physical CPU sockets in the system used by Oracle
ksbcpu_hwm 4 high water mark of number of CPUs used by Oracle
ksbcpucore_hwm 0 high water mark of number of CPU cores on system
ksbcpusocket_hwm 2 high water mark of number of CPU sockets on system
ksbcpu_actual 4 number of available CPUs in the system
ksbcpu_dr 1 CPU dynamic reconfiguration supported
kcbnbh 238518 number of buffers
kcbldq 25 large dirty queue if kcbclw reaches this
kcbfsp 40 Max percentage of LRU list foreground can scan for free
kcbcln 2 Initial percentage of LRU list to keep clean
kcbnbf 750 number buffer objects
kcbwst 0 Flag that indicates recovery or db suspension
kcteln 0 Error Log Number for thread open
kcvgcw 0 SGA: opcode for checkpoint cross-instance call
kcvgcw 0 SGA:opcode for pq checkpoint cross-instance call
17 rows selected
不知道大家是否还记得,触发后台进程 DBWR 写动作的条件包含这样两个:
1.脏缓冲(Dirty Buffers)阈值(threshold)达到
-那么这个 threshold 是多少呢?从以上视图中可以知道,这个值是 25%,即:
kcbldq 25 large dirty queue if kcbclw reaches this
这个限制同时受到一个隐含参数的控制(来自 Oracle9iR2 数据库):
SQL> @GetHidPar
Enter value for par: db_writer_scan_depth_pct
书名书名书名书名书名书名书名书名书名书名书名书名书名书名
·4·
old 6: AND x.ksppinm LIKE '%&par%'
new 6: AND x.ksppinm LIKE '%db_writer_scan_depth_pct%'
NAME VALUE DESCRIB
------------------------- ----- --------------------------------------------------------
_db_writer_scan_depth_pct 25 Percentage of LRU buffers for dbwr to scan when looking for
dirt
2.No Free Buffer-也就是当进程扫᧿ LRU 一定数量的 Block 之后,如果还找不到足够的
free 空间,则触发 DBWR 执行写出。
-那么这个扫᧿数量是多少呢?从以上视图中,我们可以知道,这个比例为 40%,即:
kcbfsp 40 Max percentage of LRU list foreground can scan for free
这个限制也受到另外一个隐含参数的限制,这个参数是_db_block_max_scan_pct:
SQL> @GetParDescrb.sql
Enter value for par: db_block_max_scan
old 6: AND x.ksppinm LIKE '%&par%'
new 6: AND x.ksppinm LIKE '%db_block_max_scan%'
NAME VALUE DESCRIB
---------------------- ------ ------------------------------------------------------
_db_block_max_scan_pct 40 Percentage of buffers to inspect when looking for free
通过这些内容,我们可以把很多数据库抽象的概念具体化,有兴趣的,大家可以继续探
索。我们将在第五章对这些内容作一点进一步的说明。
4.3数据字典表
数据字典表(Data dictionary table)用以存储表、索引、约束以及其他数据库结构的信息。
这些对象通常以“$”结尾(例如 TAB$、OBJ$、TS$等),在创建数据库的时候通过运行 sql.bsq
脚本来创建。
sql.bsq 是非常重要的一个文件,其中包含了数据字典表的定义及注释说明,每个试图深
入学习 Oracle 数据库的人都应该仔细阅读一下该文件。该文件位于$ORACLE_HOME/
rdbms/admin 目录下.
自 Oracle Database 11g 开始, sql.bsq 中的内容依据功能的不同被拆分为多个脚本, SQL 被
分别归类到不同的 bsq 文件,sql.bsq 文件起到一个入口的作用,在创建数据库时分别顺序调用
其他文件创建数据库,以下是 11g 中 sql.bsq 文件的一点摘录:
rem !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
rem Whenever new column is created to store internal, user or kernel column
rem number, be sure to update the structure adtDT in atb.c so that those
rem columns will be updated properly during drop column.
rem !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
第 1 章 章名章名章名章名章名
·5·
rem
dcore.bsq
dsqlddl.bsq
dmanage.bsq
dplsql.bsq
dtxnspc.bsq
dfmap.bsq
denv.bsq
drac.bsq
dsec.bsq
doptim.bsq
dobj.bsq
djava.bsq
dpart.bsq
drep.bsq
daw.bsq
dsummgt.bsq
dtools.bsq
dexttab.bsq
ddm.bsq
dlmnr.bsq
ddst.bsq
拆分方便了管理和维护,也方便了我们的研究和学习,下面通过一些 BSQ 对象引用了解一
下其内容.
以下是我们曾经ᨀ到过的 bootstrap$表的定义:
create table bootstrap$
( line# number not null, /* statement order id */
obj# number not null, /* object number */
sql_text varchar2("M_VCSZ") not null) /* statement */
storage (initial 50K) /* to avoid space management during IOR I */
// /* "//" required for bootstrap */
OBJ$字典表的部分结构:
create table obj$ /* object table */
( obj# number not null, /* object number */
/* DO NOT CREATE INDEX ON DATAOBJ# AS IT WILL BE UPDATED IN A SPACE
* TRANSACTION DURING TRUNCATE */
dataobj# number, /* data layer object number */
owner# number not null, /* owner user number */
书名书名书名书名书名书名书名书名书名书名书名书名书名书名
·6·
name varchar2("M_IDEN") not null, /* object name */
namespace number not null, /* namespace of object (see KQD.H): */
/* 1 = TABLE/PROCEDURE/TYPE, 2 = BODY, 3 = TRIGGER, 4 = INDEX, 5 = CLUSTER, */
/* 8 = LOB, 9 = DIRECTORY, */
/* 10 = QUEUE, 11 = REPLICATION OBJECT GROUP, 12 = REPLICATION PROPAGATOR, */
/* 13 = JAVA SOURCE, 14 = JAVA RESOURCE */
/* 58 = (Data Mining) MODEL */
subname varchar2("M_IDEN"), /* subordinate to the name */
type# number not null, /* object type (see KQD.H): */
/* 1 = INDEX, 2 = TABLE, 3 = CLUSTER, 4 = VIEW, 5 = SYNONYM, 6 = SEQUENCE, */
/* 7 = PROCEDURE, 8 = FUNCTION, 9 = PACKAGE, 10 = NON-EXISTENT, */
/* 11 = PACKAGE BODY, 12 = TRIGGER, 13 = TYPE, 14 = TYPE BODY, */
/* 19 = TABLE PARTITION, 20 = INDEX PARTITION, 21 = LOB, 22 = LIBRARY, */
/* 23 = DIRECTORY , 24 = QUEUE, */
/* 25 = IOT, 26 = REPLICATION OBJECT GROUP, 27 = REPLICATION PROPAGATOR, */
/* 28 = JAVA SOURCE, 29 = JAVA CLASS, 30 = JAVA RESOURCE, 31 = JAVA JAR, */
/* 32 = INDEXTYPE, 33 = OPERATOR , 34 = TABLE SUBPARTITION, */
/* 35 = INDEX SUBPARTITION */
/* 82 = (Data Mining) MODEL */
。。。。。。。
)
storage (initial 10k next 100k maxextents unlimited pctincrease 0)
/
注意通常大家习惯查询的 DBA_OBJECTS 字典视图就是基于 OBJ$ 数据字典表创建的,
DBA_OBJECTS 中有两个字段经常使人误解:OBJECT_ID 和 DATA_OBJECT_ID。这两个字
段分别来自 OBJ$中的 OBJ#和 DATAOBJ#,其中 OBJ#(也即 OBJECT_ID)可以被看作是对
象的逻辑号(类似序列号一样分配),该序号一旦分配之后就不会发生改变;而 DATAOBJ#
(也即 DATA_OBJECT_ID)则是和物理存储关联的编号,通常被认为是对象的物理号,这个
编号会随着对象物理存储结构的改变而发生改变。注意下面的注释中已经清晰的指出了这一
点,Oracle ᨀ示“不要在 DATAOBJ#上创建索引,因为在空间事务如 TRUNCATE 中,
DATAOBJ#会发生改变:
obj# number not null, /* object number */
/* DO NOT CREATE INDEX ON DATAOBJ# AS IT WILL BE UPDATED IN A SPACE
* TRANSACTION DURING TRUNCATE */
dataobj# number, /* data layer object number */
通过如下测试就可以发现 TRUNCATE 的这一特点:
SQL> create table test as select * from dba_users;
Table created.
SQL> select object_id,data_object_id from dba_objects
第 1 章 章名章名章名章名章名
·7·
2 where owner='EYGLE' and object_name='TEST';
OBJECT_ID DATA_OBJECT_ID
---------- --------------
15036 15036
SQL> truncate table test;
Table truncated.
SQL> select object_id,data_object_id from dba_objects
2 where owner='EYGLE' and object_name='TEST';
OBJECT_ID DATA_OBJECT_ID
---------- --------------
15036 15037
实际上这也暗示了 TRUNCATE 作为 DDL 可以快速回收空间的本质,在执行 TRUNCATE
操作时,数据库只是简单的回收空间,将空间标记为可用(并不会去数据块上真正去删除数据),
同时将对象的数据对象重新定位,完成空间回收。那么实际上,虽然 Oracle 并未ᨀ供直接的
办法,在原对象存储位置被重新写入数据之前,TRUNCATE 数据仍然是有办法恢复的(就如
同在 Windows 上误删除的文件,在覆盖之前,是可以通过软件进行恢复的)。
不再过多引用,只要打开这些文件,可能你会发现,很多困扰许久的问题,在这里可以轻
易的找到注解及答案。
由于数据字典表对于数据库的稳定运行生死攸关,所以通常 Oracle 不允许直接对数据字
典进行操作,当用户执行 DDL 操作或者某些 DML 操作时,在后台 Oracle 将这些操作解析为
对于数据字典的操作自动执行。
例如当用户创建一张数据表时,Oracle 将会在后台执行一系列的内部操作,比如向 obj$表
中插入数据、向 tab$表中记录表数据、向 col$表中记录字段信息、向 con$记录约束信息、向
seg$中记录数据段信息等,以下测试来自 Oracle Database 11g,通过跟踪我们可以获得这些内
部操作的具体步骤:
SQL> select * from v$version where rownum <2;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production
SQL> alter session set events '10046 trace name context forever,level 12';
Session altered.
SQL> create table eygle as select * from dba_users;
Table created.
SQL> SELECT VALUE FROM V$DIAG_INFO WHERE NAME = 'Default Trace File';
VALUE
--------------------------------------------------------------------------------
/opt/oracle/diag/rdbms/phsdb/phsdb/trace/phsdb_ora_2854.trc
注意,以上查询跟踪文件的视图 V$DIAG_INFO 是 11g 中引入的,其他版本中并不存在。
摘录一点跟踪文件中的数据,从中可以清晰的看到前台的一个 DDL 语句在后台是怎样被
书名书名书名书名书名书名书名书名书名书名书名书名书名书名
·8·
转化一系列的 DML 语句进行执行的,首先记录的是创建语句:
…………………
sqlid='dghqcjggp7t96'
create table eygle as select * from dba_users
END OF STMT
后台的分解操作,向 obj$中增加记录的 DML 语句:
sqlid='4bjwv5sp99589'
insert into
obj$(owner#,name,namespace,obj#,type#,ctime,mtime,stime,status,remoteowner,linkname,subna
me,dataobj#,flags,oid$,spare1,spare2,spare3)
values(:1,:2,:3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13,:14,:15,:16,:17,:18)
END OF STMT
更新 con$表数据:
sqlid='bajr90ryjd2w8'
update con$ set con#=:3,spare1=:4 where owner#=:1 and name=:2
增加段信息,向 seg$表插入数据的语句:
sqlid='g7mt7ptq286u7'
insert into seg$
(file#,block#,type#,ts#,blocks,extents,minexts,maxexts,extsize,extpct,user#,iniexts,lists
,groups,cachehint,hwmincr, spare1, scanhint, bitmapranges) values
(:1,:2,:3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13,:14,:15,:16,DECODE(:17,0,NULL,:17),:18,:19)
向 tab$表增加表记录信息:
insert into
tab$(obj#,ts#,file#,block#,bobj#,tab#,intcols,kernelcols,clucols,audit$,flags,pctfree$,pc
tused$,initrans,maxtrans,rowcnt,blkcnt,empcnt,avgspc,chncnt,avgrln,analyzetime,samplesize
,cols,property,degree,instances,dataobj#,avgspc_flb,flbcnt,trigflag,spare1,spare6)values(
:1,:2,:3,:4,decode(:5,0,null,:5),decode(:6,0,null,:6),:7,:8,decode(:9,0,null,:9),:10,:11,
:12,:13,:14,:15,:16,:17,:18,:19,:20,:21,:22,:23,:24,:25,decode(:26,1,null,:26),decode(:27
,1,null,:27),:28,:29,:30,:31,:32,:33)
向 col$表增加字段信息:
sqlid='60uw2vh6q9vn2'
insert into
col$(obj#,name,intcol#,segcol#,type#,length,precision#,scale,null$,offset,fixedstorage,se
gcollength,deflength,default$,col#,property,charsetid,charsetform,spare1,spare2,spare3)va
lues(:1,:2,:3,:4,:5,:6,decode(:5,182/*DTYIYM*/,:7,183/*DTYIDS*/,:7,decode(:7,0,null,:7)),
decode(:5,2,decode(:8,-127/*MAXSB1MINAL*/,null,:8),178,:8,179,:8,180,:8,181,:8,182,:8,183
,:8,231,:8,null),:9,0,:10,:11,decode(:12,0,null,:12),:13,:14,:15,:16,:17,:18,:19,:20)
END OF STMT
Oracle 通过将 DDL 解析为 DML 操作,并且将这些操作记录在数据字典表中,通过将这
第 1 章 章名章名章名章名章名
·9·
些信息反向解析,可以得到原始的创建语句,从 Oracle 9i 开始,一个工具包
DBMS_METADATA 被引入到数据库中来完成这项工作:
SQL> set pagesize 99
SQL> set long 12000
SQL> select dbms_metadata.get_ddl('TABLE','EYGLE') from dual;
DBMS_METADATA.GET_DDL('TABLE','EYGLE')
--------------------------------------------------------------------------------
CREATE TABLE "SYS"."EYGLE"
( "USERNAME" VARCHAR2(30) NOT NULL ENABLE,
"USER_ID" NUMBER NOT NULL ENABLE,
"PASSWORD" VARCHAR2(30),
"ACCOUNT_STATUS" VARCHAR2(32) NOT NULL ENABLE,
"LOCK_DATE" DATE,
"EXPIRY_DATE" DATE,
"DEFAULT_TABLESPACE" VARCHAR2(30) NOT NULL ENABLE,
"TEMPORARY_TABLESPACE" VARCHAR2(30) NOT NULL ENABLE,
"CREATED" DATE NOT NULL ENABLE,
"PROFILE" VARCHAR2(30) NOT NULL ENABLE,
"INITIAL_RSRC_CONSUMER_GROUP" VARCHAR2(30),
"EXTERNAL_NAME" VARCHAR2(4000),
"PASSWORD_VERSIONS" VARCHAR2(8),
"EDITIONS_ENABLED" VARCHAR2(1)
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "SYSTEM"
4.4静态数据字典视图
由于 X$表和数据字典表通常不能直接访问,Oracle 创建了静态数据字典视图来ᨀ供用户
对于数据字典信息的访问,由于这些信息通常相对稳定、不能直接修改,所以又被称为静态数
据字典视图。数据字典视图在创建数据库时由 catalog.sql 脚本(该脚本位于
$ORACLE_HOME/rdbms/admin/目录下)创建。
4.4.1 静态数据字典视图的分类
静态数据字典视图按照前缀的不同通常被分为三类:
1.USER_ 类视图包含了用户所拥有的相关对象信息,用户可以通过这个视图查询自己
书名书名书名书名书名书名书名书名书名书名书名书名书名书名
·10·
拥有的对象信息。
2.ALL_ 类视图包含了用户有权限访问的所有对象的信息。
3.DBA_ 类视图包含了数据库所有相关对象的信息,用户需要 SELECT ANY TABLE 权
限才能访问。
这三者的关系大致可以用如下示意图᧿述:
通过三类视图在本质上是为了实现权限的控制。在 Oracle 数据库中,每个用户与方案
(Schema)是对应的,Schema 是用户所拥有的对象的集合。数据库通过 Schema 将不同用户的
对象隔离开来,用户可以自由访问自己 Schema 的对象,但是对于其他 Schema 对象的访问则
需要获得授权。
以下通过常用的字典视图做一个简单的示范说明。
USER_TABLES 视图是 USER 类视图的一个典型代表。这个视图中记录了当前用户所拥
有的所有表的信息:
SQL> connect eygle/eygle
Connected.
SQL> select table_name,tablespace_name from user_tables;
TABLE_NAME TABLESPACE_NAME
------------------------------ ------------------------------
CUSTOM USERS
而对于 ALL_TABLES 视图,不仅包含用户所拥有的表,还包括用户有权限能够访问的表,
这些表可能来自其他用户的授权:
SQL> connect gqgai/eygle
Connected.
第 1 章 章名章名章名章名章名
·11·
SQL> grant select on sales to eygle;
Grant succeeded.
获得授权之后,用户就能够通过 ALL_TABLES 视图获得这些表的信息:
SQL> select table_name,owner from all_tables where owner in ('EYGLE','GQGAI');
TABLE_NAME OWNER
------------------------------ ------------------------------
CUSTOM EYGLE
SALES GQGAI
而 DBA_TABLES 则是一个超级集合,包含了数据库所有的表对象,查询这个视图需要
DBA 的权限或者 SELECT ANY TABLE 的系统权限。通过以下查询可以简要统计不同用户拥
有的表对象数量:
SQL> select owner,count(*) from dba_tables group by owner order by 2;
OWNER COUNT(*)
------------------------------ ----------
EYGLE 1
GQGAI 1
……………………
SYSTEM 150
SYS 837
23 rows selected.
4.4.2 静态数据字典视图的内部实现
既然以上ᨀ到的这三类字典都是视图(VIEW),那这些视图是怎样建立起来的?又是如
何实现的权限控制呢?我们一起来探索一下 Oracle 的实现。
通常 USER_类视图不包含 Owner 字段,查询潜在的返回当前用户的对象信息,我们以
USER_TABLES 视图为例(篇幅原因,省略了部分内容)看一下其创建及结构:
create or replace view USER_TABLES
(TABLE_NAME, TABLESPACE_NAME, CLUSTER_NAME, IOT_NAME,
PCT_FREE, PCT_USED,
…….
DEGREE, INSTANCES, CACHE, TABLE_LOCK,
SAMPLE_SIZE, LAST_ANALYZED, PARTITIONED,
IOT_TYPE, TEMPORARY, SECONDARY, NESTED,
BUFFER_POOL, ROW_MOVEMENT,
GLOBAL_STATS, USER_STATS, DURATION, SKIP_CORRUPT, MONITORING,
CLUSTER_OWNER, DEPENDENCIES, COMPRESSION)
as
select o.name, decode(bitand(t.property, 4194400), 0, ts.name, null),
书名书名书名书名书名书名书名书名书名书名书名书名书名书名
·12·
decode(bitand(t.property, 1024), 0, null, co.name),
……
from sys.ts$ ts, sys.seg$ s, sys.obj$ co, sys.tab$ t, sys.obj$ o,
sys.obj$ cx, sys.user$ cu
where o.owner# = userenv('SCHEMAID')
and o.obj# = t.obj#
…..
and t.dataobj# = cx.obj# (+)
and cx.owner# = cu.user# (+)
/
我们注意到 Where 条件中有这样一个限制:
where o.owner# = userenv('SCHEMAID')
这就限制了当前查询只返回当前用户的 SCHEMA 对象信息。
而对于 ALL_TABLES 视图,在 Where 子句中,关于用户部分,增加了这样一个条件:
and (o.owner# = userenv('SCHEMAID')
or o.obj# in
(select oa.obj#
from sys.objauth$ oa
where grantee# in ( select kzsrorol
from x$kzsro
)
)
or /* user has system privileges */
exists (select null from v$enabledprivs
where priv_number in (-45 /* LOCK ANY TABLE */,
-47 /* SELECT ANY TABLE */,
-48 /* INSERT ANY TABLE */,
-49 /* UPDATE ANY TABLE */,
-50 /* DELETE ANY TABLE */)
)
)
这个条件扩展了关于用户有权限访问的对象信息,所以实际上 USER_TABLES 的结果是
ALL_TABLES 结果的一个子集。
DBA_TABLES 视图的 Where 条件中,则没有关于 Owner 的限制,所以查询返回了数据
库中所有表的信息:
where o.owner# = u.user#
and o.obj# = t.obj#
and bitand(t.property, 1) = 0
and t.bobj# = co.obj# (+)
第 1 章 章名章名章名章名章名
·13·
and t.ts# = ts.ts#
and t.file# = s.file# (+)
and t.block# = s.block# (+)
and t.ts# = s.ts# (+)
and t.dataobj# = cx.obj# (+)
and cx.owner# = cu.user# (+)
/
这就是这几类数据字典视图的区别所在,也就是 Oracle 实现权限隔离的方式

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论