IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Oracle Discussion :

Snapshot too old lors d'un ajout de colonne


Sujet :

Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Mai 2005
    Messages
    134
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 134
    Par défaut Snapshot too old lors d'un ajout de colonne
    Bonjour,

    Oracle 8.1.7.4 AIX 4.3.3

    J'ai un snapshot too old lors d'un ajout de colonne avec une valeur par défaut.
    Je lance un script PlSQL en étant le seul connecté à la base :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    DECLARE
    	CURSOR cur_usertable IS
    		   SELECT table_name FROM user_tables order by table_name;
     
        	current_table 	 varchar2(30);
     
    	BEGIN
     
    		 OPEN cur_usertable;
     
    		 LOOP
    		 	 FETCH cur_usertable INTO current_table;
    		 	 EXIT WHEN cur_usertable%NOTFOUND;
     
    		 	 EXECUTE IMMEDIATE 'ALTER TABLE ' || current_table || ' ADD LASTARCHIVEWHO  VARCHAR2(30) DEFAULT USER';
    		 	 EXECUTE IMMEDIATE 'ALTER TABLE ' || current_table || ' ADD LASTARCHIVEDATE DATE        DEFAULT SYSDATE';
    		 	 EXECUTE IMMEDIATE 'ALTER TABLE ' || current_table || ' ADD LASTARCHIVESEQ  NUMBER';
     
    		END LOOP;
     
    		CLOSE cur_usertable;
     
    	END;
    /
    il en résulte un ORA-01555.

    J'aurais compris un rollback segment trop petit, mais un 1555 ???

    Avez-vous une idée du pourquoi ce snapshot trop vieux est généré ?

    Merci pour vos réponse.

    Cordialement,

  2. #2
    Membre Expert
    Inscrit en
    Avril 2006
    Messages
    1 024
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 1 024
    Par défaut
    Cette erreur est une faiblesse du système de rollback-segment d'oracle (moi je trouve que c'est carrément un bug mais bon...) elle n'est pas due à un problème de place mais plutot à un problème de nombre de segment. Si tu fais une recherche sur le metalink, tu va tomber sur un article d'oracle te faisant une longue dissertation à ce sujet t'expliquant le fonctionnement des rollback-segments, en particulier le fait que meme apres un commit, le bloc de rollback n'est vraiment libéré qu'au premier select de ce que tu viens de commiter...

    Bref, en gros ce genre d'erreur peut arriver quand on fait :
    - Trop de commit sans jamais faire de select derriere
    - Des commit à l'intérieur d'un curseur qui concerne des données que tu modifie (un mordage de queue quoi...)
    - plein d'autres trucs plus ou moins tordus....

    Il est possible que tu sois dans le 2ieme cas car tu modifie des structures de table, donc le dictionnaire, alors que ton curseur est justement basé sur le dictionnaire. Il faut noter que les modification de structure de font toujours des commit implicites.

    Je serais toi, j'essayerais de recopier le contenu de la vue USER_TABLES dans une table temporaire, et de baser ton curseur sur cette table temporaire...

    bon courage...

  3. #3
    Membre expérimenté
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 178
    Par défaut
    Citation Envoyé par remi4444
    Je serais toi, j'essayerais de recopier le contenu de la vue USER_TABLES dans une table temporaire, et de baser ton curseur sur cette table temporaire...
    Je suppose que par "table temporaire" vous entendez un "CREATE GLOBAL TEMPORARY TABLE...".

    Dans le cas présent, ce script semblant à usage unique, l'utilisation d'une COLLECTION me semble plus appropriée :

    CREATE VARCHAR2_TABLE AS TABLE OF VARCHAR2(500);
    /

    DECLARE

    tables_list varchar2_table;

    BEGIN

    SELECT table_name
    BULK COLLECT INTO tables_list
    FROM user_tables
    ORDER BY table_name;

    FOR i IN 1..tables_list.COUNT LOOP

    EXECUTE IMMEDIATE 'ALTER TABLE ' || tables_list(i) || ' ADD LASTARCHIVEWHO VARCHAR2(30) DEFAULT USER';
    EXECUTE IMMEDIATE 'ALTER TABLE ' || tables_list(i) || ' ADD LASTARCHIVEDATE DATE DEFAULT SYSDATE';
    EXECUTE IMMEDIATE 'ALTER TABLE ' || tables_list(i) || ' ADD LASTARCHIVESEQ NUMBER';

    END LOOP;

    END;
    /
    Cordialement,

    rbaraer

  4. #4
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    remi4444 -> si ton explication est exacte concernant les ROLLBACK SEGMENT (cf http://www.ixora.com.au/tips/admin/ora-1555.htm), ce n'est plus vrai avec un UNDO.
    Dans le cas d'une gestion automatique des rollbacks cette erreur est causé par une réutilisation des blocs du UNDO soit parce que le UNDO est trop petit soit parce que le UNDO_RETENTION n'est pas assez long (attention, si on rallonge UNDO_RETENTION, il faut souvent prévoir un agrandissement du UNDO).

    Donc, avant de répondre à la question, il faudrait connaitre la valeur du paramètre : UNDO_MANAGEMENT.

    Il doit y avoir une autre possibilité en RBS, c'est d'ajouter des segments non ?

    PS : ce serait pas plus simple de spooler le résultat dans un fichier .sql que tu lances ensuite ?

  5. #5
    Membre Expert
    Avatar de LeoAnderson
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 2 938
    Par défaut
    Oracle 8.1.7.4 AIX 4.3.3
    donc, pas de UNDO, c'est bien dommage d'ailleurs !

  6. #6
    Membre Expert
    Inscrit en
    Avril 2006
    Messages
    1 024
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 1 024
    Par défaut
    Citation Envoyé par rbaraer
    Je suppose que par "table temporaire" vous entendez un "CREATE GLOBAL TEMPORARY TABLE...".
    Je n'entendais rien de spécial juste faire les choses en 2 temps, mais effectivment la solution que vous proposez m'a l'air la plus propre puisqu'elle ne fait meme pas appel à un curseur...

    +1

    Citation Envoyé par Fred_D
    Donc, avant de répondre à la question, il faudrait connaitre la valeur du paramètre : UNDO_MANAGEMENT.
    vu la version d'oracle, je crois deviner la réponse... (pour une fois qu'un post est bien rédigé )

    Il doit y avoir une autre possibilité en RBS, c'est d'ajouter des segments non ?
    Dans le cas de traitement de masse oui, mais là j'ai plutot l'impression que c'est un autre problème (un curseur qui tape dans des données modifiées en cours de route) donc j'ai peur que ça ne résolve pas

    PS : ce serait pas plus simple de spooler le résultat dans un fichier .sql que tu lances ensuite ?
    Oui mais on sort du cadre de la pure procédure stockée il faut faire un lancement par le shell. Mais effectivement si ça ne pose pas de problème de faire ainsi, je suis d'accord, c'est le plus simple.

  7. #7
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    au temps pour moi, j'pensais que le UNDO daté de la 8i

    Sinon, le problème vient probablement du nombre de COMMIT. En effet, un DML = un commit si je ne m'abuse.

    Essaye :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    EXECUTE IMMEDIATE 'ALTER TABLE ' || tables_list(i) || ' ADD LASTARCHIVEWHO VARCHAR2(30) DEFAULT USER,LASTARCHIVEDATE DATE DEFAULT SYSDATE, LASTARCHIVESEQ NUMBER';
    une commande au lieu de 3.

Discussions similaires

  1. ORA-01555: Snapshot too old
    Par alicia26 dans le forum Administration
    Réponses: 9
    Dernier message: 10/05/2011, 11h55
  2. Snapshot too old
    Par ilalaina dans le forum Administration
    Réponses: 5
    Dernier message: 24/07/2009, 17h25
  3. Réponses: 10
    Dernier message: 08/06/2009, 16h50
  4. ORA-01555: snapshot too old
    Par skaloup dans le forum Administration
    Réponses: 6
    Dernier message: 13/06/2007, 15h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo