web-dev-qa-db-ja.com

マテリアライズドビューの更新ジョブからのスナップショットが古すぎます

このOracleデータベースには、次のマテリアライズドビュー更新スクリプトを実行するDBMS_JOBがあります。

dbms_refresh.refresh(ABCD.V_POSTAL_CODES);

手で実行すると問題ありませんが、ジョブで実行するとsnapshot too oldが発生します。また、明らかな理由もなく、約1/5の時間で成功します。

問題のエラーは次のとおりです(データベースはフランス語でインストールされています):

ORA-12012: erreur d'exécution automatique du travail 16220
ORA-12008: erreur dans le chemin de régénération de la vue matérialisée
ORA-01555: snapshot too old: rollback segment number 5 with name "_SYSSMU5$" too small
ORA-02063: précédant line de ORA10SRV
ORA-06512: à "SYS.DBMS_SNAPSHOT", ligne 2809
ORA-06512: à "SYS.DBMS_SNAPSHOT", ligne 3025
ORA-06512: à "SYS.DBMS_IREFRESH", ligne 689
ORA-06512: à "SYS.DBMS_REFRESH", ligne 195
ORA-06512: à ligne 1

これは問題のマテリアライズドビューのスクリプトであり、Oracle 10gデータベースへのDB_LINKを呼び出して、ビューのデータを取得します。

CREATE MATERIALIZED VIEW ABCD.V_POSTAL_CODES (CODE_POST)
TABLESPACE TBL_SPC
PCTUSED    0
PCTFREE    10
INITRANS   2
MAXTRANS   255
STORAGE    (
            INITIAL          200K
            NEXT             216K
            MAXSIZE          UNLIMITED
            MINEXTENTS       1
            MAXEXTENTS       UNLIMITED
            PCTINCREASE      0
            BUFFER_POOL      DEFAULT
            FLASH_CACHE      DEFAULT
            CELL_FLASH_CACHE DEFAULT
           )
NOCACHE
LOGGING
NOCOMPRESS
NOPARALLEL
BUILD IMMEDIATE
REFRESH COMPLETE
START WITH TO_DATE('09-12-2016 00:01:00','dd-mm-yyyy hh24:mi:ss')
NEXT TRUNC(SYSDATE) + 1.0007    
WITH PRIMARY KEY
AS 
/* Formatted on 2016-12-08 08:39:50 (QP5 v5.256.13226.35510) */
SELECT DISTINCT postal_code code_post
  FROM t_buildings@ora10srv
 WHERE postal_code IS NOT NULL;

上記のスクリプトの最後の2行目に、dblinkの名前が表示されています。これがdblinkのスクリプトです。

CREATE DATABASE LINK ORA10SRV
 CONNECT TO POST_SCHEMA
 IDENTIFIED BY <PWD>
 USING 'ora10srv.domain.com';

以下は、ビューの更新によってデータが取得されるテーブルのスクリプトです。

CREATE TABLE POST_SCHEMA.T_BUILDINGS
(
  BUILDING_KEY          NUMBER(10)              NOT NULL,
  SEQUENCE              NUMBER(5)               NOT NULL,
  CIVIC_NUMBER          NUMBER(10)              NOT NULL,
  APPART MENT           CHAR(5 CHAR),
  STREET_SERIE          NUMBER(10)              NOT NULL,
  STREET                VARCHAR2(60 CHAR)       NOT NULL,
  POSTAL_CODE           CHAR(7 CHAR),
  STREET_CORNER         CHAR(1 BYTE)            NOT NULL,
  STATUS                CHAR(1 CHAR)            NOT NULL,
  NOTE                  VARCHAR2(100 BYTE),
  SERIAL                NUMBER(10)              DEFAULT 0                     NOT NULL,
  IDE                   NUMBER(10)              NOT NULL
)
TABLESPACE TBL_SPC
PCTUSED    0
PCTFREE    10
INITRANS   1
MAXTRANS   255
STORAGE    (
            INITIAL          504K
            NEXT             7776K
            MINEXTENTS       1
            MAXEXTENTS       UNLIMITED
            PCTINCREASE      0
            BUFFER_POOL      DEFAULT
           )
LOGGING 
NOCOMPRESS 
NOCACHE
NOPARALLEL
MONITORING;

これで、関係するすべてのテーブルとオブジェクトが得られたので、デバッグに関して以下のことを行いました。

  • UNDO_RETENTIONパラメータを高くしすぎたため、邪魔にならない(20000)

  • UNDO表領域を非常に大きくしました。

  • 手でビューをコンパイルしようとしたが、動作します。コンパイルしてコミットしないと、別のセッションから実行しようとすると同様のエラーが発生します。

  • DBMS_REFRESHを取り除き、代わりにDBMS_MVIEW.REFRESHfalseに設定してatomic_refreshを使用しました。

-UNDOテーブルスペースをGUARANTEE RETENTIONに設定します

-参照されている遠隔データベースのテーブルのすべてのインデックスを完全に削除して再作成しました。

それでも、毎晩次のエラーメッセージが表示されます。

ORA-12012: erreur d'exécution automatique du travail 16220
ORA-12008: erreur dans le chemin de régénération de la vue matérialisée
ORA-01555: snapshot too old: rollback segment number 11 with name "_SYSSMU11$" too small
ORA-02063: précédant line de ORA10P
ORA-06512: à "SYS.DBMS_SNAPSHOT", ligne 2809
ORA-06512: à "SYS.DBMS_SNAPSHOT", ligne 3025
ORA-06512: à "SYS.DBMS_SNAPSHOT", ligne 2994
ORA-06512: à ligne 1

OracleでSRを開いてみます。この特定の問題に関してOracleサポートWebサイトで見つけられるものは次のとおりです。

Until a consistent, reproducible test case can be developed in-house this problem remains unresolved.

この問題は根本的な問題を見つけることなく、この時点でクローズされました。問題を一貫して再現するのは簡単ではありません。

4
A_V

ヒント

追加情報を提供するための可能な方法の簡単な要約。

職歴

ジョブ履歴をクエリすると、追加情報が得られる場合があります。

SELECT  /*+ RULE */
    A.JOB JOB#, 
    SCHEMA_USER MVIEW_OWNER,
    substr(DECODE(SUBSTR(WHAT,INSTR(WHAT,'.',1,2)+2,INSTR(WHAT,'”',1,4)-4-INSTR(WHAT,'.',1,2)+2),NULL,SUBSTR(WHAT,1,80), 
    SUBSTR(WHAT,INSTR(WHAT,'.',1,2)+2,INSTR(WHAT,'”',1,4)-4-INSTR(WHAT,'.',1,2)+2)),0,80) JOB_DESCRIPTION,
    to_char(LAST_DATE, 'yyyy-mm-dd hh24:mi:ss') LAST_RUN_DATE, 
    to_char(NEXT_DATE, 'yyyy-mm-dd hh24:mi:ss') NEXT_SCHED_RUN_DATE, 
    DECODE(BROKEN,'Y','YES','N','NO',' ') IS_BROKEN,
    FAILURES,  
    RUNNING IS_RUNNING, 
    B.SID SID 
FROM DBA_JOBS A LEFT OUTER JOIN 
    (SELECT /*+ RULE */ JOB,'YES' RUNNING,SID FROM DBA_JOBS_RUNNING ) B 
ON A.JOB = B.JOB 
ORDER BY SCHEMA_USER, JOB_DESCRIPTION;

参照: 私のマテリアライズドビューの更新が更新されません–パート1

得られる結果によっては、追加情報を探すことができる場合があります。

ロールバックと元に戻す

データベースはロールバック取り消しセグメントで実行されていますか?代わりにUndo Segments(10g +)への切り替えを検討してください。

SMUを有効にするには、UNDO_MANAGEMENTパラメータをTRUEに設定します

どうして?

Oracle Databaseの以前のリリースでは、ロールバック・セグメントを使用してUNDOを格納していました。 Oracle9iは自動UNDO管理を導入しました。これは、ロールバックセグメント管理に関連する複雑さを排除することにより、UNDOスペース管理を簡素化します。 UNDO表領域(自動UNDO管理)を使用して、ロールバックセグメントではなくUNDOを管理することを強くお勧めします(Oracle 9i以降)。

参照: ロールバックと元に戻す表領域の違いは何ですか? 、セクション元に戻すとロールバック

アドバイザーフレームワーク

Undo Segementsモードで実行している場合は、次のスクリプト(Advisor Framework)を使用して、システムからUndo構成に関する助言情報を取得できます。

set serveroutput on

 DECLARE
  v VARCHAR2(300); 
 BEGIN
   v := dbms_undo_adv.undo_advisor(SYSDATE-1/1440, SYSDATE, 1);
   dbms_output.put_line(v);
 END;
 /

参照: Oracle DBMS_UNDO_ADV

データベースに十分なUNDOセグメントがない場合、MVが実行する大量の変更/移動に対応するためにUNDOテーブルスペースのサイズを変更する必要がある場合があります。

2