Skip to content

客户反映归档的位置不太多,再仔细看归档的名字也不对;检查下发现指定 归档目录类似
/arch/test 而不是/arch/test/
如下测试验证log_archive_dest_1与log_archive_format对生成的归档文件名的影响。
1.log_archive_dest_1指定的目录后面还有字段

1.1. 字段对应的无同名目录,生成归档文件名=log_archive_dest_1+log_archive_format

1.2 字段对应的有同名目录,生成归档文件在同名目录下,文件名为log_archive_format
2.log_archive_dest_1指定的目录不存在–报错
3.log_archive_dest_1指定的目录
归档文件名=log_archive_format

———————————–
1 log_archive_dest_1指定的目录后面还有字段

1.1. 字段对应的无同名目录,生成归档文件名=log_archive_dest_1+log_archive_format

归档文件名=log_archive_dest_1+log_archive_format
SQL> alter system set log_archive_dest_1=’LOCATION=/u01/oracle/base/oracle/oradata/arch/test’;
System altered.
SQL> archive log list;
Database log mode Archive Mode
Automatic archival Enabled
Archive destination /u01/oracle/base/oracle/oradata/arch/test
Oldest online log sequence 24
Next log sequence to archive 26
Current log sequence 26
SQL> show parameter log_archive_format
NAME TYPE VALUE
———————————— ———– ——————————
log_archive_format string %t_%s_%r.dbf
SQL> alter system switch logfile;
System altered.
——–生成的文件名
[oracle@bys1 arch]$ pwd
/u01/oracle/base/oracle/oradata/arch
[oracle@bys1 arch]$ ls
test1_26_900253622.dbf

1.2 字段对应的有同名目录,生成归档文件在同名目录下,文件名为log_archive_format

文件在同名目录下,文件名为log_archive_format

SQL> alter system switch logfile;
System altered.

[oracle@bys1 test]$ pwd
/u01/oracle/base/oracle/oradata/arch/test
[oracle@bys1 test]$ ls
1_40_900253622.dbf

2.log_archive_dest_1指定的目录不存在–直接报错
SQL> alter system set log_archive_dest_1=’LOCATION=/u01/oracle/base/oracle/oradata/arch/test/’;
alter system set log_archive_dest_1=’LOCATION=/u01/oracle/base/oracle/oradata/arch/test/’
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-16032: parameter LOG_ARCHIVE_DEST_1 destination string cannot be translated
ORA-07286: sksagdi: cannot obtain device information.
Linux Error: 2: No such file or directory

3.log_archive_dest_1指定目录
归档文件名=log_archive_format
[oracle@bys1 arch]$ mkdir test
[oracle@bys1 arch]$ ls
test test1_26_900253622.dbf
SQL> alter system set log_archive_dest_1=’LOCATION=/u01/oracle/base/oracle/oradata/arch/test/’;
System altered.
SQL> archive log list;
Database log mode Archive Mode
Automatic archival Enabled
Archive destination /u01/oracle/base/oracle/oradata/arch/test/
Oldest online log sequence 25
Next log sequence to archive 27
Current log sequence 27
SQL> show parameter log_archive_format
NAME TYPE VALUE
———————————— ———– ——————————
log_archive_format string %t_%s_%r.dbf
SQL> alter system switch logfile;
System altered.
———
[oracle@bys1 arch]$ cd test
[oracle@bys1 test]$ ls -al
total 12
drwxr-xr-x 2 oracle oinstall 4096 Feb 1 16:13 .
drwxr-xr-x 3 oracle oinstall 4096 Feb 1 16:13 ..
-rw-r—– 1 oracle asmadmin 2560 Feb 1 16:13 1_27_900253622.dbf
[oracle@bys1 test]$ pwd
/u01/oracle/base/oracle/oradata/arch/test

 

测试log_archive_dest_1与log_archive_format对生成的归档文件名的影响

TRUNCATE表后对表大小进行查询,表的空间没有释放完毕?
对此进行实验测试,结果如下:(测试环境LINUX+ORACLE11.2.0.3)
创建表时语句指定了storage (MINEXTENTS 5);时,TRUNCATE后还有5个EXTENT;
创建表时语句不指定storage (MINEXTENTS参数,即使用默认值时;TRUNCATE后只有1个EXTENT;
———— 实验1:指定了storage (MINEXTENTS 5)
SQL> create tablespace test2 datafile ‘/u01/oracle/base/oracle/oradata/bys7/test2.dbf’ size 10m uniform size 40k;
Tablespace created.

SQL> show user
USER is “TEST”
SQL> create table test1(aa number,name varchar2(128)) tablespace test2 storage (MINEXTENTS 5);
Table created.
SQL> select owner,SEGMENT_NAME,TABLESPACE_NAME,EXTENT_ID from dba_extents where SEGMENT_NAME=’TEST1′;
OWNER SEGMENT_NAME TABLESPACE_NAME EXTENT_ID
—————————— ———— ————— ———-
TEST TEST1 TEST2 0
TEST TEST1 TEST2 1
TEST TEST1 TEST2 2
TEST TEST1 TEST2 3
TEST TEST1 TEST2 4

SQL> insert into test1 select object_id,object_name from dba_objects;
13723 rows created.
SQL> commit;
Commit complete.
SQL> select owner,SEGMENT_NAME,TABLESPACE_NAME,EXTENT_ID from dba_extents where SEGMENT_NAME=’TEST1′;
OWNER SEGMENT_NAME TABLESPACE_NAME EXTENT_ID
—————————— ———— ————— ———-
TEST TEST1 TEST2 0
TEST TEST1 TEST2 1
TEST TEST1 TEST2 2
TEST TEST1 TEST2 3
TEST TEST1 TEST2 4
TEST TEST1 TEST2 5
TEST TEST1 TEST2 6
TEST TEST1 TEST2 7
TEST TEST1 TEST2 8
TEST TEST1 TEST2 9
TEST TEST1 TEST2 10
TEST TEST1 TEST2 11
12 rows selected.

SQL>truncate table test1;
Table truncated.

SQL> select owner,SEGMENT_NAME,TABLESPACE_NAME,EXTENT_ID from dba_extents where SEGMENT_NAME=’TEST1′;

OWNER SEGMENT_NAME TABLESPACE_NAME EXTENT_ID
—————————— ———— ————— ———-
TEST TEST1 TEST2 0
TEST TEST1 TEST2 1
TEST TEST1 TEST2 2
TEST TEST1 TEST2 3
TEST TEST1 TEST2 4

SQL> select SEGMENT_NAME,TABLESPACE_NAME,BYTES/1024 kb,EXTENTS,BLOCKS,INITIAL_EXTENT,NEXT_EXTENT,MIN_EXTENTS,MAX_EXTENTS from dba_segments where SEGMENT_NAME=’TEST1′;
SEGMENT_NAME TABLESPACE_NAME KB EXTENTS BLOCKS INITIAL_EXTENT NEXT_EXTENT MIN_EXTENTS MAX_EXTENTS
———— ————— ———- ———- ———- ————– ———– ———– ———–
TEST1 TEST2 200 5 25 204800 40960 1 2147483645

实验2:创建表时不指定storage (MINEXTENTS参数 使用默认值
SQL> create table test2 tablespace test2 as select object_id,object_name from dba_objects;
Table created.

SQL> set pagesize 1000
SQL> select owner,SEGMENT_NAME,TABLESPACE_NAME,EXTENT_ID from dba_extents where SEGMENT_NAME=’TEST2′;
OWNER SEGMENT_NAME TABLESPACE_NAME EXTENT_ID
—————————— ———— ————— ———-
TEST TEST2 TEST2 0
TEST TEST2 TEST2 1
TEST TEST2 TEST2 2
TEST TEST2 TEST2 3
TEST TEST2 TEST2 4
TEST TEST2 TEST2 5
TEST TEST2 TEST2 6
TEST TEST2 TEST2 7
TEST TEST2 TEST2 8
TEST TEST2 TEST2 9
TEST TEST2 TEST2 10
TEST TEST2 TEST2 11
12 rows selected.

SQL> truncate table test2;
Table truncated.

SQL> select owner,SEGMENT_NAME,TABLESPACE_NAME,EXTENT_ID from dba_extents where SEGMENT_NAME=’TEST2′;
OWNER SEGMENT_NAME TABLESPACE_NAME EXTENT_ID
—————————— ———— ————— ———-
TEST TEST2 TEST2 0

 

表的storage (MINEXTENTS 属性对truncate后表大小的影响

官方文档中关于NLS_LENGTH_SEMANTICS参数介绍:
可选值是BYTE | CHAR,默认是BYTE,可以在数据库和会话级动态修改。也可以在客户端环境变量中进行设置(不适合JDBC瘦客户端)
NCHAR, NVARCHAR2, CLOB, and NCLOB 始终是基于BYTE。
以SYS用户登陆时不考虑NLS_LENGTH_SEMANTICS参数统一使用BYTE;除非在创建对象等DDL语句中明确定义。
ORACLE强烈建议不能在数据库实例级别设置此参数。
—-
AL32UTF8字符集时一个汉字占三个byte
ZHS16GBK字符集时一个汉字占两个byte

本实验结论:
1.创建表时指定字段类型为 varchar2(10)时–即不指定使用的类型,字段使用的dba_tab_columns视图的char_used字段值等于创建表时会话级的nls_length_semantics=BYTE
2.在AL32UTF8字符集时一个汉字是3个BYTE,ZHS16GBK字符集时一个汉字占两个byte。
3.如果字段类型为 varchar2(10)为BYTE(dba_tab_columns视图char_used字段是B(BYTE)),能存放三个汉字—>一个汉字是3个BYTE
4.如果字段类型为 varchar2(10)为char(dba_tab_columns视图char_used字段是C(CHAR)),能存放十个汉字—>一个汉字是3个BYTE
5.以SYS用户登陆时不考虑NLS_LENGTH_SEMANTICS参数统一使用BYTE;除非在创建对象等DDL语句中明确定义。
6.在系统或会话级修改nls_length_semantics=char参数值,不会对已有表中varchar2字段的char_used进行修改

实验的步骤:
实验1-4使用AL32UTF8的数据库进行测试。
实验1:默认nls_length_semantics=BYTE且指定字段类型为 varchar2(10)
此时从dba_tab_columns视图的char_used字段可以发现使用的是B(BYTE),在AL32UTF8字符集下一个汉字是3个BYTE。
实验2:修改nls_length_semantics=CHAR且指定字段类型为 varchar2(10)
此时从dba_tab_columns视图的char_used字段可以发现使用的是C(CHAR),此时可以插入10个字符。
实验3:alter system set nls_length_semantics=char;参数不会对已有的表中varchar2字段的char_used进行修改
实验4:测试以SYS用户登陆时不考虑NLS_LENGTH_SEMANTICS参数统一使用BYTE;除非在创建对象等DDL语句中明确定义。
实验5:测试ZHS16GBK字符集时一个汉字占的字符数

具体实验过程
#################################################################
实验1:
默认nls_length_semantics=BYTE且指定字段类型为 varchar2(10)
此时从dba_tab_columns视图的char_used字段可以发现使用的是B(BYTE),在AL32UTF8字符集下一个汉字是3个BYTE。
SQL> select userenv(‘language’) from dual;
USERENV(‘LANGUAGE’)
—————————————————-
AMERICAN_AMERICA.AL32UTF8
SQL> select lengthb(‘白’) from dual;
LENGTHB(‘白’)
————-
3
SQL> show user
USER is “BYS”
SQL> show parameter nls_length_semantics;
NAME TYPE VALUE
———————————— ———– ——————————
nls_length_semantics string BYTE
SQL> create table t1(id number,name varchar2(10));
Table created.
SQL> create table t4(id number,name varchar2(10 char));
Table created.

SQL> select table_name,column_name,data_type,char_used from dba_tab_columns where table_name=’T1′ or table_name=’T4′ ;
TABLE_NAME COLUMN_NAME DATA_TYPE C
—————————— —————————— ———- –
T4 NAME VARCHAR2 C
T4 ID NUMBER
T1 NAME VARCHAR2 B
T1 ID NUMBER
SQL> desc t1
Name Null? Type
—————————————– ——– —————————-
ID NUMBER
NAME VARCHAR2(10)

在SQL*PLUS窗口输入时–经过了字符转换(猜测是主机的)显示是5个汉字30个字符
SQL> insert into t1 values(1,’浙江省杭州’);
insert into t1 values(1,’浙江省杭州’)
*
ERROR at line 1:
ORA-12899: value too large for column “BYS”.”T1″.”NAME” (actual: 30, maximum: 10)
SQL> insert into t1 values(1,’浙江杭州’);

在PL/SQL DEVELOPER工具窗口:
SQL> insert into t1 values(1,’浙江省杭州’);

insert into t1 values(1,’浙江省杭州’)
ORA-12899: 列 “BYS”.”T1″.”NAME” 的值太大 (实际值: 15, 最大值: 10)

SQL> insert into t1 values(1,’浙江杭州’);

insert into t1 values(1,’浙江杭州’)
ORA-12899: 列 “BYS”.”T1″.”NAME” 的值太大 (实际值: 12, 最大值: 10)

SQL> insert into t1 values(1,’浙江省’);
1 row inserted
SQL> commit;
Commit complete
SQL> select * from t1;
ID NAME
———- ———-
1 浙江省
SQL> insert into t4 values(1,’浙江省杭州市西湖区西湖’);
insert into t4 values(1,’浙江省杭州市西湖区西湖’)
ORA-12899: 列 “BYS”.”T4″.”NAME” 的值太大 (实际值: 11, 最大值: 10)
SQL> insert into t4 values(1,’浙江省杭州市西湖区西’);
1 row inserted
SQL> commit;
Commit complete
SQL> select * from t4;
ID NAME
———- —————————————-
1 浙江省杭州
1 浙江省杭州市西湖区西

#####################################################################
实验2:
修改nls_length_semantics=CHAR且指定字段类型为 varchar2(10)
此时从dba_tab_columns视图的char_used字段可以发现使用的是C(CHAR),此时可以插入10个字符。
SQL> alter session set nls_length_semantics=CHAR;
Session altered.
SQL> show parameter nls_length_semantics;
NAME TYPE VALUE
———————————— ———– ——————————
nls_length_semantics string CHAR
SQL> create table t2(id number,name varchar2(10));
Table created.
SQL> create table t3(id number,name varchar2(10 char));
Table created.
SQL> create table t6(id number,name varchar2(10 byte));
Table created.
SQL> select table_name,column_name,data_type,char_used from dba_tab_columns where table_name=’T3′ or table_name=’T2′ or table_name=’T6′ ;

TABLE_NAME COLUMN_NAME DATA_TYPE C
—————————— —————————— ———- –
T6 NAME VARCHAR2 B
T6 ID NUMBER
T3 NAME VARCHAR2 C
T3 ID NUMBER
T2 NAME VARCHAR2 C
T2 ID NUMBER

在PL/SQL DEVELOPER工具窗口:
SQL> insert into t2 values(1,’浙江省杭州市江干区下沙’);

insert into t2 values(1,’浙江省杭州市江干区下沙’)
ORA-12899: 列 “BYS”.”T2″.”NAME” 的值太大 (实际值: 11, 最大值: 10)

SQL> insert into t2 values(1,’浙江省杭州市江干区下’);
1 row inserted
SQL> insert into t2 values(1,’浙江省杭州市江干区’);
1 row inserted
SQL> commit;
Commit complete
SQL> select * from t2;
ID NAME
———- —————————————-
1 浙江省杭州市江干区下
1 浙江省杭州市江干区

################################################################
实验3:alter system set nls_length_semantics=char;参数不会对原有的表中varchar2字段的char_used进行修改
SQL> select table_name,column_name,data_type,char_used from dba_tab_columns where table_name=’T1′ or table_name=’T4′ ;
TABLE_NAME COLUMN_NAME DATA_TYPE C
—————————— —————————— ———- –
T4 NAME VARCHAR2 C
T4 ID NUMBER
T1 NAME VARCHAR2 B
T1 ID NUMBER

SQL> alter system set nls_length_semantics=char;
System altered.
SQL> select table_name,column_name,data_type,char_used from dba_tab_columns where table_name=’T1′ or table_name=’T4′ ;
TABLE_NAME COLUMN_NAME DATA_TYPE C
—————————— —————————— ———- –
T1 ID NUMBER
T1 NAME VARCHAR2 B
T4 ID NUMBER
T4 NAME VARCHAR2 C
此时对T1进行插入操作,超过3个汉字会报错
SQL> insert into t1 values(11,’浙江省美’);

insert into t1 values(11,’浙江省美’)

ORA-12899: value too large for column “BYS”.”T1″.”NAME” (actual: 12, maximum: 10)

实验4:测试以SYS用户登陆时不考虑NLS_LENGTH_SEMANTICS参数统一使用BYTE;除非在创建对象等DDL语句中明确定义。
SQL> show user
USER is “SYS”
SQL> show parameter nls_length_semantics;
NAME TYPE VALUE
———————————— ———– ——————————
nls_length_semantics string BYTE
SQL> SQL> alter system set nls_length_semantics=char;
System altered.
SQL> show parameter nls_length_semantics;
NAME TYPE VALUE
———————————— ———– ——————————
nls_length_semantics string CHAR
SQL> create table bys.t8(id number,name varchar2(10));
Table created.
SQL> create table bys.t9(id number,name varchar2(10 char));
Table created.
SQL> col data_type for a10
set linesize 160
SQL> SQL> select table_name,column_name,data_type,char_used from dba_tab_columns where table_name=’T8′ or table_name=’T9′ ;

TABLE_NAME COLUMN_NAME DATA_TYPE C
—————————— —————————— ———- –
T8 ID NUMBER
T8 NAME VARCHAR2 B
T9 ID NUMBER
T9 NAME VARCHAR2 C

##########################################################
实验5:测试ZHS16GBK字符集时一个汉字占的字符数
SQL> select userenv(‘language’) from dual;
USERENV(‘LANGUAGE’)
—————————————————-
AMERICAN_AMERICA.ZHS16GBK
SQL> show user
USER is “BYS”
SQL> show parameter nls_length_semantics;
NAME TYPE VALUE
———————————— ———– ——————————
nls_length_semantics string BYTE
SQL> create table t1(id number,name varchar2(8));
Table created.
SQL> create table t2(id number,name varchar2(8 char));
Table created.

SQL> select table_name,column_name,data_type,char_used from dba_tab_columns where table_name=’T1′ or table_name=’T2′ ;
TABLE_NAME COLUMN_NAME DATA_TYPE C
—————————— —————————— ———- –
T2 NAME VARCHAR2 C
T2 ID NUMBER
T1 NAME VARCHAR2 B
T1 ID NUMBER

SQL> select lengthb(‘白’) from dual;
LENGTHB(‘白’)
————-
2
SQL> insert into t1 values(1,’浙江省杭州’);
insert into t1 values(1,’浙江省杭州’)
ORA-12899: 列 “BYS”.”T1″.”NAME” 的值太大 (实际值: 10, 最大值: 8)
SQL> insert into t1 values(1,’浙江杭州’);
1 row inserted
SQL> insert into t2 values(1,’浙江省杭州市西湖区’);
insert into t2 values(1,’浙江省杭州市西湖区’)
ORA-12899: 列 “BYS”.”T2″.”NAME” 的值太大 (实际值: 9, 最大值: 8)
SQL> insert into t2 values(1,’浙江省杭州市西湖’);
1 row inserted
SQL> commit;
Commit complete

SQL> select * from t1;
ID NAME
———- ——–
1 浙江杭州
SQL> select * from t2;
ID NAME
———- —————-
1 浙江省杭州市西湖

 

验证ORACLE不同字符集中汉字占用的byte及NLS_LENGTH_SEMANTICS参数的影响

近期接连遇到AWR 及STATSPACK的snapshot不能自动生成排查。

STATSPACK的snapshot不能自动生成原因是存放快照的基表:ORA-01631: max # extents (505) reached in table PERFSTAT.STATS$FILESTATXS
AWR不能自动生成快照是因为之前系统进程数达到上限,数据库也HANG住;MMON进程异常;通过os层面kill MMON进程后,数据库实例自动又启动MMON,之后恢复正常。

问题与排查如下:

1.STATSPACK的snapshot不能自动生成排查

ALERT日志中信息:
Mon Apr 4 15:01:00 2016
ORA-1631: max # extents 505 reached in table PERFSTAT.STATS$FILESTATXS
Mon Apr 4 15:01:00 2016
Errors in file /oracle/8.1.7/admin/prod/bdump/snp0_150774_prod.trc:
ORA-12012: error on auto execute of job 403
ORA-01631: max # extents (505) reached in table PERFSTAT.STATS$FILESTATXS
ORA-06512: at “PERFSTAT.STATSPACK”, line 1167
ORA-06512: at “PERFSTAT.STATSPACK”, line 71
ORA-06512: at line 1
Mon Apr 4 17:38:19 2016

查看快照生成情况:

14232 04 Apr 2016 01:00 5
14233 04 Apr 2016 02:00 5
14234 04 Apr 2016 03:00 5

Specify the Begin and End Snapshot Ids
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Enter value for begin_snap:

查看生成快照的JOB的运行情况:
SQL> conn perfstat/perfstat
Connected.
select job,schema_user,to_char(next_date,’yyyy/mm/dd hh24:mi:ss’) as next_D,interval,what from user_jobs;
SQL> SQL>
JOB SCHEMA_USER NEXT_D INTERVAL WHAT
———- ———— —————— ————— ——————–
423 PERFSTAT <span style=”color:#FF0000;”>4000/01/01 </span>00:00:0 trunc(SYSDATE+1 statspack.snap;
0 /24,’HH’)
—-可以看到下次执行是2000年以后。。
SQL> exec dbms_job.remove(423);

PL/SQL procedure successfully completed.

SQL> @?/rdbms/admin/spauto.sql

PL/SQL procedure successfully completed.

Job number for automated statistics collection for this instance
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Note that this job number is needed when modifying or removing
the job:
JOBNO
———-
443

Job queue process
~~~~~~~~~~~~~~~~
Below is the current setting of the job_queue_processes init.ora
parameter – the value for this parameter must be greater
than 0 to use automatic statistics gathering:
NAME TYPE VALUE
———————————— ——- ——————————
job_queue_processes integer 1
Next scheduled run
~~~~~~~~~~~~~~~~~~
The next scheduled run for this job is:

JOB NEXT_DATE NEXT_SEC
———- ——— —————-
443 29-APR-16 11:00:00

SQL> select job,schema_user,to_char(next_date,’yyyy/mm/dd hh24:mi:ss’) as next_D,interval,what from user_jobs;

JOB SCHEMA_USER NEXT_D INTERVAL WHAT
———- ———— —————— ————— ——————–
443 PERFSTAT 2016/04/29 11:00:0 trunc(SYSDATE+1 statspack.snap;
0 /24,’HH’)

这里没有使用扩展表的EXTENT的方式,而是删除旧有的快照信息,删除方法有如下两种:
方法1:删除快照信息:
Oracle还提供了系统脚本用于Truncate这些统计信息表,这个脚本名字是: sptrunc.sql (8i、9i都相同)
该脚本主要内容如下,里面看到的就是statspack相关的所有系统表:

方法2:手动删除指定范围的快照:
删除stats$snapshot数据表中的相应数据,其他表中的数据会相应的级连删除:
SQL> select max(snap_id) from stats$snapshot;
MAX(SNAP_ID)
————
12345

delete from stats$snapshot where snap_id < = 100; —如果一次删除的多,建议分批删除、提交。–我是一次删除500个快照,可以观察到生成REDO较多。
commit;
你可以更改snap_id的范围以保留你需要的数据。
在以上删除过程中,你可以看到所有相关的表都被锁定。

2.到AWR 的snapshot不能自动生成排查

参考文档:Troubleshooting: Missing Automatic Workload Repository (AWR) Snapshots and Other Collection Issues (文档 ID 1301503.1)按顺序进行排查,主要是查看MMON/MMNL进程的TRACE信息,发现其中MMON进程TRACE不存在;手动执行生成快照命令exec dbms_workload_repository.create_snapshot;也无法正常完成,但是未发现相关表是被锁:结合文档 ID 1301503.1中的排查思路进行排查后,惟一存在异常的是MMON进程,然后在OS层面KILL MMON进程,之后实例自动启动MMON,之后可以正常生成快照。

AWR 及STATSPACK的snapshot不能自动生成排查

看到群里有人问普通用户访问基表的问题,测试下如下:

X$基表可以通过创建视图,再对视图创建同义词方式、授权的方式来实现普通用户可以访问基表。

当然了普通用户访基表也是没道理的,理论上没必要,权限控制上也应该是不允许的。此处不考虑合理性,就此问题进行实验。
1.直接对X$基表创建同义词,其它用户无法实现访问。
SQL> show user
USER is “SYS”
SQL> select count(*) from sys.x$kcbwds;

COUNT(*)
———-
8

SQL> CREATE PUBLIC SYNONYM kcbwds FOR sys.x$kcbwds;

Synonym created.

SQL> grant select on sys.x$kcbwds to bys;
grant select on sys.x$kcbwds to bys
*
ERROR at line 1:
ORA-02030: can only select from fixed tables/views
———-
SQL> show user
USER is “BYS”
SQL> select count(*) from sys.x$kcbwds;
select count(*) from sys.x$kcbwds
*
ERROR at line 1:
ORA-00942: table or view does not exist

SQL> select count(*) from kcbwds;
select count(*) from kcbwds
*
ERROR at line 1:
ORA-00942: table or view does not exist

————–

2.使用对X$基表创建视图的方法可以实现普通用户访问X$:
SQL> show user
USER is “SYS”
SQL> select count(*) from x$kcbwds;

COUNT(*)
———-
8
SQL> create view testa as select * from sys.x$kcbwds;

View created.

SQL> grant select on sys.testa to bys;

Grant succeeded.

SQL> conn bys/bys
Connected.
SQL> show user
USER is “BYS”
SQL> select count(*) from sys.testa;

COUNT(*)
———-
8
SQL> desc sys.testa
Name Null? Type
—————————————– ——– —————————-
ADDR RAW(4)
INDX NUMBER
INST_ID NUMBER
SET_ID NUMBER
POOL_ID NUMBER
DBWR_NUM NUMBER
BLK_SIZE NUMBER
后面省略。。。

3.可以通过对视图再加同义词方式来实现更简单的访问
SQL> CREATE PUBLIC SYNONYM testb FOR sys.testa;

Synonym created.

SQL> show user
USER is “SYS”
SQL> conn / as sysdba
Connected.
SQL> conn bys/bys
Connected.
SQL> select count(*) from testb;

COUNT(*)
———-
8

 

通过创建视图及同义词方式实现普通用户查询X$基表的方法