热衷技术,热爱交流
分类: Oracle
2013-05-23 22:35:15
在外模式范畴,数据库字典仅仅指用户建立的一些对象,以及他们的对象信息,这些东西一般和业务相关,程序可以随时用DML改变。但是模式和内模式范畴中的数据字典,则是整个数据库的核心内容,它们往往是只读的,本文也仅讨论它们。
存储了数据库元数据的一些表就是数据字典(在这些表基础上可以建立视图,同义词等对象),这些元数据一个特点就是定义,它可能并不存放对象(比如表)实际的数据,但是它却控制了模式对象的一些重要特征,例如ddl信息。
例如:查看表的DDL信息
HUANGXING >variable huangxing varchar2(4000);
HUANGXING >execute :huangxing:=dbms_metadata.get_ddl('TABLE','STUDENT');
PL/SQL procedure successfully completed.
HUANGXING >print huangxing;
HUANGXING
----------------------------------------------------------------------------------------------------------------------
CREATE TABLE "HUANGXING"."STUDENT"
( "SNO" NUMBER(5,0) NOT NULL ENABLE,
"SNAME" VARCHAR2(10),
"SAGE" NUMBER(5,0),
"SSEX" VARCHAR2(5),
"SDEPT" VARCHAR2(10),
CONSTRAINT "OK" PRIMARY KEY ("SNO")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "HUANGXING" ENABLE
) SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 8192 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "HUANGXING"
数据字典的内容大致包含:
l 模式对象(tables, views, indexes, clusters, synonyms, sequences, procedures, functions, packages, triggers等)的定义信息。
l 模式对象的空间使用及分配信息(例如,表空间,数据文件等)。
l 完整性约束信息(参照完整性,实体完整性,用户定义完整性)。
l 用户及权限等信息。
l 审计信息(数据库审计)。
l 数据库其他信息。
在讨论数据字典的时候,由于视图本身是由表生成的,所以我们把视图一并看作是数据字典。
数据字典包含下面四种类别的表或者视图:
1. 内部表
2. 数据字典表
3. 数据字典视图
4. 动态性能视图
内部表适用于跟踪数据库内部信息,维护数据库正常运行。内部表在启动时候建立在内存中,往往用来记录一些动态信息,许多动态性能是图就来源于它.由于内部表的重要性,oracle未提供相关文档,只能留给dba们去探索。
内部表仅仅sysdba用户才能看,无法对内部表进行授权。
SYS >grant select on x$kcccp to huangxing;
grant select on x$kcccp to huangxing
ERROR at line 1:
ORA-02030: can only select from fixed tables/views
由于内部表存在与内存中,无法通过段空间视图查看:
SYS >select * from dba_segments where segment_name='X$KCCCP';
通过内部表查看一些重要信息:
查看增量检查点相关信息:
SYS >SELECT CPLRBA_SEQ,CPLRBA_BNO,CPLRBA_BOF,CPODR_SEQ,CPODR_BNO,CPODR_BOF,CPODS,CPDRT,CPHBT FROM x$kcccp;
CPLRBA_SEQ|CPLRBA_BNO|CPLRBA_BOF| CPODR_SEQ| CPODR_BNO| CPODR_BOF|CPODS | CPDRT| CPHBT
----------|----------|----------|----------|----------|----------|----------------|----------|----------
177| 17741| 0| 177| 18220| 0|6048511 | 50| 816223981
查看系统运行一些整体信息:
SYS >col KVITTAG for a20
SYS >col KVITDSC for a80
SYS >select KVITVAL,KVITTAG,KVITDSC from x$kvit;
KVITVAL|KVITTAG |KVITDSC
----------|--------------------|------------------------------------------------------------
2|ksbcpu |number of logical CPUs in the system used by Oracle
2|ksbcpucore |number of physical CPU cores in the system used by Oracle
1|ksbcpusocket |number of physical CPU sockets in the system used by Oracle
2|ksbcpu_hwm |high water mark of number of CPUs used by Oracle
2|ksbcpucore_hwm |high water mark of number of CPU cores on system
1|ksbcpusocket_hwm |high water mark of number of CPU sockets on system
2|ksbcpu_actual |number of available CPUs in the system
1|ksbcpu_dr |CPU dynamic reconfiguration supported
7003|kcbnbh |number of buffers
25|kcbldq |large dirty queue if kcbclw reaches this
40|kcbfsp |Max percentage of LRU list foreground can scan for free
2|kcbcln |Initial percentage of LRU list to keep clean
2400|kcbnbf |number buffer objects
0|kcbwst |Flag that indicates recovery or db suspension
0|kcteln |Error Log Number for thread open
0|kcvgcw |SGA: opcode for checkpoint cross-instance call
0|kcvgcw |SGA:opcode for pq checkpoint cross-instance call
数据库字典表以‘$’结尾,通常用于存放模式对象(例如表,索引,存储过程,完整性约束,等)的一些结构信息。
数据字典表在数据库创建时候(create database隐含触发)由文件sql.bsp包含的初始化脚本文件完成。
实际上,一个ddl语句在后台实质是转化为一系列dml语句操作数据字典表:
建表,增加一列,增加完整性约束,插入一行数据。
建表:
create table ok(id number);
alter table ok add name varchar2(10);
alter table ok
add constraint okokok
check (id between 1 and 19);
insert into ok values(10,'100');
alter table ok drop constraint okokok;
drop table ok;
观察后台对数据字典表的操作情况(摘录):
对象信息:
insert into obj$(owner#,name,namespace,obj#,type#,ctime,mtime,stime,status,
remoteowner,linkname,subname,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)
段信息:
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)
记录信息:
insert into tab$(obj#,ts#,file#,block#,bobj#,tab#,intcols,kernelcols,clucols,
audit$,flags,pctfree$,pctused$,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)
列信息:
insert into col$(obj#,name,intcol#,segcol#,type#,length,precision#,scale,
null$,offset,fixedstorage,segcollength,deflength,default$,col#,property,
charsetid,charsetform,spare1,spare2,spare3)
values
(: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)
约束信息:
insert into con$(owner#,name,con#,spare1)
values
(:1,:2,:3,:4)
obj$记录了几乎所有数据库对象(包括表,索引,视图,同义词,存储过程等),
SYS >SELECT OBJ#,DATAOBJ#,OWNER#,NAME,NAMESPACE,TYPE# from obj$ where name='TEST';
OBJ#| DATAOBJ#| OWNER#|NAME | NAMESPACE| TYPE#
----------|----------|----------|------------------------------|----------|----------
62281| 62281| 32|TEST | 1| 2
OBJ#和DATAOBJ#分别代表表的逻辑编号号和物理存储号(段的编号)
例如,Truncate操作是ddl语句,可以进行空间回收,执行truncate操作,观察对象变化
SYS >truncate table huangxing.test;
SYS >SELECT OBJ#,DATAOBJ#,OWNER#,NAME,NAMESPACE,TYPE# from obj$ where name='TEST';
OBJ#| DATAOBJ#| OWNER#|NAME | NAMESPACE| TYPE#
----------|----------|----------|------------------------------|----------|----------
62281| 62537| 32|TEST | 1| 2
SYS >start tablespace/extents
Enter value for tablespace: HUANGXING
Enter value for segment: TEST
old 3: where tablespace_name='&tablespace' and segment_name='&segment'
new 3: where tablespace_name='HUANGXING' and segment_name='TEST'
SEGMENT_NAME | FILE_ID| EXTENT_ID| BLOCK_ID| BLOCKS|BYTES/1024/1024||'M'
--------------------|----------|----------|----------|----------|-----------------------------------------
TEST | 5| 0| 131112| 8|.0625M
可以看到,truncate实际是把表占用的空间标为可用, 同时在表obj$中进行物理对象的重新定位,这样就完成了空间的回收。
因为内部表和数据字典表一般无不提供直接访问,这就需要一些命名更为容易理解的视图用于访问数据字典表和内部表。
静态数据字典视图是在基表的基础上创建的一系列视图,它以一种更友好的方式展示了基表中的内容。这些视图分为三类,分别以user_、all_和dba_开头,他们之间的包含关系如下图所示:
使用这些视图需要注意一下几点:
1. 据库之后,就需要使用脚本catalog.sql创建数据字典。实际上,这三类表实现了权限划分,在创建的时候就已经指定了用户可以用他们看到什么结果(tdcore.sql脚本创建并指定)。
2. 这几种视图的定义与区别,如下表所示
3. 对某一种视图,这三种前缀并不是总能同时出现,例如:
SYS >desc dba_segments;
Name Null? Type
OWNER VARCHAR2(30)
SEGMENT_NAME VARCHAR2(81)
PARTITION_NAME VARCHAR2(30)
……………………………………
SYS >desc all_segments;
ERROR:
ORA-04043: object all_segments does not exist
4. 需要注意的是,访问dba_xxx视图需要具备select any table或者dba权限
1. 通过dictionary视图和dict同义词来查看系统都包含哪些静态视图:
Dictionary记录了所有的静态数据字典视图:
通过DBMS_METADATA.GET_DDL获取视图dictionary的ddl
SYS >start dict/get_ddl
Enter value for type: VIEW
Enter value for name: DICTIONARY
PL/SQL procedure successfully completed.
CREATE OR REPLACE FORCE VIEW "SYS"."DICTIONARY" ("TABLE_NAME", "COMMENTS") AS
select o.name, c.comment$
from sys.obj$ o, sys.com$ c
where o.obj# = c.obj#(+)
and c.col# is null
and o.owner# = 0
and o.type# = 4
and (o.name like 'USER%'
or o.name like 'ALL%'
or (o.name like 'DBA%'
and exists
(select null
from sys.v$enabledprivs
where priv_number = -47 /* SELECT ANY TABLE */)
)
)
union all
select o.name, c.comment$
from sys.obj$ o, sys.com$ c
where o.obj# = c.obj#(+)
and o.owner# = 0
and o.name in ('AUDIT_ACTIONS', 'COLUMN_PRIVILEGES', 'DICTIONARY',
'DICT_COLUMNS', 'DUAL', 'GLOBAL_NAME', 'INDEX_HISTOGRAM',
'INDEX_STATS', 'RESOURCE_COST', 'ROLE_ROLE_PRIVS', 'ROLE_SYS_PRIVS',
'ROLE_TAB_PRIVS', 'SESSION_PRIVS', 'SESSION_ROLES',
'TABLE_PRIVILEGES','NLS_SESSION_PARAMETERS','NLS_INSTANCE_PARAMETERS',
'NLS_DATABASE_PARAMETERS', 'DATABASE_COMPATIBLE_LEVEL',
'DBMS_ALERT_INFO', 'DBMS_LOCK_ALLOCATED')
and c.col# is null
union all
select so.name, 'Synonym for ' || sy.name
from sys.obj$ ro, sys.syn$ sy, sys.obj$ so
where so.type# = 5
and ro.linkname is null
and so.owner# = 1
and so.obj# = sy.obj#
and so.name <> sy.name
and sy.owner = 'SYS'
and sy.name = ro.name
and ro.owner# = 0
and ro.type# = 4
and (ro.owner# = userenv('SCHEMAID')
or ro.obj# in
(select oa.obj#
from sys.objauth$ oa
where grantee# in (select kzsrorol from x$kzsro))
or 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 */)
))
系统在创建完这个试图后,还需要创建dictionary同义词和dict同义词;可以从表obj$获取相关信息:
TYPE#为4表示视图,为5表示同义词;owner#为0表示sys用户,为1表示public角色
SYS >select OBJ#,DATAOBJ#,TYPE#,NAME,OWNER# from obj$ where name in ('DICT','DICTIONARY');
OBJ#| DATAOBJ#| TYPE#|NAME | OWNER#
----------|----------|----------|------------------------------|----------
3533| | 4|DICTIONARY | 0
3534| | 5|DICTIONARY | 1
3535| | 5|DICT | 1
SYS >select OWNER,OBJECT_NAME,OBJECT_ID,OBJECT_TYPE from dba_objects where OBJECT_NAME in ('DICT','DICTIONARY');
OWNER |OBJECT_NAM| OBJECT_ID|OBJECT_TYP
----------|----------|----------|----------
SYS |DICTIONARY| 3533|VIEW
PUBLIC |DICT | 3535|SYNONYM
PUBLIC |DICTIONARY| 3534|SYNONYM
实际上,从这里可以类推别的一些同义词,例如obj,ind,但是没有table,view。
2. 使用dict_columns看看视图的列(仅仅统计视图)
SYS > select * from (select table_name,count(COLUMN_NAME) sum_columns from dict_columns group by table_name order by sum_columns desc) where rownum<=5;
TABLE_NAME |SUM_COLUMNS
------------------------------|-----------
GV$SESSION | 98
V$SESSION | 97
GV$ACTIVE_SESSION_HISTORY | 97
DBA_HIST_ACTIVE_SESS_HISTORY | 97
V$ACTIVE_SESSION_HISTORY | 96
于是,我们就能看到,视图GV$SESSION拥有最多的列。
3. 使用dba_tab_columns查看拥有列最多的对象(包括表,视图和clusters)
SYS > select * from (select table_name,count(COLUMN_NAME) sum_columns from dba_tab_columns group by table_name order by sum_columns desc) where rownum<=5;;
TABLE_NAME |SUM_COLUMNS
------------------------------|-----------
MGMT$CSA_COLLECTIONS | 101
GV_$SESSION | 98
GV_$ACTIVE_SESSION_HISTORY | 97
DBA_HIST_ACTIVE_SESS_HISTORY | 97
V_$SESSION | 97
查看对象属主:
SYS >select OWNER,OBJECT_NAME,OBJECT_ID,OBJECT_TYPE from dba_objects where OBJECT_NAME in ('DICT','MGMT$CSA_COLLECTIONS');;
OWNER |OBJECT_NAME | OBJECT_ID|OBJECT_TYP
----------|--------------------------------------------------|----------|----------
PUBLIC |MGMT$CSA_COLLECTIONS | 57959|SYNONYM
PUBLIC |DICT | 3535|SYNONYM
SYSMAN |MGMT$CSA_COLLECTIONS | 60613|VIEW
于是,MGMT$CSA_COLLECTIONS是sysman的一个视图,他拥有最多的列
3. 获取拥有索引最多的表(dba_ind_columns):
SYS >select * from (select table_name,count(INDEX_NAME ) sum_index_columns from dba_ind_columns group by table_name order by sum_index_columns desc ) where rownum<=5;;
TABLE_NAME |SUM_INDEX_COLUMNS
------------------------------|-----------------
AW_TRACK$ | 32
MGMT_METRICS | 26
OBJ$ | 25
MGMT_INV_COMPONENT | 16
REPCAT$_FLAVOR_OBJECTS
| 14
4. 使用*_source视图获取一些对象的定义:
前面说到,可以使用包对象dbms_metadata.get_ddl获取表、数据字典视图,存储过程的ddl,但是,对于某些存储对象例如java,触发器,等对象,需要使视图*_source视图获取。
这个视图实际主要和数据字典表source$对应
注意分辨*_source和dbms_metadata.get_ddl的区别,dbms_metadata.get_ddl一般是把内容直接列出来(方便直接粘贴),而*_source视图则是把定义一行行地列出来的。
5. *_ERORS,这系列视图可以用来检验模式存储对象的语法错误:
例如:
HUANGXING > CREATE OR REPLACE PROCEDURE "HUANGXING"."P11"
2 as
3 begin
4 for i in 1 .. 80
5 loop
6 insert into test select * from user_tables;
7 end loop;
8 end;
9 END P11;
10 /
Warning: Procedure created with compilation errors.
HUANGXING >SHOW ERROR;
Errors for PROCEDURE "HUANGXING"."P11":
LINE/COL|ERROR
--------|-----------------------------------------------------------------
9/1 |PLS-00103: Encountered the symbol "END"
HUANGXING >select name,TEXT from user_ERRORs;
NAME
------------------------------
TEXT
------
P11
PLS-00103: Encountered the symbol "END"
HUANGXING >CREATE OR REPLACE PROCEDURE "HUANGXING"."P11"
2 as
3 begin
4 for i in 1 .. 80
5 loop
6 insert into test select * from user_tables;
7 end loop;
8 END P11;
9 /
Procedure created.
Elapsed: 00:00:00.46
HUANGXING >SHOW ERROR;
No errors.
HUANGXING >select name,TEXT from user_ERRORs;
no rows selected
其他有用视图参见《Oracle? Database Reference .pdf》;
动态性能视图是一组反映数据库当前活动信息的虚拟表,所有者为sys,以V$或者GV$开头,是管理员监控和调优数据库的重要工具。
动态性能视图可以看到下列信息:
System and session parameters
Memory usage and allocation
File states (including RMAN backup files)
Progress of jobs and tasks
SQL execution
Statistics and metrics
数据库启动时,需要在内存中建立x$内部表,接着建立GV$和V$视图,通过执行计划就能看到两者区别:
SYS >select * from v$instance;
……………………………………………………………………………………………………
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 100 | 26600 | 0 (0)| 00:00:01 |
| 1 | MERGE JOIN CARTESIAN | | 100 | 26600 | 0 (0)| 00:00:01 |
| 2 | MERGE JOIN CARTESIAN| | 1 | 253 | 0 (0)| 00:00:01 |
|* 3 | FIXED TABLE FULL | X$KSUXSINST | 1 | 206 | 0 (0)| 00:00:01 |
| 4 | BUFFER SORT | | 1 | 47 | 0 (0)| 00:00:01 |
|* 5 | FIXED TABLE FULL | X$KVIT | 1 | 47 | 0 (0)| 00:00:01 |
| 6 | BUFFER SORT | | 100 | 1300 | 0 (0)| 00:00:01 |
| 7 | FIXED TABLE FULL | X$QUIESCE | 100 | 1300 | 0 (0)| 00:00:01 |
------------------------------------------------------------------------------------
3 - filter("KS"."INST_ID"=USERENV('INSTANCE'))
5 - filter("KVITTAG"='kcbwst')
SYS >select * from gv$instance;
…………………………………………………………………………………………………………………………
| 0 | SELECT STATEMENT | | 10000 | 2597K| 7 (100)| 00:00:01 |
| 1 | MERGE JOIN CARTESIAN | | 10000 | 2597K| 7 (100)| 00:00:01 |
| 2 | MERGE JOIN CARTESIAN| | 100 | 25300 | 0 (0)| 00:00:01 |
|* 3 | FIXED TABLE FULL | X$KVIT | 1 | 47 | 0 (0)| 00:00:01 |
| 4 | BUFFER SORT | | 100 | 20600 | 0 (0)| 00:00:01 |
| 5 | FIXED TABLE FULL | X$KSUXSINST | 100 | 20600 | 0 (0)| 00:00:01 |
| 6 | BUFFER SORT | | 100 | 1300 | 6 (100)| 00:00:01 |
| 7 | FIXED TABLE FULL | X$QUIESCE | 100 | 1300 | 0 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
- filter("KVITTAG"='kcbwst')
两者使用了相同的底层表,但是查询过滤条件不一样,V$视图限制了从当前实例查询,而GV$视图则是没有限制。在RAC环境中,可以查询到所有的实例信息。实际上,v$视图一般是依据gv$创建的。可以使用视图v$fixed_view_definition(这个视图记录了v$和gv$视图的ddl语句。当然,还有别的):
SYS >select * from v$fixed_view_definition where VIEW_NAME='V$INSTANCE'
VIEW_NAME |VIEW_DEFINITION
------------------------------|----------------------------------------
V$INSTANCE |select INSTANCE_NUMBER , INSTANCE_NAME
|, HOST_NAME , VERSION , STARTUP_TIME , S
|TATUS , PARALLEL , THREAD# , ARCHIVER ,
|LOG_SWITCH_WAIT , LOGINS , SHUTDOWN_PEND
|ING, DATABASE_STATUS, INSTANCE_ROLE, ACT
|IVE_STATE, BLOCKED from GV$INSTANCE wher
|e inst_id = USERENV('Instance')
以v$视图为例:
在v$视图建立完毕后,oracle需要使用Catalog.sql脚本(实际是的事它包含的cdfixed.sql脚本)创建相应的v_$视图以及v$同义词。
create or replace view v_$instance as select * from v$instance;
create or replace public synonym v$instance for v_$instance;
grant select on v_$instance to select_catalog_role;
实际上,用户一般是没法直接访问v$视图的,普通用户发出select * from v$instance后,实际上是通过这个公用同义词定位到了v_$视图,然后再间接访问v$视图。那么,用户就必须具备访问v_$视图的权限才能访问真正的v$视图
例如:
HUANGXING >select * from v$instance;
select * from v$instance
ERROR at line 1:
ORA-00942: table or view does not exist(没有权限,所以找不到这个视图)
HUANGXING >desc v$instance;
ERROR:
ORA-04043: object "SYS"."V_$INSTANCE" does not exist(定位到这个视图了)
上面显示,实际上,v$instance是一个公用同义词,已经被解析为V_$INSTANCE
当给用户赋予读取某个V$视图时,不能直接赋予同义词的select 权限,而是之上的V_$权限:
SYS >grant select on v$instance to huangxing;
grant select on v$instance to huangxing
ERROR at line 1:
ORA-02030: can only select from fixed tables/views
SYS >grant select on v_$instance to huangxing;
Grant succeeded.
或者:
SYS >grant SELECT_CATALOG_ROLE to huangxing;
之前的dictionarys视图记录了所有的数据字典视图,那么什么视图记录了所有的动态性能视图呢?答案是v$fixed_table.另外,通过这个视图还可以看到X$的相关信息
HUANGXING >select count(*) from v$fixed_table where name like 'GV$%';
COUNT(*)
----------
505
HUANGXING >select count(*) from v$fixed_table where name like 'V$%';
COUNT(*)
----------
536
HUANGXING >select count(*) from v$fixed_table where
name like '%X$%';
COUNT(*)
----------
970
HUANGXING >select count(*) from v$fixed_table;
COUNT(*)
----------
2013
下面是10g以后引入的命名规则:
HUANGXING >select * from v$fixed_table where NAME
NOT like '%V$%' AND NAME NOT like '%X$%';
NAME | OBJECT_ID|TYPE | TABLE_NUM
------------------------------|----------|-----|----------
GO$SQL_BIND_CAPTURE |4294952035|VIEW | 65537
O$SQL_BIND_CAPTURE |4294952036|VIEW | 65537
可以通过视图v$fixed_view_definition查看在各个阶段创建的动态性能视图的定义,只要实例数据库启动,这个视图就记录了所有的动态性能视图的定义,尽管它可能还没创建。
nomount:
SYS >select count(*) from v$fixed_view_definition;
COUNT(*)
----------
1043
一般启动到nomount阶段,常见视图,比如v$instance,v$fixed_table,v$parameter,v$option,v$sga,v$bh,v$process,v$version,v$session, v$transaction会在这个阶段创建
Mount:
SYS >alter database mount;
启动到mount阶段后,由于读取了控制文件,将会创建更多的动态性能视图,例如v$controlfile,v$database,v$datafile,v$dagtafile_header.
Open:
Open以后,该有的视图都会创建。
一般用户访问对象时候,sql是根据下面顺序查找对象:
1. 在用户模式中查找是否存在这个表,或者视图
2. 如果在不存在相应表和视图,则判断是否是用户私有的同义词
3. 如果还不是,就判断是否是公有的同义词
4. 同义词存在,就定位到相应的对象
5. 如果同义词都不存在,就返回错误“ORA-00942: table or view does not exist”
以v$parameter为例。
已知,v$parameter是v_$parameter视图的公有同义词,v_parameter视图来自v$parameter视图,下面看看普通用户访问v$parameter的过程;
HUANGXING >alter session set events '10046 trace name context forever,level 12';
HUANGXING >select * from v$parameter;
HUANGXING >alter session set events '10046 trace name context off';
HUANGXING >select * from v$diag_info;
分析dump文件:
按照表,视图顺序来判断这个表的类型:
PARSING IN CURSOR #140105136966208 len=202 dep=1 uid=0 oct=3 lid=0 tim=1369308940095695 hv=3819099649 ad='6c854600' sqlid
='3nkd3g3ju5ph1'
select obj#,type#,ctime,mtime,stime, status, dataobj#, flags, oid$, spare1, spare2 from obj$ where owner#=:1 and name=:2 and namespace=:3 and remoteowner is null and linkname is null and subname is null
END OF STMT
……………………………………………………
BINDS #140105136966208:
Bind#0
oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
oacflg=00 fl2=0001 frm=00 csi=00 siz=80 off=0
kxsbbbfp=7f6cc4ecd848 bln=22 avl=02 flg=05
value=32
Bind#1
oacdty=01 mxl=32(11) mxlc=00 mal=00 scl=00 pre=00
oacflg=10 fl2=0001 frm=01 csi=852 siz=0 off=24
kxsbbbfp=7f6cc4ecd860 bln=32 avl=11 flg=01
value="V$PARAMETER"
Bind#2
oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
oacflg=00 fl2=0001 frm=00 csi=00 siz=0 off=56
kxsbbbfp=7f6cc4ecd880 bln=22 avl=02 flg=01
value=1
传入参数owner#,name,namespace参数后,判断对象类型。普通用户是没有这个表的,所有接下来将定位到同义词:
PARSING IN CURSOR #140105137050376 len=46 dep=1 uid=0 oct=3 lid=0 tim=1369308940167138 hv=1343089354 ad='6c908f88' sqlid=
'1mjd9xp80vuqa'
select node,owner,name from syn$ where obj#=:1
END OF STMT
PARSE #140105137050376:c=1999,e=1862,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,plh=0,tim=1369308940167132
BINDS #140105137050376:
Bind#0
oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
oacflg=00 fl2=0001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=7f6cc4ecc450 bln=22 avl=03 flg=05
value=1542
直接执行这条sql就知道,实际上获得了同义词的底层对象(V_$PARAMETER):
SYS >select node,owner,name from syn$ where obj#=1542;
NODE |OWNER |NAME
-------------------------------------------|----------|------------------------------
|SYS |V_$PARAMETER
接下来,找到这个对象后,就要找到这个视图的定义内容:
PARSING IN CURSOR #140105137019064 len=83 dep=1 uid=0 oct=3 lid=0 tim=1369308940399855 hv=1709162946 ad='6c839820' sqlid=
'g3wrkmxkxzhf2'
select cols,audit$,textlength,intcols,property,flags,rowid from view$ where obj#=:1
END OF STMT
PARSE #140105137019064:c=2000,e=1581,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,plh=0,tim=1369308940399851
BINDS #140105137019064:
Bind#0
oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
oacflg=00 fl2=0001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=7f6cc4d11380 bln=22 avl=03 flg=05
value=1541
PARSING IN CURSOR #140105135231048 len=37 dep=1 uid=0 oct=3 lid=0 tim=1369308940407967 hv=1398610540 ad='6c838070' sqlid=
'grwydz59pu6mc'
select text from view$ where rowid=:1
END OF STMT
PARSE #140105135231048:c=0,e=88,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,plh=3684871272,tim=1369308940407963
BINDS #140105135231048:
Bind#0
oacdty=11 mxl=16(16) mxlc=00 mal=00 scl=00 pre=00
oacflg=18 fl2=0001 frm=00 csi=00 siz=16 off=0
kxsbbbfp=7f6cc4d10c08 bln=16 avl=16 flg=05
value=00000276.000C.0001
SYS >select obj# from view$ where dbms_rowid.rowid_to_restricted(rowid,0)='00000276.000C.0001';
OBJ#
----------
1541
SYS >select text from view$ where obj#=1541;
select "NUM","NAME","TYPE","VALUE","DISPLAY_VALUE","ISDEFAULT","ISSES_MODIFIABLE","ISSYS_MODIFIABLE","ISINSTANCE_MODIFIABLE","ISMODIFIED","ISADJUSTED","ISDEPRECATED","ISBASIC","DESCRIPTION","UPDATE_COMMENT","HASH" from v$parameter