读书笔记 eygle 深入解析oracle
实验一遍加深理解
oracle数据字典表
(obj$之类)
ORACLE_HOME/RDMS/ADMIN/SQL.BSQ
建立这些 字典 表 (create database 时候 会 调用sql.bsq)
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 */
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, */
从注释可以看到OBJ#=OBJECT_ID(ALL_OBEJCETS.OBJECT_ID,DBA_OBJECTS.OBJECTS_ID,USER_OBJECTS.OBJECTS_ID)
dataobj#=data_object_id /* data layer object number */
区别是OBJ#一但分配就不改变了
dataobj#是于物理的存储有关系的,就是对象的物理号,随对象物理结构的改变而改变
SQL> select object_id,data_object_iD from dba_objects where object_name='T2';
OBJECT_ID DATA_OBJECT_ID
---------- --------------
52658 52658
SQL> truncate table xh.t2;
表被截断。
SQL> select object_id,data_object_iD from dba_objects where object_name='T2';
OBJECT_ID DATA_OBJECT_ID
---------- --------------
52658 53317(因为truncate 导致对象物理结构改变,truncate修改数据字典并不实际回收数据,然后对对象重新定位data_object_id改变)
所以可以看到注释中说不要dataobJ# column列建立index
SQL> select object_id from user_objects where object_name='T4';
OBJECT_ID
----------
53027
执SQL> alter session set sql_trace=true;
会话已更改。
SQL> drop table t3;
表已删除。
行DML(特定),DDL时候 ORACLE 会自动对数据字典操作
PARSING IN CURSOR #33 len=29 dep=1 uid=0 ct=7 lid=0 tim=15412874138 hv=1088688876 ad='1b40120c'
delete TAB$ where obj#=:1 都会换成类似的dml从 数据字典中删除数据
END OF STMT
静态数据字典VIEW :ALL_(当前用户可访问的所有对象),DBA_(DB中所有对象,需要是DBA ROLE,OR SELECT_CATALOG_ROLE),user_(当前用户拥有的对象)
SQL> conn xh/a831115
已连接。
SQL> select * from session_roles;
ROLE
------------------------------
DBA~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~XH 有dba role
SELECT_CATALOG_ROLE
HS_ADMIN_ROLE
EXECUTE_CATALOG_ROLE
DELETE_CATALOG_ROLE
EXP_FULL_DATABASE
IMP_FULL_DATABASE
GATHER_SYSTEM_STATISTICS
SCHEDULER_ADMIN
WM_ADMIN_ROLE
JAVA_ADMIN
ROLE
------------------------------
JAVA_DEPLOY
XDBADMIN
XDBWEBSERVICES
OLAP_DBA
已选择15行。
SQL> select count(*) from user_tables;
COUNT(*)
----------
2
SQL> select count(*) from all_tables;
COUNT(*)
----------
1584
SQL> select count(*) from dba_tables;
COUNT(*)
----------
1584
创建这些静态数据字典的VIEW 来自 oracle_home/rdbms/admin/catalog.sql
create or replace view USER_TABLES
(TABLE_NAME, TABLESPACE_NAME, CLUSTER_NAME, IOT_NAME, STATUS,
where o.owner# = userenv('SCHEMAID')~~~~~~~~~SCHEMAID returns the id of the schema for the current user. This id is used
and o.obj# = t.obj#
通过这个USERENV函数 限制只输出属于current user的 表
**************注意userenv()这个函数比较有用 **********
SQL> conn xh/a831115
已连接。
SQL> select userenv('SCHEMAID') from dual;
USERENV('SCHEMAID')
-------------------
61
SQL> select username from dba_users where user_id=61;
USERNAME
------------------------------
XH~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~只返回属于 user xh的
create or replace view DBA_TABLES
(OWNER, TABLE_NAME, TABLESPACE_NAME, CLUSTER_NAME, IOT_NAME, STATUS,
PCT_FREE, PCT_USED,
INI_TRANS, MAX_TRANS,
INITIAL_EXTENT, NEXT_EXTENT,
where o.owner# = u.user#*******返回DB中所有USER的表
create or replace view ALL_TABLES
(OWNER, TABLE_NAME, TABLESPACE_NAME, CLUSTER_NAME, IOT_NAME, STATUS,
where o.owner# = u.user#
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 */,~~~~~~~~存在这样的限制(DBA_中没有限制)
-48 /* INSERT ANY TABLE */,
-49 /* UPDATE ANY TABLE */,
-50 /* DELETE ANY TABLE */)
create or replace public synonym ALL_TABLES for ALL_TABLES 上面建立的是一个VIEW 为这个VIEW建立同译词(USER查询时实际是查这个同译词)
/
grant select on ALL_TABLES to PUBLIC with grant option 将SELECT ON ALL_TABLES给PBULIC ROLE,且可以授予其他USER
grant select on DBA_TABLES to select_catalog_role 可以看到 DBA_TABLES 给了SELECT_catalog_role,不能转授予其他USER
/
SQL> create user test identified by a123;
用户已创建。
SQL> grant connect to test;
授权成功。
SQL> grant resource to test;
授权成功。
SQL> conn test/a123
已连接。
SQL> select count(*) from all_tables;
COUNT(*)
----------
91
SQL> select count(*) from dba_tables;
select count(*) from dba_tables
*
第 1 行出现错误:
ORA-00942: 表或视图不存在
SQL> conn / as sysdba
已连接。
SQL> grant select_catalog_role to test
2 ;
授权成功。
SQL> conn test/a123
已连接。
SQL> select count(*) from dba_tables;
COUNT(*)
----------
1584
SQL> grant select_catalog_role to xh;***************
grant select_catalog_role to xh
*
第 1 行出现错误:
ORA-01932: ADMIN 选项未授权给角色 'SELECT_CATALOG_ROLE'
动态性能VIEW
DB启动时 ORACLE 动态创建x$ table,又根据 x$ table 动态创建了 V$,gv$ VIEW ,动态的反映DB情况
GV$ 与V$区别 就是 gv$ global view 针对 RAC
SQL> select inst_id from gv$instance;
INST_ID~~~~~~~~~~~~INSTANCE ID
----------
1
看下创建语句
SQL> select view_definition from v$fixed_view_definition where view_name='V$INST
ANCE';
VIEW_DEFINITION
--------------------------------------------------------------------------------
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, ACTIVE_STATE, BLOCKED from GV$INSTANCE wher
e inst_id = USERENV('Instance')~~~~~~~~~~~~~~~~~~~~~~可以看到v$是针对当前INSTANCE
SQL> select USERENV('Instance') from dual;
USERENV('INSTANCE')
-------------------
1
SQL> select view_definition from v$fixed_view_definition where view_name='GV$INS
TANCE';
VIEW_DEFINITION
--------------------------------------------------------------------------------
select ks.inst_id,ksuxsins,ksuxssid,ksuxshst,ksuxsver,ksuxstim,decode(ksuxssts,0
,'STARTED',1,'MOUNTED',2,'OPEN',3,'OPEN MIGRATE','UNKNOWN'),decode(ksuxsshr,0,'N
O',1,'YES',2,NULL),ksuxsthr,decode(ksuxsarc,0,'STOPPED',1,'STARTED','FAILED'),de
code(ksuxslsw,0,NULL,2,'ARCHIVE LOG',3,'CLEAR LOG',4,'CHECKPOINT', 5,'REDO
GENERATION'),decode(ksuxsdba,0,'ALLOWED','RESTRICTED'),decode(ksuxsshp,0,'NO','
YES'),decode(kvitval,0,'ACTIVE',2147483647,'SUSPENDED','INSTANCE RECOVERY'),deco
de(ksuxsrol,1,'PRIMARY_INSTANCE',2,'SECONDARY_INSTANCE','UNKNOWN'), decode(qui_s
tate,0,'NORMAL',1,'QUIESCING',2,'QUIESCED','UNKNOWN'), decode(bitand(ksuxsdst, 1
), 0, 'NO', 1, 'YES', 'NO') from x$ksuxsinst ks, x$kvit kv, x$quiesce qu where k
vittag = 'kcbwst'~~~~~~~~~~~~~~~~~GV 没这个限制
create or replace view v_$librarycache as select * from v$librarycache;
create or replace public synonym v$librarycache for v_$librarycache;
grant select on v_$librarycache to select_catalog_role;
可以看到oracle 先创建 v_$librarycache 这个VIEW(基于 v$librarycache(基于x$) )
对 v_$librarycache 又创建 v$librarycache SYNONYM同译词
用户访问用的是 同译词
create or replace view gv_$sqlstats as select * from gv$sqlstats;
create or replace public synonym gv$sqlstats for gv_$sqlstats;
grant select on gv_$sqlstats to select_catalog_role;~~~~~~~可以看到 要访问gv_$sqlstats必须要select_catalog_role
SQL> conn tr/a123
已连接。
SQL> select * from session_roles;
ROLE
------------------------------
CONNECT~~~~~~~~~~~~~~~~~~~没有select_catalog_role ROLE
SQL> desc gv$sqlstats;
ERROR:
ORA-04043: 对象 "SYS"."GV_$SQL" 不存在~~~~~~~~~可以看到error 实际查询的是GV_$
SQL> conn / as sysdba
已连接。
SQL> create user tr identified by a123;
用户已创建。
SQL> grant connect,resource to tr;
授权成功。
SQL> grant select_catalog_role to tr;
授权成功。
SQL> conn tr/a123
SQL> select count(*) from v$session;
COUNT(*)
----------
23
SQL> ed
已写入 file afiedt.buf
1 create or replace procedure tr
2 as
3 type a is table of v$session%rowtype;
4 b a;
5 begin
6 select * bulk collect into b from v$session ;
7 for i in 1..b.count loop
8 dbms_output.put_line(b(1).sid);
9 end loop;
10* end;
SQL> /
警告: 创建的过程带有编译错误。
SQL> show error
PROCEDURE TR 出现错误:
LINE/COL ERROR
-------- -----------------------------------------------------------------
3/1 PL/SQL: Item ignored
3/20 PLS-00201: 必须声明标识符 'V$SESSION'
6/1 PL/SQL: SQL Statement ignored
6/35 PL/SQL: ORA-00942: 表或视图不存在~~~~~~~~~~~~~~~~~~~
8/1 PL/SQL: Statement ignored
8/27 PLS-00487: 对变量 'V$SESSION%ROWTYPE' 的引用无效
SQL>
原理很简单 查询v$session 这个SYNONYM 是通过 ROLE 查询到的(类似grant select on gv_$sqlstats to select_catalog_role 权限,角色实验中也有实验到),procedure中需要
直接 授予的权限 而不是通过role(role要登陆才能激活 procedure,trigger中无效)
SQL> conn / as sysdba
已连接。
SQL> grant select on v_$session to tr ~~~~~~~授予直接查看v_$librarycache 这个基于 (基于 v$librarycache(基于x$) ) 的view
2 ;
授权成功。
SQL> alter procedure tr.tr compile;
过程已更改。
所有的 X$表,V$ VIEW,GV$ view
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
SQL> select count(*) from v$fixed_table where name like 'X$%';
COUNT(*)
----------
613
SQL> select count(*) from v$fixed_table where name like 'GV$%';
COUNT(*)
----------
372
SQL> select count(*) from v$fixed_table where name like 'V$%';
COUNT(*)
----------
396
每个阶段的v$
NOMOUNT:可以查看与spfile相关的VIEW 可以查询
例如
SQL> select count(*) from v$parameter;~************查不了
select count(*) from v$parameter
*
第 1 行出现错误:
ORA-01220: ?????????????????
SQL> select count(*) from v$spparameter;
COUNT(*)
----------
265
SQL> select count(*) from v$sga;
COUNT(*)
----------
4
SQL> select count(*) from v$bh;
COUNT(*)
----------
0
SQL> select count(*) from v$instance;
COUNT(*)
----------
1
SQL> alter database mount;加载控制文件 可以查询与controlfile相关的VIEW
SQL> select count(*) from v$database;
COUNT(*)
----------
1
SQL> select count(*) from v$datafile;
COUNT(*)
----------
6
SQL> select count(*) from v$datafile_header;
COUNT(*)
----------
6
SQL> select count(*) from v$log;
COUNT(*)
----------
3
SQL> alter database open;所有VIEW可查询
数据库已更改。
ORACLE 查询时 VIEW优先 ,然后是 synonym
SQL> conn xh/a831115
已连接。
SQL> create table t1 as select * from user_users;
表已创建。
SQL> create view v$t1 as select * from t1;
视图已创建。
SQL> create view v_$t1 as select * from v$t1;
视图已创建。
SQL> create public synonym v$t1 for v_$t1;
同义词已创建。
SQL> conn / as sysdba
已连接。
SQL> create view v$t1 as select username from user_users ;
视图已创建。
SQL> desc v$t1;
名称 是否为空? 类型
----------------------------------------- -------- -------------------------
USERNAME NOT NULL VARCHAR2(30)
SQL> drop view v$t1;~~~~~~~删除这个VIEW
视图已删除。
SQL> desc v$t1;再查询是 SYNONYM
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------
USERNAME NOT NULL VARCHAR2(30)
USER_ID NOT NULL NUMBER
ACCOUNT_STATUS NOT NULL VARCHAR2(32)
LOCK_DATE DATE
EXPIRY_DATE DATE
DEFAULT_TABLESPACE NOT NULL VARCHAR2(30)
TEMPORARY_TABLESPACE NOT NULL VARCHAR2(30)
CREATED NOT NULL DATE
INITIAL_RSRC_CONSUMER_GROUP VARCHAR2(30)
EXTERNAL_NAME VARCHAR2(4000)
实验看v$parameter
SQL> desc v$fixed_view_definition
名称 是否为空? 类型
----------------------------------------- -------- ---------------------
VIEW_NAME VARCHAR2(30) 视图名
VIEW_DEFINITION VARCHAR2(4000) 视图定义
SQL> select view_definition from v$fixed_view_definition where view_name='V$PARA
METER';
VIEW_DEFINITION
--------------------------------------------------------------------------------
select NUM , NAME , TYPE , VALUE , DISPLAY_VALUE, ISDEFAULT , ISSES_MODIFIABLE
, ISSYS_MODIFIABLE , ISINSTANCE_MODIFIABLE, ISMODIFIED , ISADJUSTED , ISDEPRECAT
ED, DESCRIPTION, UPDATE_COMMENT, HASH from GV$PARAMETER where inst_id = USERENV
('Instance') ~~~~~~~~~~~~~~~~~~~基于gv$parameter
SQL> select view_definition from v$fixed_view_definition where view_name='GV$PAR
AMETER';
VIEW_DEFINITION
--------------------------------------------------------------------------------
select x.inst_id,x.indx+1,ksppinm,ksppity,ksppstvl, ksppstdvl, ksppstdf, decode
(bitand(ksppiflg/256,1),1,'TRUE','FALSE'), decode(bitand(ksppiflg/65536,3),1,'I
MMEDIATE',2,'DEFERRED', 3,'IMMEDIATE','FALSE'),
decode(bitand(ksppiflg,4),4,'FALSE', decod
e(bitand(ksppiflg/65536,3), 0, 'FALSE', 'TRUE')), decode(bitand(ksppstvf,7),
1,'MODIFIED',4,'SYSTEM_MOD','FALSE'), decode(bitand(ksppstvf,2),2,'TRUE','FALSE
'), decode(bitand(ksppilrmflg/64, 1), 1, 'TRUE', 'FALSE'), ksppdesc, ksppstcmn
t, ksppihash from x$ksppi x, x$ksppcv y where (x.indx = y.indx) and ((translat
e(ksppinm,'_','#') not like '##%') and ((translate(ksppinm,'_','#') not like
'#%') or (ksppstdf = 'FALSE') or (bitand(ksppstvf,5) > 0)))
基于
x$ksppi x, x$ksppcv y 所有参数都在这个2个VIEW中 包含隐藏参数
V$ VIEW 不能直接授予 USER (SYS 除外) ,可以通过v_$这个视图基于(v$) 授予USER,USER 查询时通过 SYNOYNM(对V_$创建)
SQL> grant select on v$instance to xh;
grant select on v$instance to xh
*
第 1 行出现错误:
ORA-02030: 只能从固定的表/视图查询
SQL> desc sys.v$parameter;(SYS 是直接先访问 VIEW)可以看到普通USER 无法访问V$ VIEW
ERROR:
ORA-04043: 对象 sys.v$parameter 不存在
SQL> desc v$parameter; 访问的是 基于V_$建立的SYNONYM
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------
NUM NUMBER
NAME VARCHAR2(80)
TYPE NUMBER
VALUE VARCHAR2(512)
DISPLAY_VALUE VARCHAR2(512)
ISDEFAULT VARCHAR2(9)
ISSES_MODIFIABLE VARCHAR2(5)
ISSYS_MODIFIABLE VARCHAR2(9)
ISINSTANCE_MODIFIABLE VARCHAR2(5)
ISMODIFIED VARCHAR2(10)
ISADJUSTED VARCHAR2(5)
ISDEPRECATED VARCHAR2(5)
DESCRIPTION VARCHAR2(255)
UPDATE_COMMENT VARCHAR2(255)
HASH NUMBER
看oracle访问过程
SQL> alter session set events '10046 trace name context forever,level 12';用10046跟踪
会话已更改。
SQL> select count(*) from v$parameter;
COUNT(*)
----------
263
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
PARSE #1:c=0,e=637,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,tim=9148878891
BINDS #1:
kkscoacd
Bind#0
acdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
acflg=08 fl2=0001 frm=00 csi=00 siz=24 ff=0
kxsbbbfp=07ad56dc bln=22 avl=02 flg=05
value=61
Bind#1
acdty=01 mxl=32(11) mxlc=00 mal=00 scl=00 pre=00
acflg=18 fl2=0001 frm=01 csi=852 siz=32 ff=0
kxsbbbfp=07ad56b0 bln=32 avl=11 flg=05
value="V$PARAMETER"
Bind#2
acdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
acflg=08 fl2=0001 frm=00 csi=00 siz=24 ff=0
kxsbbbfp=07ad568c bln=24 avl=02 flg=05
value=1
SQL> select obj#,type#,ctime,mtime,stime,status,dataobj#,flags,oid$, spare1, spa
re2 from obj$ where owner#=61 and name='V$PARAMETER' and namespace=1;
未选定行~~~输入 61,v$parameter ,1 没记录 XH SCHEMA下没有这个OBJ,所以为空接着判断 验证SYNONYM,假如OBJ属于查询的SCHEMA的话 oracle
可以查到以下信息 看到对象类型,按表>view>synonym 定位判断
type :1 = INDEX, 2 = TABLE, 3 = CLUSTER, 4 = VIEW, 5 = SYNONYM, 6 = SEQUENCE
SQL> select username from dba_users where user_id=61;(OWNER#)
USERNAME
------------------------------
XH
SQL> select obj#,type#,ctime,mtime,stime,status,dataobj#,flags,oid$, spare1, spa
re2 from obj$ where owner#=1 and name='V$PARAMETER' and namespace=1;
OBJ# TYPE# CTIME MTIME STIME STATUS
---------- ---------- -------------- -------------- -------------- ----------
DATAOBJ# FLAGS OID$ SPARE1 SPARE2
---------- ---------- -------------------------------- ---------- ----------
1097 5 30-8月 -05 30-8月 -05 30-8月 -05 1
0 6 65535
继续输出
select node,owner,name from syn$ where obj#=:1
END OF STMT
PARSE #3:c=31250,e=132154,p=0,cr=147,cu=0,mis=1,r=0,dep=1,og=4,tim=9149088970
BINDS #3:
kkscoacd
Bind#0
acdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
acflg=08 fl2=0001 frm=00 csi=00 siz=24 ff=0
kxsbbbfp=07a83a2c bln=22 avl=03 flg=05
value=1097
SQL> select object_id,object_type,owner from dba_objects where object_id=1097;
OBJECT_ID OBJECT_TYPE OWNER
---------- ------------------- ------------------------------
1097 SYNONYM PUBLIC~~~~~~~~~~~~~~~~~~~~~~~~~~是个同译词 属于 公有(表和,VIEW 没查到 查询公有SYNONYM)
SQL> select node,owner,name from syn$ where obj#=1097;
NODE
--------------------------------------------------------------------------------
OWNER NAME
------------------------------ ------------------------------
SYS V_$PARAMETER~~~~~~~ 是V_$PARAMETER的同译词 属于SYS SCHEMA
select text from view$ where rowid=:1 查询view获得定义VIEW 的SQLTEXT
END OF STMT
BINDS #1:
kkscoacd
Bind#0
acdty=11 mxl=16(16) mxlc=00 mal=00 scl=00 pre=00
acflg=18 fl2=0001 frm=00 csi=00 siz=16 ff=0
kxsbbbfp=07a8bd94 bln=16 avl=16 flg=05
value=000001CD.001D.0001
SQL> select obj# from view$ where dbms_rowid.rowid_to_restricted(rowid,0)='00000
1CD.001D.0001';
OBJ#
----------~~~~~查看obj 为1096
1096
SQL> select object_id,object_type,owner,object_name from dba_objects where objec
t_id=1096;
OBJECT_ID OBJECT_TYPE OWNER
---------- ------------------- ------------------------------
OBJECT_NAME
--------------------------------------------------------------------------------
1096 VIEW SYS
V_$PARAMETER
查询SYS V_$PARAMETER 这个VIEW 定义的SQLTXT
SQL> select text from view$ where dbms_rowid.rowid_to_restricted(rowid,0)='00000
1CD.001D.0001';
TEXT
--------------------------------------------------------------------------------
select "NUM","NAME","TYPE","VALUE","DISPLAY_VALUE","ISDEFAULT","ISSES_MODIFIABLE ....FROM V$PARAMETER(基于x$建立的view)
~~~~~~~~~
SQL>
顺序:
parse for object t
if (table t OR VIEW t) 先查表 or view 是否存在
RETURN
elseif (synonym t)~~~~~不存在表or view 查私有SYNONYM
return
elseif(public synonym t) 不存在 私有synonym 查公有synonym
return
else
signal 0ra-00942(TABLE OR VIEW DOES NOT EXIST)~~~~~~~~~都没有报错
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12020513/viewspace-615502/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/12020513/viewspace-615502/