RAC环境碰到ORA-4063错误

RAC环境中,查询一个视图出现了ORA-4063错误。

 

 

错误出现时的现象如下:

SQL> select * from v1;
select * from v1
              *
1 行出现错误:
ORA-04063: view "U1.V1"
有错误


SQL> set long 1000
SQL> select text from user_views where view_name = 'V1';

TEXT
--------------------------------------------------------------------------------
select t1.id id1, t2.id id2
from t1, t2
where t1.id = t2.id


SQL> create or replace view v1 as
  2  select t1.id id1, t2.id id2
  3  from t1, t2
  4  where t1.id = t2.id
  5  ;

视图已创建。

SQL> select * from v1;

未选定行

由于对视图的基表进行过重建的操作,因此很可能是这个原因导致了视图的错误。但是奇怪的是:为了获取视图错误的信息,而尝试重新创建视图时,错误却消失了。

Oracle对于ORA-4063错误的描述:

ORA-04063: %s has errors
Cause: Attempt to execute a stored procedure or use a view that has errors. For stored procedures, the problem could be syntax errors or references to other, non-existent procedures. For views, the problem could be a reference in the view’s defining query to a non-existent table. Can also be a table which has references to non-existent or inaccessible types.
Action: Fix the errors and/or create referenced objects as necessary

如果错误和Oracle文档中描述的一致,那么导致视图报错的原因就是视图所访问的表不存在,如果是这个错误的话那么没有道理可以通过重建视图来解决错误。

感觉是碰到了Oraclebug,经过不断的尝试,最终重现了这个问题。

下面是问题重现的步骤:

SQL> select instance_name from v$instance;

INSTANCE_NAME
----------------
testrac2

SQL> create user u1 identified by u1 default tablespace users;

用户已创建。

SQL> create user u2 identified by u2 default tablespace users;

用户已创建。

SQL> grant create session, create view, create synonym to u1;

授权成功。

SQL> grant create session, create synonym to u2;

授权成功。

SQL> conn test/test
已连接。
SQL> create table t1 (id number);

表已创建。

SQL> create table t2 (id number);

表已创建。

SQL> grant select on t1 to u1 with grant option;

授权成功。

SQL> grant select on t2 to u1 with grant option;

授权成功。

SQL> conn u1/u1
已连接。
SQL> create synonym t1 for test.t1;

同义词已创建。

SQL> create synonym t2 for test.t2;

同义词已创建。

SQL> create view v1 as select t1.id id1, t2.id id2
  2  from t1, t2
  3  where t1.id = t2.id;

视图已创建。

SQL> create view v2 as select t1.id id1, t2.id id2
  2  from t1, t2
  3  where t1.id = t2.id;

视图已创建。

SQL> grant select on v1 to u2;

授权成功。

SQL> grant select on v2 to u2;

授权成功。

检查描述一下上面的测试步骤:在RAC环境的一个实例上,创建两个辅助用户,并给这两个辅助用户授权必要的权限。在TEST用户中建立两个基表,将基表的SELECT WITH GRANT OPTION权限授权给U1用户,U1用户建立同名同义词指向这两个基表,而后建立两个相同的视图访问这两个基表,并将这两个视图的查询权限授予用户U2

SQL> conn u2/u2
已连接。
SQL> select instance_name from v$instance;

INSTANCE_NAME
----------------
testrac1

SQL> create synonym v1 for u1.v1;

同义词已创建。

SQL> create synonym v2 for u1.v2;

同义词已创建。

SQL> select * from v1;

未选定行

SQL> select * from v2;

未选定行

RAC的实例1上以U2用户建立连接并建立了同义词指向U1的视图,并通过同义词访问U1的视图。

下面回到实例2上,删除并重建TEST用户下的基表T1

SQL> conn test/test
已连接。
SQL> drop table t1 purge;

表已删除。

SQL> create table t1 (id number);

表已创建。

然后回到实例1上,使用U2用户查询V1视图:

SQL> select * from v1;
select * from v1
              *
1 行出现错误:
ORA-04063: view "U1.V1"
有错误

这里报错是正常的,因为还没有给U1用户授权:

回到实例2,只给U1授权SELECTU1拥有查询权限,但是U1不能将这个表的访问权限权限授予其他用户:

SQL> grant select on t1 to u1;

授权成功。

回到实例1U2用户再次运行查询:

SQL> select * from v1;
select * from v1
              *
1 行出现错误:
ORA-04063: view "U1.V1"
有错误

还是相同的错误,但是问题已经产生了。因为对于单实例数据库而言,同样的操作应该报错ORA-3113,指出U2没有访问对象V1的权限,而不是出现ORA-4063错误。

回到实例2,检查U1用户下的视图状态:

SQL> conn u1/u1
已连接。
SQL> select object_name, object_type, status
  2  from user_objects 
  3  where object_name like 'V_';

OBJECT_NAME                    OBJECT_TYPE         STATUS
------------------------------ ------------------- -------
V1
                             VIEW                INVALID
V2
                             VIEW                INVALID

视图V1的状态是不正确的,如果是在单实例环境下进行测试,到这一步会发现V1的状态是VALID。因为U1已经有了访问T1的权限,而U2又尝试访问V1视图,在发现视图状态不正确后会尝试编译V1。虽然由于U1用户缺少SELECT WITH GRANT OPTION权限,使得U2用户没有权限访问V1视图,但是V1视图本身的编译不会报错。

切换到test用户,这次将GRANT权限也授权给U1用户:

SQL> conn test/test
已连接。
SQL> grant select on t1 to u1 with grant option;

授权成功。

在实例1上,U2用户再次访问V1视图:

SQL> select * from v1;
select * from v1
              *
1 行出现错误:
ORA-04063: view "U1.V1"
有错误


SQL> select * from v2;

未选定行

访问V1仍然报错,但是之前没有访问过的V2视图,在查询时没有报错。这时即使是U1本身去访问V1视图也会报错ORA-4063

SQL> conn test/test
已连接。
SQL> select * from v1;
select * from v1
              *
1 行出现错误:
ORA-04063: view "U1.V1"
有错误

问题重现了。这个问题在RAC环境下才会出现,当授权操作和用户访问不再同一个实例上,由于Oraclebug致使用户访问对象时没有检测到正确的权限,导致了视图状态的错误。

测试还发现造成BUG的几个必要条件:

U2用户在T1被删除后且还没有将权限授权给U1用户时,执行查询;

仅将T1的查询权限授权给U1,而没有授权WITH GRANT OPTION

U2用户再次执行查询,且在授权和U2用户执行查询之间,U1用户没有执行过查询;

确保授权操作和U2查询操作处于RAC数据库的不同实例。

满足了这些条件,问题就可能会重现。

感觉问题产生的原因可能和下面两个BUG有一定的关系:

一次ORA-942错误的跟踪(一):http://yangtingkun.itpub.net/post/468/480559

一次ORA-942错误的跟踪(二):http://yangtingkun.itpub.net/post/468/480671

一次ORA-942错误的跟踪(三):http://yangtingkun.itpub.net/post/468/480744

一次ORA-942错误的跟踪(四):http://yangtingkun.itpub.net/post/468/480825

一次ORA-942错误的跟踪(五):http://yangtingkun.itpub.net/post/468/480896

RAC环境一个实例删除已被另一个实例删除的表时报错:http://yangtingkun.itpub.net/post/468/316777

问题解决倒是很简单,除了前面的重建视图外,重新编译视图也可以解决问题:

SQL> alter view v1 compile;

视图已变更。

SQL> select * from v1;

未选定行

根据上面的描述可以看到,这个bug出现的条件十分严格,在实际情况中碰到这个bug的可能性很小,而且解决起来也很容易。有人可能认为这个bug不用理会,但是对于一个DBA来说,应该搞清楚bug出现的原因以及这个bug的危害,如果不深入的分析怎么判断这个bug重现的可能性的大小以及bug对系统的影响呢。

没有人能解决所有碰到的问题,但是一个合格的DBA应该可以独立解决大部分碰到的问题。解决问题的能力并不是天生的,随着知识和经验的不断积累,解决问题的能力会不断的增强。知识积累可以通过学习文档获得,而经验的积累就需要在分析、解决问题的过程中获得。因此不要轻易放过任何一个问题,每个问题都是一个积累经验的机会。

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/4227/viewspace-611706/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/4227/viewspace-611706/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值