Cette base de données Oracle a un DBMS_JOB qui exécute le script de rafraîchissement de la vue matérialisé suivant:
dbms_refresh.refresh(ABCD.V_POSTAL_CODES);
Si je l'exécute à la main, c'est Finbut si le travail l'exécute un snapshot too old
se produit. Il y aura également environ 1/5 du temps ne réussira-t-il pas à des raisons apparentes.
Voici l'erreur en question (la base de données est installée en français):
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
C'est le script de la vue matérialisée en question, il appelle un db_link à une base de données Oracle 10G pour récupérer les données de la vue:
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;
Vous pouvez voir dans la deuxième dernière ligne du script ci-dessus, le nom du Dblink. Voici le script du Dblink:
CREATE DATABASE LINK ORA10SRV
CONNECT TO POST_SCHEMA
IDENTIFIED BY <PWD>
USING 'ora10srv.domain.com';
Voici le script de la table d'obtenir des données tirées de l'actualisation de la vue.
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;
Donc, maintenant que nous avons toutes les tables et objets impliqués: ce que j'ai fait autant que le débogage est:
Levé le UNDO_RETENTION
Paramètre trop élevé, donc c'est hors de passage (20000)
Fait l'imputant à table d'annulation très grosse.
J'ai essayé de compiler la vue à la main, cela fonctionne. Si j'essaie de le compiler et que vous ne l'engagez pas, cela entraînera une erreur similaire si j'essaie de l'exécuter d'une autre session.
Débarrassé de DBMS_REFRESH
et utilisé DBMS_MVIEW.REFRESH
Au lieu de cela avec atomic_refresh
défini sur false
.
-Le l'époque d'annulation à GUARANTEE RETENTION
-Compatiblement supprimé et recréé tous les index de la table de la base de données distante référencée.
Néanmoins, je reçois les messages d'erreur suivants toutes les nuits:
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
Je vais essayer d'ouvrir un SR avec Oracle. Voici ce que vous pouvez repérer sur le site Web d'assistance Oracle concernant ce problème spécifique:
Until a consistent, reproducible test case can be developed in-house this problem remains unresolved.
Le bogue a été fermé à ce stade sans trouver de problème racine. Le problème n'est pas facile de reproduire de manière cohérente.
Juste un résumé rapide des moyens possibles de vous fournir des informations supplémentaires.
Vous pouvez obtenir des informations supplémentaires si vous interrogez l'historique des tâches:
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;
Référence: Ma vue de rafraîchissement matérialisé n'est pas rafraîchissant - Partie 1
Selon les résultats que vous obtenez, vous pourrez peut-être rechercher des informations supplémentaires.
Votre base de données est-elle en cours d'exécution avec Rollback Undo Segments? Vous voudrez peut-être envisager de passer aux segments annuler à la place (10g +).
Pour activer SMU, définissez le paramètre Undo_Management à true
Pourquoi?
Les versions antérieures de la base de données Oracle utilisaient des segments de restauration pour stocker Annuler. Oracle9i a introduit une gestion automatique des annulations, qui simplifie l'annulation de la gestion de l'espace en éliminant les complexités associées à la gestion des segments de restauration. Oracle recommande fortement (Oracle 9i et sur des mots) d'utiliser Annuler Tablepace (Management automatique des annulations) pour gérer des segments d'annulation plutôt que de retourner.
Référence: Quelle est la différence entre la restauration et l'annulation des espaces de table? , section annuler contre la restauration
Si vous exécutez dans annuler les segments , vous pouvez extraire des informations de conseil sur la configuration des annulations du système avec le script suivant (Cadre de conseiller):
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;
/
Référence: oracle dbms_undo_adv
Si vous trouvez que votre base de données ne dispose pas de suffisamment de segments d'annulation, vous devrez peut-être redimensionner votre espace de table Annuler pour accueillir la grande quantité de modifications/déplacements que votre MV fonctionne.