この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.REFRESH
をfalse
に設定して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.
この問題は根本的な問題を見つけることなく、この時点でクローズされました。問題を一貫して再現するのは簡単ではありません。
追加情報を提供するための可能な方法の簡単な要約。
ジョブ履歴をクエリすると、追加情報が得られる場合があります。
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;
/
データベースに十分なUNDOセグメントがない場合、MVが実行する大量の変更/移動に対応するためにUNDOテーブルスペースのサイズを変更する必要がある場合があります。