web-dev-qa-db-ja.com

マテリアライズドビューが無効になり、USER_MVIEWS.COMPILE_STATEが「NEEDS_COMPILE」になります

Oracle(11.2.0.4)マテリアライズドビューからデータを取得しているアプリケーションがあります。関連するテーブルまたは関連付けられたオブジェクトでDMLアクションが発生すると、マテリアライズドビューの動作が無効になります。

私のマテリアライズドビューの候補は以下のとおりであり、関連するオブジェクトが常に有効であることを確認しています。

CREATE materialized VIEW mv_emp_test1 
NOLOGGING COMPRESS build IMMEDIATE 
REFRESH FORCE 
START WITH (SYSDATE) NEXT (SYSDATE+5/1024)
as
......

マテリアライズドビューは、5分ごとに更新されるとINVALID状態になり、次のいずれかの方法が適用されると有効になります。

alter materialized view mv_emp_test1 recompile;
or
exec dbms_mview.refresh('mv_emp_test1');

また、関連ドキュメントとバグを確認しました。metalinkのDoc ID 264036.1には正確なシナリオが含まれていますが、適切な回避策が見つからなかったため、5分ごとに自動更新されます。

1
Suresh Gautam

それが予想される動作です。

ベーステーブルのデータが変更され、ビューが最新ではなくなった場合、ステータスは無効になります。再コンパイルまたは更新すると、最新の状態になり、再び有効になります。したがって、ビューの無効な状態を気にする必要はありません。

この質問はすでにstackoverfow.comで提起されており、 Andrew Brennan によって回答されています。

MOS Doc ID 264036.1を参照してください:

MVに関連する依存関係は自動的に維持され、正しく動作します。 MVが作成されると、マテリアライズドビューはその定義で参照されるマスターテーブルに依存します。マテリアライズドビューの依存関係に対するINSERT、DELETE、UPDATE、DDL操作などのDML操作は、無効になります。

3
miracle173

マテリアライズドビューの背後にある全体的なアイデアは、ビューでデータを「利用可能」にすることであり、たとえばリモートの場所など、基礎となるテーブルからデータを取得する必要はありません。データまたはテーブル定義が変更されると、MVはINVALIDになります。

マテリアライズドビュー

(以前のバージョンではスナップショットと呼ばれていました)

マテリアライズドビューの定義は、元のドキュメントにあります:

同期レプリケーション

最新のデータを取得する場合は、通常のビューまたは同期レプリケーションの使用を検討してください。

参考文献:

3

マテリアライズドビューを自動的に更新する場合は、 JOB_QUEUE_PROCESSES を1以上の値に設定する必要があります。

おそらくジョブキュープロセスが不足していますか?

SQL> alter system set job_queue_processes=0;

System altered.

SQL> select * from test;

    ID
----------
     1
     2
     3
     4


SQL> Create Materialized view test_mv 
refresh complete 
start with (sysdate) 
next (sysdate+1/1440) 
with rowid 
as 
select * from test;   

Materialized view created.

SQL> select compile_state from dba_mviews where mview_name='TEST_MV';

COMPILE_STATE
-------------------
VALID

SQL> select * from test_mv;

    ID
----------
     1
     2
     3
     4


SQL> insert into test values(5);

1 row created.

SQL> commit;

Commit complete.

SQL> select compile_state from dba_mviews where mview_name='TEST_MV';

COMPILE_STATE
-------------------
NEEDS_COMPILE

1分間お待ちください...

SQL> select * from test_mv;

    ID
----------
     1
     2
     3
     4

変更はまだ反映されていません。

SQL> exec dbms_mview.refresh('TEST_MV');

PL/SQL procedure successfully completed.

SQL> select compile_state from dba_mviews where mview_name='TEST_MV';

COMPILE_STATE
-------------------
VALID

現在、これは有効な状態です。

他の人が述べたように、NEEDS_COMPILE状態になるのはMVの予想される動作です。ただし、MVは5分間隔で自動的に更新されます。

SQL> alter system set job_queue_processes=1000;

System altered.

SQL> select compile_state from dba_mviews where mview_name='TEST_MV';

COMPILE_STATE
-------------------
VALID

SQL> insert into test values(6);

1 row created.

SQL> commit;

Commit complete.

SQL> select compile_state from dba_mviews where mview_name='TEST_MV';

COMPILE_STATE
-------------------
NEEDS_COMPILE

ちょっと待って...

SQL> /

COMPILE_STATE
-------------------
VALID

有効になりました。

2
JSapkota