首先,oracle的字典表和视图基本上可以分为三个层次。
1.1 x$表
这一部分表是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
1.2 gv$和v$视图
从oracle8开始,gv$视图开始被引入,其含义为global v$.
除了一些特例以外,每个v$视图都有一个对应的gv$视图存在。
gv$视图的产生是为了满足ops环境的需要,在ops环境中,查询gv$视图返回所有实例信息,而每个v$视图基于gv$视图,增加了inst_id列判断后建立,只包含当前连接实例信息。
注意,每个v$视图都包含类似语句:
where inst_id = userenv('instance')
用于限制返回当前实例信息。
我们从gv$fixed_table和v$fixed_table开始
sql> select view_definition from v_$fixed_view_definition where view_name='v$fixed_table';
view_definition
------------------------------------------------------------------------------
select name , object_id , type , table_num from gv$fixed_table where inst_id = userenv('instance')
这里我们看到v$fixed_table基于gv$fixed_table创建。
sql> select view_definition from v_$fixed_view_definition where view_name='gv$fixed_table';
view_definition
------------------------------------------------------------------------------
select inst_id,kqftanam, kqftaobj, 'table', indx from x$kqfta
union all
select inst_id,kqfvinam, kqfviobj, 'view', 65537 from x$kqfvi
union all
select inst_id,kqfdtnam, kqfdtobj, 'table', 65537 from x$kqfdt
这样我们找到了gv$fixed_table视图的创建语句,该视图基于x$表创建。
1.3 gv_$,v_$视图和v$,gv$同义词
这些视图是通过catalog.ql创建。
当catalog.sql运行时:
create or replace view v_$fixed_table as select * from v$fixed_table;
create or replace public synonym v$fixed_table for v_$fixed_table;
create or replace view gv_$fixed_table as select * from gv$fixed_table;
create or replace public synonym gv$fixed_table for gv_$fixed_table;
我们注意到,第一个视图v_$和gv_$首先被创建,v_$和gv_$两个视图。
然后基于v_$视图的同义词被创建。
所以,实际上通常我们访问的v$视图,其实是指向v_$视图的同义词。
而v_$视图是基于真正的v$视图(这个视图是基于x$表建立的)。
而v$fixed_view_definition视图是我们研究oracle对象关系的一个入口,仔细理解oracle的数据字典机制,有助于深入了解和学习oracle数据库知识。
1.4 再进一步1.4.1 x$表
关于x$表,其创建信息我们也可以从数据字典中一窥究竟。
首先我们考察bootstrap$表,该表中记录了数据库启动的基本及驱动信息。
sql> select * from bootstrap$;
line# obj# sql_text
------------------------------------------------------------------------------
-1 -1 8.0.0.0.0
0 0 create rollback segment system storage ( initial 112k next 1024k minextents 1 m
8 8 create cluster c_file#_block#("ts#" number,"segfile#" number,"segblock#" number)
9 9 create index i_file#_block# on cluster c_file#_block# pctfree 10 initrans 2 maxt
14 14 create table seg$("file#" number not null,"block#" number not null,"type#" numbe
5 5 create table clu$("obj#" number not null,"dataobj#" number,"ts#" number not null
6 6 create cluster c_ts#("ts#" number) pctfree 10 pctused 40 initrans 2 maxtrans 255
7 7 create index i_ts# on cluster c_ts# pctfree 10 initrans 2 maxtrans 255 storage (
....
这部分信息,在数据库启动时最先被加载,跟踪数据库的启动过程,我们发现数据库启动的第一个动作就是:
create table bootstrap$ ( line# number not null, obj#
number not null, sql_text varchar2(4000) not null) storage (initial
50k objno 56 extents (file 1 block 377))
这部分代码是写在oracle应用程序中的,在内存中创建了bootstrap$以后,oracle就可以从file 1,block 377上读取其他信息,创建重要的数据库对象。从而根据这一部分信息启动数据库,这就实现了数据库的引导,类似于操作系统的初始化。
这部分你可以参考biti_rainy的文章。
x$表由此建立。这一部分表可以从v$fixed_table中查到:
sql> select count(*) from v$fixed_table where name like 'x$%';
count(*)
----------
394
共有394个x$对象被记录。
1.4.2 gv$和v$视图
x$表建立以后,基于x$表的gv$和v$视图得以创建。
这部分视图我们也可以通过查询v$fixed_table得到。
sql> select count(*) from v$fixed_table where name like 'gv$%';
count(*)
----------
259
这一部分共259个对象。
sql> select count(*) from v$fixed_table where name like 'v$%';
count(*)
----------
259
同样是259个对象。
v$fixed_table共记录了:
394 + 259 + 259 共 912 个对象。
我们通过v$parameter视图来追踪一下数据库的架构:
sql> select view_definition from v$fixed_view_definition a where a.view_name='v$parameter';
view_definition
------------------------------------------------------------------------------
select num , name , type , value , isdefault , isses_modifiable , issys_modifia
ble , ismodified , isadjusted , description, update_comment from gv$parameter wh
ere inst_id = userenv('instance')
我们看到v$parameter是由gv$parameter创建的。
sql> select view_definition from v$fixed_view_definition a where a.view_name='gv$parameter';
view_definition
-----------------------------------------------------------------------------
select x.inst_id,x.indx+1,ksppinm,ksppity,ksppstvl,ksppstdf, decode(bitand(kspp
iflg/256,1),1,'true','false'), decode(bitand(ksppiflg/65536,3),1,'immediate',2,
'deferred', 3,'immediate','false'), decode(bit
and(ksppstvf,7),1,'modified',4,'system_mod','false'), decode(bitand(ksppstvf,2)
,2,'true','false'), ksppdesc, ksppstcmnt from x$ksppi x, x$ksppcv y where (x.i
ndx = y.indx) and ((translate(ksppinm,'_','#') not like '#%') or (ksppstdf = 'f
alse'))
在这里我们看到gv$parameter来源于x$ksppi,x$ksppcv两个x$表。 x$ksppi,x$ksppcv 基本上包含所有数据库可调整参数,v$parameter展现的是不包含"_"开头的参数。以"_"开头的参数我们通常称为隐含参数,一般不建议修改,但很多因为功能强大经常使用而广为人知。