物化视图注册信息的清除

物化视图注册信息的清除


物化视图的日志清除是由Oracle自动完成的。Oracle会根据物化视图基表上的注册信息和物化视图的刷新来确定何时删除物化视图日志。
物化视图的注册信息的清除则是在删除物化视图的时候进行,但是对于物化视图建立在远端数据库中的情况,物化视图注册信息的清除可能会复杂一些。

如果物化视图建立在本地,则Oracle拥有所有的数据字典信息,因此,本篇所有的测试都是针对远端物化视图进行的。
首先来看清除物化视图日志的例子。这个操作完全有Oracle进行,即使用户没有物化视图日志的DELETE权限也没有关系。
首先,登陆远端数据库建立测试所用基表和物化视图日志:
SQL> CONN [email=TEST/TEST@TEST2]TEST/TEST@TEST2[/email]已连接。
SQL> CREATE TABLE T1 (ID NUMBER PRIMARY KEY);
表已创建。
SQL> CREATE MATERIALIZED VIEW LOG ON T1;
实体化视图日志已创建。
下面在本地建立数据库链和物化视图:
SQL> CONN USERA/USERA已连接。
SQL> CREATE DATABASE LINK TEST2 CONNECT TO TEST IDENTIFIED BY TEST USING 'TEST2';
数据库链接已创建。
SQL> CREATE MATERIALIZED VIEW MV_TEST REFRESH FAST AS SELECT * FROM [email=T1@TEST2]T1@TEST2[/email];
实体化视图已创建。
下面开始测试:
SQL> INSERT INTO [email=T1@TEST2]T1@TEST2[/email] VALUES (1);
已创建 1 行。
SQL> COMMIT;
提交完成。
SQL> SELECT COUNT(*) FROM [email=MLOG$_T1@TEST2]MLOG$_T1@TEST2[/email];
COUNT(*)
----------
1
SQL> EXEC DBMS_MVIEW.REFRESH('MV_TEST')
PL/SQL 过程已成功完成。
SQL> SELECT COUNT(*) FROM [email=MLOG$_T1@TEST2]MLOG$_T1@TEST2[/email];
COUNT(*)
----------
0
可见,物化视图日志在物化视图刷新后自动清除了。不过由于数据库链的连接用户是TEST拥有对MLOG$_T1的删除权限。下面建立一个新的用户,只给MLOG$_T1的查询权限:
SQL> CONN [email=TEST/TEST@TEST2]TEST/TEST@TEST2[/email]已连接。
SQL> CREATE USER AAA IDENTIFIED BY AAA;
用户已创建。
SQL> GRANT CONNECT, RESOURCE TO AAA;
授权成功。
SQL> GRANT SELECT ON T1 TO AAA;
授权成功。
SQL> GRANT SELECT ON MLOG$_T1 TO AAA;
授权成功。
由于我本地数据库的GLOBAL_NAMES设置为FALSE,因此可以建立另一个不同用户的数据库链指向TEST2库。
SQL> CONN USERA/USERA已连接。
SQL> SHOW PARAMETER GLOBAL_NAMES
NAME TYPE VALUE
------------------------------------ ----------- ----------------------
global_names boolean FALSE
SQL> DROP MATERIALIZED VIEW MV_TEST;
实体化视图已删除。
SQL> CREATE DATABASE LINK TEST2_NEW CONNECT TO AAA IDENTIFIED BY AAA USING 'TEST2';
数据库链接已创建。
SQL> SELECT COUNT(*) FROM [email=TEST.T1@TEST2_NEW]TEST.T1@TEST2_NEW[/email];
COUNT(*)
----------
1
SQL> CREATE MATERIALIZED VIEW MV_TEST2 REFRESH FAST AS SELECT * FROM [email=TEST.T1@TEST2_NEW]TEST.T1@TEST2_NEW[/email];
实体化视图已创建。
SQL> INSERT INTO [email=T1@TEST2]T1@TEST2[/email] VALUES (2);
已创建 1 行。
SQL> SELECT COUNT(*) FROM [email=MLOG$_T1@TEST2]MLOG$_T1@TEST2[/email];
COUNT(*)
----------
1
SQL> EXEC DBMS_MVIEW.REFRESH('MV_TEST2')
PL/SQL 过程已成功完成。
SQL> SELECT COUNT(*) FROM [email=MLOG$_T1@TEST2]MLOG$_T1@TEST2[/email];
COUNT(*)
----------
0
可见,物化视图日志的清除完全是Oracle的内容操作,与用户的权限没有关系。
物化视图日志的清除依赖于物化视图的注册信息,那么物化视图的注册信息的清除呢:
SQL> SELECT OWNER, NAME, MVIEW_SITE, MVIEW_ID
2 FROM [email=USER_REGISTERED_MVIEWS@TEST2]USER_REGISTERED_MVIEWS@TEST2[/email];
OWNER NAME MVIEW_SITE MVIEW_ID
---------- -------------------- ------------------------------ ----------
USERA MV_TEST2 YTK.US.ORACLE.COM 64
SQL> DROP MATERIALIZED VIEW MV_TEST2;
实体化视图已删除。
SQL> SELECT OWNER, NAME, MVIEW_SITE, MVIEW_ID
2 FROM [email=USER_REGISTERED_MVIEWS@TEST2]USER_REGISTERED_MVIEWS@TEST2[/email];
未选定行
通过测试不难发现在删除物化视图时,Oracle自动将删除的消息传递到主站点,主站点同时清除物化视图的注册信息。
就是这么简单吗,是的。不过前提是创建物化视图时使用的数据库链存在且可用。
如果删除这个数据库链:
SQL> CREATE MATERIALIZED VIEW MV_TEST2 REFRESH FAST AS SELECT * FROM [email=TEST.T1@TEST2_NEW]TEST.T1@TEST2_NEW[/email];
实体化视图已创建。
SQL> SELECT OWNER, NAME, MVIEW_SITE, MVIEW_ID
2 FROM [email=USER_REGISTERED_MVIEWS@TEST2]USER_REGISTERED_MVIEWS@TEST2[/email];
OWNER NAME MVIEW_SITE MVIEW_ID
---------- -------------------- ------------------------------ ----------
USERA MV_TEST2 YTK.US.ORACLE.COM 65
SQL> DROP DATABASE LINK TEST2_NEW;
数据库链接已删除。
SQL> DROP MATERIALIZED VIEW MV_TEST2;
实体化视图已删除。
SQL> SELECT OWNER, NAME, MVIEW_SITE, MVIEW_ID
2 FROM [email=USER_REGISTERED_MVIEWS@TEST2]USER_REGISTERED_MVIEWS@TEST2[/email];
OWNER NAME MVIEW_SITE MVIEW_ID
---------- -------------------- ------------------------------ ----------
USERA MV_TEST2 YTK.US.ORACLE.COM 65
在删除数据库链之后删除物化视图,删除物化视图的动作本身并不会报错,但是主站点的物化视图日志不会被清除。
另外Oracle没有聪明到利用其它的等价数据库链的地步,它只会使用物化视图定义中指定的那个数据库链。
下面继续观察物化视图日志的清除情况:
SQL> INSERT INTO [email=T1@TEST2]T1@TEST2[/email] VALUES (3);
已创建 1 行。
SQL> COMMIT;
提交完成。
SQL> SELECT COUNT(*) FROM [email=MLOG$_T1@TEST2]MLOG$_T1@TEST2[/email];
COUNT(*)
----------
1
由于物化视图注册信息的存在,物化视图
下面重建数据库链和刚才删除的物化视图:
SQL> CREATE DATABASE LINK TEST2_NEW CONNECT TO AAA IDENTIFIED BY AAA USING 'TEST2';
数据库链接已创建。
SQL> CREATE MATERIALIZED VIEW MV_TEST2 REFRESH FAST AS SELECT * FROM [email=TEST.T1@TEST2_NEW]TEST.T1@TEST2_NEW[/email];
实体化视图已创建。
SQL> SELECT OWNER, NAME, MVIEW_SITE, MVIEW_ID
2 FROM [email=USER_REGISTERED_MVIEWS@TEST2]USER_REGISTERED_MVIEWS@TEST2[/email];
OWNER NAME MVIEW_SITE MVIEW_ID
---------- -------------------- ------------------------------ ----------
USERA MV_TEST2 YTK.US.ORACLE.COM 66
SQL> SELECT COUNT(*) FROM [email=MLOG$_T1@TEST2]MLOG$_T1@TEST2[/email];
COUNT(*)
----------
1
由于OWNER、NAME和MVIEW_SITE等信息完全一样,Oracle没有建立新的注册信息,而是更新了注册信息,物化视图的ID由原来的65变成了66。
但是这次物化视图的创建并没有清掉物化视图日志。
而且后续的刷新操作也无法清除掉物化视图日志:
SQL> INSERT INTO [email=T1@TEST2]T1@TEST2[/email] VALUES (4);
已创建 1 行。
SQL> COMMIT;
提交完成。
SQL> SELECT COUNT(*) FROM [email=MLOG$_T1@TEST2]MLOG$_T1@TEST2[/email];
COUNT(*)
----------
2
SQL> EXEC DBMS_MVIEW.REFRESH('MV_TEST2')
PL/SQL 过程已成功完成。
SQL> SELECT COUNT(*) FROM [email=MLOG$_T1@TEST2]MLOG$_T1@TEST2[/email];
COUNT(*)
----------
2
这时候物化视图日志已经无法正常的清除了。虽然通过删除物化视图的办法可以去掉注册信息,但是仍然不能解决物化视图日志无法被清除的问题。
SQL> DROP MATERIALIZED VIEW MV_TEST2;
实体化视图已删除。
SQL> SELECT OWNER, NAME, MVIEW_SITE, MVIEW_ID
2 FROM [email=USER_REGISTERED_MVIEWS@TEST2]USER_REGISTERED_MVIEWS@TEST2[/email];
未选定行
SQL> CREATE MATERIALIZED VIEW MV_TEST2 REFRESH FAST AS SELECT * FROM [email=TEST.T1@TEST2_NEW]TEST.T1@TEST2_NEW[/email];
实体化视图已创建。
SQL> INSERT INTO [email=T1@TEST2]T1@TEST2[/email] VALUES (5);
已创建 1 行。
SQL> COMMIT;
提交完成。
SQL> SELECT COUNT(*) FROM [email=MLOG$_T1@TEST2]MLOG$_T1@TEST2[/email];
COUNT(*)
----------
3
SQL> EXEC DBMS_MVIEW.REFRESH('MV_TEST2')
PL/SQL 过程已成功完成。
SQL> SELECT COUNT(*) FROM [email=MLOG$_T1@TEST2]MLOG$_T1@TEST2[/email];
COUNT(*)
----------
3
SQL> SELECT OWNER, NAME, MVIEW_SITE, MVIEW_ID
2 FROM [email=USER_REGISTERED_MVIEWS@TEST2]USER_REGISTERED_MVIEWS@TEST2[/email];
OWNER NAME MVIEW_SITE MVIEW_ID
---------- -------------------- ------------------------------ ----------
USERA MV_TEST2 YTK.US.ORACLE.COM 67
查询USER_BASE_TABLE_MVIEWS视图可以发现,MVIEW_ID为65的信息并没有清除掉。
SQL> SELECT OWNER, MASTER, MVIEW_ID FROM [email=USER_BASE_TABLE_MVIEWS@TEST2]USER_BASE_TABLE_MVIEWS@TEST2[/email];
OWNER MASTER MVIEW_ID
---------- ------------------------------ ----------
TEST T1 65
TEST T1 67
现在问题就和以前碰到的一个物化视图日志没有清除的情况完全一样了。
不过区别在于,一个是由于数据库损坏重建造成的,而本例中仅仅是由于在删除物化视图之前删除了数据库链。
下面在远端数据库直接清除MVIEW_ID为65的信息就可以了:
SQL> EXEC [email=DBMS_MVIEW.PURGE_MVIEW_FROM_LOG@TEST2(65]DBMS_MVIEW.PURGE_MVIEW_FROM_LOG@TEST2(65[/email])
PL/SQL 过程已成功完成。
SQL> SELECT COUNT(*) FROM [email=MLOG$_T1@TEST2]MLOG$_T1@TEST2[/email];
COUNT(*)
----------
0

 

 

转载自:http://itjaj.com/thread-2955-1-5.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值