惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
SegmentFault 最新的问题
博客园 - 三生石上(FineUI控件)
爱范儿
爱范儿
博客园 - 聂微东
V
Visual Studio Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
M
MIT News - Artificial intelligence
The GitHub Blog
The GitHub Blog
Recent Announcements
Recent Announcements
有赞技术团队
有赞技术团队
L
LangChain Blog
I
InfoQ
T
Tailwind CSS Blog
博客园 - 【当耐特】
V
V2EX
博客园_首页
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
GbyAI
GbyAI
Vercel News
Vercel News
雷峰网
雷峰网
量子位
A
About on SuperTechFans
Martin Fowler
Martin Fowler
H
Help Net Security

博客园 - 一江水

什么时候使用绑定变量性能反而更差 模拟登录新浪微博(Python) Oracle ASM 详解 Oracle OS Block Header Oracle如何根据物化视图日志快速刷新物化视图 物化视图注册信息的清除 Oracle RAC 碰到 gc buffer busy Oracle RAC 常用维护工具和命令 RAC Debug开关修改工具 Java连接Sybase ASE数据库的一个简单例子 中文图解Python脚本 解决sybase中文以及大小写问题(服务器端)(utf8 乱码) 如何使Sybase ASE中对象名不区分大小写? 使用 Oracle 数据库 10g内部的 ETL 基础架构 Oracle代理用户(Proxy User) Android系统手机端抓包方法 RAC中如何更改对外网卡和内部互联网卡的IP及VIP ORA-12545: 因目标主机或对象不存在, 连接失败 Oracle数据块损坏恢复总结[转]
物化视图日志没有清除
一江水 · 2012-12-05 · via 博客园 - 一江水

最近在研究物化视图日志的结果,查询了一下系统中物化视图日志的情况,没想到却发现了一个问题:

调用自己写的一个脚本,结果发现个别物化视图日志的数量已经达到了几十万:

SQL> declare
  2  v_output number; 
  3  begin
  4  for c_cursor in (select tname from tab where tname like 'MLOG%') LOOP
  5  execute immediate 'select count(*) from ' || c_cursor.tname into v_output;
  6  dbms_output.put_line(substr(c_cursor.tname, 7) || ' count(*) is ' || v_output);
  7  end loop;
  8  end;
  9  /
CAT_ADMIN count(*) is 0
CAT_AGENT count(*) is 0
CAT_AREA_MEDICARE count(*) is 115416
CAT_AREA_PRICE count(*) is 789700
……
CAT_PRODUCT count(*) is 507262
CAT_PRODUCT_CENTER count(*) is 90945
……
PLT_ORG_PLAT count(*) is 207
PLT_PLAT count(*) is 52
T_DIRECT_SEEDING count(*) is 0
T_INVITE count(*) is 0
T_MARK count(*) is 0
Z_INVITE_COMM_PUB count(*) is 0

PL/SQL procedure successfully completed.

当前查询的站点是主站点,建立了一个主体组。系统中还建立了三个物化视图站点,其中两个刷新全部主体组,一个刷新主体组的一部分。其中两个物化视图刷新组的刷新频率是30分钟,另外一个是1天。因此,物化视图日志中存在少量数据是正常的,但是超过十万条就不正常了。

查询数据量大的一个物化视图日志表,发现物化视图日志中包含着很多以前的数据,时间从2004年8月一直到现在,而物化视图站点最大刷新间隔是1天。

通过查询DBA_BASE_TABLE_VIEWS视图,发现问题:

SQL> SELECT * FROM DBA_BASE_TABLE_MVIEWS WHERE MVIEW_LAST_REFRESH_TIME < TRUNC(SYSDATE);

OWNER   MASTER                         MVIEW_LAST_REFRESH_   MVIEW_ID
------- ------------------------------ ------------------- ----------
NDMAIN  CAT_AREA_MEDICARE              2004-08-08 00:57:26        448
NDMAIN  CAT_AREA_PRICE                 2004-08-08 00:57:26        449
NDMAIN  CAT_AUTH_MEDICARE              2004-08-08 00:57:26        450
NDMAIN  CAT_AUTH_MEDICARE_RELATE_PRODU 2004-08-08 00:57:26        451
NDMAIN  CAT_AUTH_PRICE                 2004-08-08 00:57:26        469
NDMAIN  CAT_BUYER                      2004-08-08 00:57:26        509
NDMAIN  CAT_CATEGORY                   2004-08-08 00:57:26        529
NDMAIN  CAT_DEALER                     2004-08-08 00:57:26        473
NDMAIN  CAT_DOSEAGE_FORM               2004-08-08 00:57:26        454
NDMAIN  CAT_DRUG                       2004-08-08 00:57:26        455
NDMAIN  CAT_ENTERPRISE                 2004-08-08 00:57:26        456
NDMAIN  CAT_ENTERPRISE_PLATCODE        2004-08-08 00:57:26        457
NDMAIN  CAT_FILE_SALER                 2004-08-08 00:57:26        474
NDMAIN  CAT_INVITE_COMM                2004-08-08 00:57:26        489
NDMAIN  CAT_MANUFACTURE                2004-08-08 00:57:26        471
NDMAIN  CAT_METRIC                     2004-08-08 00:57:26        458
NDMAIN  CAT_PRODUCT                    2004-08-08 00:57:26        534
NDMAIN  CAT_PRODUCT_CENTER             2004-08-08 00:57:26        475
NDMAIN  CAT_QUALITY_DEFINE             2004-08-08 00:57:26        461
NDMAIN  CAT_REGION                     2004-08-08 00:57:26        462
NDMAIN  CAT_WRAP                       2004-08-08 00:57:26        472
NDMAIN  MBR_FOOTING_RECORD             2004-08-08 00:57:26        463
NDMAIN  MBR_GRADE                      2004-08-08 00:57:26        464
NDMAIN  MBR_MEMBER                     2004-08-08 00:57:26        465
NDMAIN  MBR_MEMBER_ITEM                2004-08-08 00:57:26        466
NDMAIN  PLT_ORG_PLAT                   2004-08-08 00:57:26        467
NDMAIN  PLT_PLAT                       2004-08-08 00:57:26        468

27 rows selected.

这些物化视图的查询上次刷新时间是04年8月,而且也正是这些物化视图的物化视图日志数据量异常。

继续查询,又发现问题:

SQL> SELECT * FROM DBA_BASE_TABLE_MVIEWS WHERE MASTER = 'CAT_PRODUCT';

OWNER   MASTER                         MVIEW_LAST_REFRESH_   MVIEW_ID
------- ------------------------------ ------------------- ----------
NDMAIN  CAT_PRODUCT                    2004-08-08 00:57:26        534
NDMAIN  CAT_PRODUCT                    2005-02-28 01:05:59        560
NDMAIN  CAT_PRODUCT                    2005-02-28 13:34:42        676
NDMAIN  CAT_PRODUCT                    2005-02-28 14:08:46        530

居然有四个物化视图定义在物化视图组上,看来是其中一个一直没有刷新,难怪造成了这个问题。

SQL> SELECT OWNER, NAME, MVIEW_SITE, MVIEW_ID FROM DBA_REGISTERED_MVIEWS 
  2  WHERE NAME = 'CAT_PRODUCT';

OWNER   NAME            MVIEW_SITE                  MVIEW_ID
------- --------------- ------------------------- ----------
NDMAIN  CAT_PRODUCT     REPDB01.US.ORACLE.COM            560
NDMAIN  CAT_PRODUCT     BJDB01.US.ORACLE.COM             530
NDMAIN  CAT_PRODUCT     ZJTRADE.US.ORACLE.COM            676

可是查询已注册的物化视图却只发现三个,看来原因就出在多出的那个物化视图身上。

其中一个物化视图站点在去年8月的时候进行过升级,整个数据库EXP,导入到一个新的服务器上,并重建了物化视图站点。看来现在的问题是由于上次没有将物化视图环境清除干净。

物化视图以前已经进行了UNREGISTERED_MVIEW_GROUP的操作,只需要执行PURGE_MVIEW_FROM_LOG过程就行了。

PURGE_MVIEW_FROM_LOG过程进行了重载,可以输入MVIEW_ID或输入MVIEWOWNER、MVIEWNAME、MVIEWSITE。由于MVIEWSITE现在已经被重复使用,因此只能通过MVIEW_ID的方式。

SQL> SELECT * FROM DBA_BASE_TABLE_MVIEWS WHERE MASTER = 'CAT_PRODUCT';

OWNER   MASTER                         MVIEW_LAST_REFRESH_   MVIEW_ID
------- ------------------------------ ------------------- ----------
NDMAIN  CAT_PRODUCT                    2004-08-08 00:57:26        534
NDMAIN  CAT_PRODUCT                    2005-02-28 01:05:59        560
NDMAIN  CAT_PRODUCT                    2005-02-28 14:08:46        530
NDMAIN  CAT_PRODUCT                    2005-02-28 14:34:39        676

SQL> SELECT COUNT(*) FROM NDMAIN.MLOG$_CAT_PRODUCT;

  COUNT(*)
----------
    507347

SQL> EXEC DBMS_MVIEW.PURGE_MVIEW_FROM_LOG(534)

PL/SQL procedure successfully completed.

SQL> COMMIT;

Commit complete.

SQL> SELECT * FROM DBA_BASE_TABLE_MVIEWS WHERE MASTER = 'CAT_PRODUCT';

OWNER   MASTER                         MVIEW_LAST_REFRESH_   MVIEW_ID
------- ------------------------------ ------------------- ----------
NDMAIN  CAT_PRODUCT                    2005-02-28 01:05:59        560
NDMAIN  CAT_PRODUCT                    2005-02-28 14:08:46        530
NDMAIN  CAT_PRODUCT                    2005-02-28 14:34:39        676

SQL> SELECT COUNT(*) FROM NDMAIN.MLOG$_CAT_PRODUCT;

  COUNT(*)
----------
       236

通过执行PURGE_MVIEW_FROM_LOG过程,DBA_BASE_TABLE_MVIEWS视图中的结果和MLOG中的数量都恢复正常。

SQL> begin
  2  for i in (select mview_id from dba_base_table_mviews where mview_last_refresh_time < trunc(sysdate)) loop
  3  dbms_mview.purge_mview_from_log(i.mview_id);
  4  end loop;
  5  commit;
  6  end;
  7  /

PL/SQL procedure successfully completed.

http://yangtingkun.itpub.net/post/468/19939