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

Administration Oracle Discussion :

Purger une base, quelle solution ?


Sujet :

Administration Oracle

  1. #21
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2003
    Messages : 92
    Points : 48
    Points
    48
    Par défaut
    Salut à tous


    Alors j'ai fait des tests avec le dbms_redefinition comme vous le suggériez mais pour l'instant juste avec une table (la premier dans l'ordre de suppression).

    Après l'avoir redéfini en table partition (je mettrai la procédure une fois validée si cela intéresse quelqu'un), j'ai donc supprimé les partitions qui contenait les données inférieur à 2010.

    Or je constate que :
    - quand je fait un count sur les données inférieur a 2010, ca prend du temps pour trouver 0 enregistrement .... problème du HWM ?

    - Malgré la suppression des dites partitions, aucun gain d'espace au niveau du tablespace... pire même, on ne récupére l'espace utilisé lors de la redéfinition ?

    Qu'en pensez vous, y a t il des opérations supplémentaire à faire pour ces deux cas ?

    Par la suite, il faudra que je valide, comme le disait Mohamed.Houri, les performances de la base, et etre sur que mes plans d'execution ne sont affecté par cette opération
    It's me !!

  2. #22
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2003
    Messages : 92
    Points : 48
    Points
    48
    Par défaut
    Citation Envoyé par elkamaro Voir le message
    - quand je fait un count sur les données inférieur a 2010, ca prend du temps pour trouver 0 enregistrement .... problème du HWM ?
    Erreur de ma part pour cette remarque, il n'y pas de lenteur sur ça.
    It's me !!

  3. #23
    Membre actif Avatar de olivanto
    Responsable d'exploitation informatique
    Inscrit en
    Mars 2005
    Messages
    513
    Détails du profil
    Informations professionnelles :
    Activité : Responsable d'exploitation informatique
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2005
    Messages : 513
    Points : 204
    Points
    204
    Par défaut
    Citation Envoyé par elkamaro Voir le message
    Salut à tous


    Alors j'ai fait des tests avec le dbms_redefinition comme vous le suggériez mais pour l'instant juste avec une table (la premier dans l'ordre de suppression).

    Après l'avoir redéfini en table partition (je mettrai la procédure une fois validée si cela intéresse quelqu'un)
    intéréssé ::
    apprenti sorcier Oracle & boulet intérimaire...
    http://www.courtois.cc/murphy/murphy_informatique.html

  4. #24
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2003
    Messages : 92
    Points : 48
    Points
    48
    Par défaut
    Citation Envoyé par olivanto Voir le message
    intéréssé ::
    Aprés avoir lu plusieurs sujet en anglais et aussi cette page de developpez et surtout en espérant que j'ai rien oublié :

    Alors pour redéfinir une table afin d'y ajouter des partitions :


    1-Vérifier que la table peut effectivement être redéfinie en ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    exec dbms_redefinition.can_redef_table( 'SCOTT', 'TABLE1' );
    cette procédure m'avait renvoyé une erreur ORA-12091 que j'ai corrigé avec ca : clique ici

    2- Grant à l'utilisateur de la table
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    grant execute on dbms_redefinition to scott ;
    grant dba to SCOTT;
    3- Créer une table intérimaire à l'image de la table qu'on veut redéfinir on y ajoutant les partitions qu'on veut
    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
     
    CREATE TABLE TABLE1_TEMP
    (
      NUMERO                  NUMBER(10)        NOT NULL,
      CODE                   VARCHAR2(3 BYTE)  NOT NULL,
      DATEMAJ                 DATE              DEFAULT sysdate               NOT NULL
    )
    PARTITION BY RANGE (DATEMAJ) (
      PARTITION P_2006 VALUES LESS THAN (TO_DATE('2007-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS')),
      PARTITION P_2007 VALUES LESS THAN (TO_DATE('2008-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS')),
      PARTITION P_2008 VALUES LESS THAN (TO_DATE('2009-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS')),
      PARTITION P_2009 VALUES LESS THAN (TO_DATE('2010-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS')),
      PARTITION P_2010 VALUES LESS THAN (TO_DATE('2011-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS')),
      PARTITION P_2011 VALUES LESS THAN (TO_DATE('2012-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS')),
      PARTITION P_2012 VALUES LESS THAN (TO_DATE('2013-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS')),
      PARTITION P_MAX VALUES LESS THAN (MAXVALUE)
      );
     
    ALTER TABLE TABLE1_TEMP ADD (
      CONSTRAINT PK_TABLE1
     PRIMARY KEY
     (NUMERO);


    4- on commence la redefinition

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    exec dbms_redefinition.start_redef_table( 'SCOTT', 'TABLE1', 'TABLE1_TEMP' );
    5- on crée les objets de la table
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    begin
                dbms_redefinition.copy_table_dependents
                ( 'SCOTT', 'TABLE1', 'TABLE1_TEMP',
                  copy_indexes => dbms_redefinition.cons_orig_params,
    			  copy_constraints => dbms_redefinition.cons_orig_params,
    			  copy_privileges => dbms_redefinition.cons_orig_params,
    			  copy_triggers => dbms_redefinition.cons_orig_params,
                 num_errors => :nerrors );
    end;
    /
    6- on finit la redéfinition
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    exec DBMS_REDEFINITION.FINISH_REDEF_TABLE();
    7- on supprime les grant si besoin


    Bon je viens de me rendre compte que dans mon script que j'ai executé, je n'avais pas mis exec DBMS_REDEFINITION.FINISH_REDEF_TABLE()
    est ce que c'est à cause de cela que j'ai pas récupérer mon espace, je ne sais pas
    It's me !!

  5. #25
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2003
    Messages : 92
    Points : 48
    Points
    48
    Par défaut
    arfff ... des fois on passe a coté des trucs simple.
    Je n'ai pas récupérer mon espace dans le tablespace juste parceque je n'avais pas supprimer la table temporaire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    drop table table1_temp cascade constraints;
    olivanto, je me suis aussi beaucoup servit de ce post ou tu es déjà intervenu
    It's me !!

  6. #26
    Membre actif Avatar de olivanto
    Responsable d'exploitation informatique
    Inscrit en
    Mars 2005
    Messages
    513
    Détails du profil
    Informations professionnelles :
    Activité : Responsable d'exploitation informatique
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2005
    Messages : 513
    Points : 204
    Points
    204
    Par défaut
    merci bcp pour tes précisions, elles tombent à pic !
    apprenti sorcier Oracle & boulet intérimaire...
    http://www.courtois.cc/murphy/murphy_informatique.html

  7. #27
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2003
    Messages : 92
    Points : 48
    Points
    48
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    PARTITION P_2010 VALUES LESS THAN (2156516),
    PARTITION P_MAX VALUES LESS THAN (MAXVALUE)
    Svp, pour certaine tables (voir même toutes), les partitions sont faites avec des valeurs en dur (car les valeurs sont défini avec des sous requetes).

    Donc qu'on arrive par exemple en fin d'année, il faut que je fasse une nouvelle partition pour l'année qui vient de se terminée (2011) en déterminant la valeur en dur. Or les valeurs de 2011 sont déjà dans la partition p_max.

    quand je vais faire mon
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ADD PARTITION P_2011 VALUES LESS THAN (3562516),
    ,
    est ce que les données vont se deplacer de P_MAX vers P_2011 ou pas ?

    Merci pour votre aide
    It's me !!

  8. #28
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 460
    Points : 8 074
    Points
    8 074
    Par défaut
    Citation Envoyé par elkamaro Voir le message
    quand je vais faire mon
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ADD PARTITION P_2011 VALUES LESS THAN (3562516),
    ,
    est ce que les données vont se deplacer de P_MAX vers P_2011 ou pas ?
    S'il y a une partition avec MAXVALUE, vous ne pourrez pas utiliser un ADD PARTITION. C'est un SPLIT qu'il faudra faire.
    Consultant / formateur Oracle indépendant
    Certifié OCP 12c, 11g, 10g ; sécurité 11g

    Ma dernière formation Oracle 19c publiée sur Linkedin : https://fr.linkedin.com/learning/oracle-19c-l-administration

  9. #29
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2003
    Messages : 92
    Points : 48
    Points
    48
    Par défaut
    Merci pour l'explication Pomalaix


    Sinon voici un autre article ou il y'a beacoup de conseil pour l'utilisation de dbms_redefinition :
    trucs propos de dbms_redefinition

    Sinon, en fait j'ai toujours mon probleme d'espace au niveau des tbs
    Malgré que je supprime mes tables temporaire (drop table tb cascades constraints purge), je ne récupére pas l'espace qui a ete utilisé par le dbms_redefinition

    ce qui m'embête un peu car j'ai peu d'espace.

    Une idée ?
    It's me !!

  10. #30
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2003
    Messages : 92
    Points : 48
    Points
    48
    Par défaut
    Bonjour j'ai encore besoin de votre aide :

    Lorsque je fais le dbms_redefinition.copy_table_dependents, j'ai des erreurs pour toutes mes tables, de 4 à 12 erreur parfois.

    Mais impossible de savoir comment connaitres les erreurs et surtout pourquoi.

    Je me suis rendu compte de ca, car une fois que toutes mes redefinition se sont terminé, je me suis retrouvé avec un tbs index 2 fois moins gros qu'en temps normal

    Des idées d'aide svp, j'ai rien trouvé sur le web
    It's me !!

  11. #31
    Membre actif Avatar de olivanto
    Responsable d'exploitation informatique
    Inscrit en
    Mars 2005
    Messages
    513
    Détails du profil
    Informations professionnelles :
    Activité : Responsable d'exploitation informatique
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2005
    Messages : 513
    Points : 204
    Points
    204
    Par défaut
    bon, je commence à travailler dessus...et je me pose les mêmes questions.

    pour répondre à ta question ; que sont devenus les indexes des tables "avant partition" ??

    Car c'est là un point que je ne comprend pas ; lors de la définition de la table temporaire et de sa redéfinition, on ne voit rien sur les indexes, triggers, etc...
    Comment sont-ils transférés dans la "nouvelle table" partitionnée ?

    Et "l'ancienne" table, garde t-elle ses indexs quelque part ??
    apprenti sorcier Oracle & boulet intérimaire...
    http://www.courtois.cc/murphy/murphy_informatique.html

  12. #32
    Membre régulier
    Homme Profil pro
    Inscrit en
    Octobre 2002
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2002
    Messages : 58
    Points : 86
    Points
    86
    Par défaut
    Bonjour,

    Les indexes, grants, stats, triggers, contraintes etc... sont copiés de la table d'origine vers la table de travail, lors de l'appel à

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dbms_redefinition.copy_table_dependents()
    On peut choisir de ne pas copier certains de ces objets lors de l'appel à la fonction. (cf. code ci-dessous avec tous les paramètres explicitement passés à la procédure)

    Concernant les indexes/contraintes/.... d'origine, c'est à vérifier, mais je pense qu'ils sont toujours sur la table à la fin du processus, ils doivent juste porter un autre nom.

    Citation Envoyé par Elkamaro
    Lorsque je fais le dbms_redefinition.copy_table_dependents, j'ai des erreurs pour toutes mes tables, de 4 à 12 erreur parfois.

    Mais impossible de savoir comment connaitres les erreurs et surtout pourquoi.
    J'imagine que tu connais le nombre d'erreurs via la variable de sortie de la procedure dbms_redefinition.copy_table_dependents().

    Tu peux visualiser tous les ordres DDL qui ont généré une erreur Oracle, dans la vue DBA_REDEFINITION_ERRORS.

    Pour savoir quelle était l'erreur, il suffit de ré-exécuter le DDL

    Je ne sais pas si cela peut aider, mais au cas où, voila un script que j'ai fait la semaine dernière, pour partitionner des tables selon un champ date. Le script est appelé par du shell, c'est pour cela que le nom des tables/schéma/colonne etc... est paramétré.

    Mais le principe reste valide j'imagine.

    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
     
    whenever sqlerror exit failure
     
    set feedback off
    set verify off 
    set serveroutput on size unlimited
    set linesize 2000
    set trimspool on
    set wrap off
    set pagesize 0
     
     
    define g_schema=&1
    define g_table=&2
    define g_colonne=&3
    define g_table_work=&g_table._WRK
    define g_interval_fonction=&4
    define g_interval_type=&5
     
    Prompt Verification si partitionnement possible pour &g_schema..&g_table ...
    BEGIN
       DBMS_REDEFINITION.CAN_REDEF_TABLE('&g_schema','&g_table', dbms_redefinition.cons_use_pk);
    END;
    /
    Prompt Verifiaction OK.
     
    Prompt Création de la table de travail &g_schema..&g_table_work
     
    -- Si des tables relicats de précédentes exec existent, on les supprime
    declare
    	l_cnt integer;
    begin
    	select count(*)
    	into l_cnt
    	from all_tables
    	where owner = '&g_schema'
    	and table_name = '&g_table_work';
     
    	if l_cnt > 0 then
    		execute immediate 'drop table &g_schema..&g_table_work purge';
    	end if;
     
    	select count(*)
    	into l_cnt
    	from all_tables
    	where owner = '&g_schema'
    	and table_name = '&g_table._ERR';
     
    	if l_cnt > 0 then
    		execute immediate 'drop table &g_schema..&g_table._ERR purge';
    	end if;
     
    end;
    /
     
    declare
    	ltmp varchar2(40);
    	strsql varchar2(32000);
    begin
    	select tablespace_name
    	into ltmp
    	from all_tables 
    	where table_name = '&g_table' 
    	and owner = '&g_schema';
     
    	strsql := q'#
    	CREATE TABLE &g_schema..&g_table_work tablespace #'|| ltmp ||q'#
    	PARTITION BY RANGE (&g_colonne) 
    	INTERVAL (&g_interval_fonction(1,'&g_interval_type'))
    	(
    	  PARTITION P_1 VALUES LESS THAN (to_date('190002','YYYYMM')) NOCOMPRESS  
    	)
    	AS SELECT * FROM &g_schema..&g_table
    	WHERE 0=1#';
     
    	execute immediate strsql;
     
    end;
    /
     
     
    /*
    	Début de la redéfinition
    */
     
    alter session force parallel dml parallel 3;
    alter session force parallel query parallel 3;
     
    Prompt Debut de la redefinition
    BEGIN
       DBMS_REDEFINITION.START_REDEF_TABLE('&g_schema', '&g_table','&g_table_work', null, dbms_redefinition.cons_use_pk);
    END;
    /
     
     
     -- Transfert des objets dépendants (indexes, contraintes, grant, triggers...)
    Prompt Copie des objets dependants de la table
    DECLARE
        num_errors PLS_INTEGER:=0;
    	l_e_already_not_null exception;
    	PRAGMA EXCEPTION_INIT(l_e_already_not_null,-1442);
    	l_cpt_err PLS_INTEGER:=0;
    BEGIN
    	dbms_redefinition.copy_table_dependents(
    		uname            => '&g_schema',
    		orig_table       => '&g_table',
    		int_table        => '&g_table_work',
    		copy_indexes     => dbms_redefinition.cons_orig_params,
    		copy_triggers    => TRUE,
    		copy_constraints => TRUE,
    		copy_privileges  => TRUE,
    		ignore_errors    => TRUE,
    		num_errors       => num_errors,
    		copy_statistics  => TRUE
    	);
     
    	if nvl(num_errors,0) != 0 then
    		-- On essaye de réexécuter le DDL qui a planté pour voir le type d'erreur
    		for i in (select ddl_txt from DBA_REDEFINITION_ERRORS) loop
    		begin
    			execute immediate i.ddl_txt;
    		exception
    			-- On ignore les erreurs de type "contrainte not null est deja not null"
    			when l_e_already_not_null then null;
    			when others then l_cpt_err := l_cpt_err + 1;
    		end;
    		end loop;
     
    		if l_cpt_err != 0 then
    			execute immediate 'create table &g_schema..&g_table._ERR as SELECT object_name, base_table_name, ddl_txt FROM DBA_REDEFINITION_ERRORS';
    			dbms_redefinition.abort_redef_table('&g_schema', '&g_table', '&g_table_work');
    			dbms_output.put_line('*** Des erreurs ont ete detectees lors de la copie des objets dependants de la table.');
    			dbms_output.put_line('*** Le code DDL ayant provoque les erreurs peut etre visualise via: SELECT * FROM &g_schema..&g_table._ERR;');
    			raise_application_error(-20000,'Erreur fatale lors du partitionnement de &g_table. Operation annulee.');		
    		end if;
     
    	end if;
    END;
    /
     
    Prompt Synchronisation table de travail 
    BEGIN
       DBMS_REDEFINITION.SYNC_INTERIM_TABLE('&g_schema','&g_table', '&g_table_work');
    END;
    /
     
    Prompt Finalisation de la redefinition
    BEGIN
       DBMS_REDEFINITION.FINISH_REDEF_TABLE('&g_schema','&g_table', '&g_table_work');
    END;
    /
     
    -- suppression de la table intermédiaire
    DROP TABLE &g_schema..&g_table_work cascade constraints purge;
     
    exit
    A noter que lors du dbms_redefinition.copy_table_dependents(), j'ai décidé d'ignorer les erreurs ORA-1442.

    Ce script est très certainement améliorable, mais il a le mérite de fonctionner et de répondre a mon besoin
    Tuning and optimization are not a fix to a bad design. A good design is a fix to a bad design.

  13. #33
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Mars 2010
    Messages
    536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 536
    Points : 1 359
    Points
    1 359
    Par défaut
    Citation Envoyé par elkamaro Voir le message
    Bonjour à tous,

    je viens a vous pour de l'aide.
    Mon client me demande d'effectuer la purge d'une base de donnée Oracle10g d'à peu prés 100go pour gagner de l'espace.

    Je dois supprimer toutes les données antérieur à 2010.
    J'ai déjà ciblé quelles tables sont concernées et leurs ordres.
    Je n'ai pu obtenir que 1heure/jour d'indisponibilité de la base pour cette purge

    Lorsque je fais un delete normal sur les tables, il me faut plus de 3 semaines pour tout purgé (avec la base en ligne, mais bon les performance de la base sont très dégradées)
    Voilà plusieurs semaines que vous avez posé cette question de purge et il me semble que vous êtes toujours au point mort.

    Certains, très justement, vous ont proposé de transformer vos tables en table partitionnés. Mais je suis désolé de vous dire que ce genre de chose doit être pensé au moment de la modélisation de la base de données et non maintenant. Si votre client prévoyait de faire une purge tous les 6 mois, pourquoi alors avoir attendu jusqu’à la mise en production pour commencer à envisager une solution de purge très efficace ?

    Admettons que vous voulez vraiment passer maintenant d’un schéma de tables normales (heap table) à un schéma de table partitionnées ! Vu votre objectif de purge des données sur la base d’un critère de date et sur un rythme régulier d’une purge par semestre, c’est ce qui se fait de mieux par rapport à cet objectif (dommage qu’il ait été pensé maintenant).

    Je suppose que vous allez faire un partitionnement par date (range partition) et que vous allez considérer le critère de date qui sert à la purge comme clé de partitionnement. Très bien. Dans ce cas il vous faudra simplement supprimer les partitions que vous n’utilisez plus avec un simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    alter table ma_nouvelle_tab_part drop partition p2010 update global indexes ;
    Je ne passerai pas sans vous signaler que, comme vous avez certainement des tables liées entre elles par des clés étrangères, vous devriez d’abord ‘’disabler’’ ces contraintes d’intégrité avant de supprimer les partitions et de les ‘’ré-enabler’’ à la fin sans validation bien évidemment.

    Par contre, en passant à ce nouveau schéma, vous pourriez (au conditionnel) bien aussi complètement détériorer la performance de votre application. La raison dans ce cas n’aura rien à voir avec la fragmentation des indexes basés sur le critère de date (‘’sweeper indexes’’ ou ‘smashed indexes’’ ou ‘’right hand indexes’’) mais plutôt avec le comportement des anciennes requêtes par rapport au partitionnement. Toute requête ne faisant pas appel à la clé de partitionnement fera un ''PARTITION RANGE ALL'' ce qui n’est pas du tout le but du partitionnement à savoir:

    1. Facilité d’administration (comme la purge par exemple)
    2. Amélioration de la performance grâce à l’élimination de partitions

    Comment allez-vous transformer vos indexes ? En indexes simples ? En indexes localement partitionnés ? En indexes globalement partitionnés ? En indexes préfixés (non préfixés) ?

    Ne foncez pas sur une solution si vous ne maitrisez pas tous les aspects qui entourent cette solution
    Bien Respectueusement
    www.hourim.wordpress.com

    "Ce qui se conçoit bien s'énonce clairement"

  14. #34
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2003
    Messages : 92
    Points : 48
    Points
    48
    Par défaut
    Citation Envoyé par Dajon Voir le message
    Bonjour,

    Les indexes, grants, stats, triggers, contraintes etc... sont copiés de la table d'origine vers la table de travail, lors de l'appel à

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dbms_redefinition.copy_table_dependents()
    Une chose a préciser quand même
    mes tables contenaient des colonnes en NOT NULL, ce que represente oracle en constraint systeme

    et le dbms_redefinition.copy_table_dependents() ne copie pas les contraintes système.
    Il faut pour remerdier a cela faire un register de toutes ces contraintes
    voila mon bout de code qui remedie a cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for i in (select 'dbms_redefinition.register_dependent_object( ''ADMIN_OM'', ''' || a.table_name|| ''', ''' || b.table_name|| ''',DBMS_REDEFINITION.CONS_CONSTRAINT,''ADMIN_OM'','''||a.constraint_name||''','''||b.constraint_name||''');' exec
     from dba_cons_columns a, dba_cons_columns b
    where  a.COLUMN_NAME=b.column_name and a.table_name ='MESSAGE' and b.table_name ='MESSAGE_TEMP' and a.constraint_name like 'SYS%')
    loop
    execute immediate  ('begin '||i.exec|| ' end;');
    end loop;
    It's me !!

  15. #35
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2003
    Messages : 92
    Points : 48
    Points
    48
    Par défaut
    Citation Envoyé par Mohamed.Houri Voir le message
    Voilà plusieurs semaines que vous avez posé cette question de purge et il me semble que vous êtes toujours au point mort.
    Bonjour Mohamed,

    Non je ne suis pas au point mort, j'ai finaliser tous mes scripts et je les ai tester et ils sont fonctionnel, la seul chose qu'il me reste a faire, c'est les excuter pour faire une redefinition de toutes mes tables et ensuite tester mes applications dessus pour voir que deviennent les performances.



    Si votre client prévoyait de faire une purge tous les 6 mois, pourquoi alors avoir attendu jusqu’à la mise en production pour commencer à envisager une solution de purge très efficace ?
    Mon client n'a rien prévu depuis le debut de la base concernant une quelconque purge, ce n'est que maintenant qu'il demande a ce qu'elle soit prise en compte.
    Erreur de conception au debut, je vous l'admet et je n etais pas présent non plus au debut pour le leur proposer.
    Mais maintenant c'est a moi qu'on demande de trouver des solutions.



    Je suppose que vous allez faire un partitionnement par date (range partition) et que vous allez considérer le critère de date qui sert à la purge comme clé de partitionnement. Très bien. Dans ce cas il vous faudra simplement supprimer les partitions que vous n’utilisez plus avec un simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    alter table ma_nouvelle_tab_part drop partition p2010 update global indexes ;
    Je ne passerai pas sans vous signaler que, comme vous avez certainement des tables liées entre elles par des clés étrangères, vous devriez d’abord ‘’disabler’’ ces contraintes d’intégrité avant de supprimer les partitions et de les ‘’ré-enabler’’ à la fin sans validation bien évidemment.
    Merci pour cette précision, c'est exactement ce qui m'est arrivé et c est comme ca que j'ai resolu le probleme de suppression des partitions.

    Par contre, en passant à ce nouveau schéma, vous pourriez (au conditionnel) bien aussi complètement détériorer la performance de votre application. La raison dans ce cas n’aura rien à voir avec la fragmentation des indexes basés sur le critère de date (‘’sweeper indexes’’ ou ‘smashed indexes’’ ou ‘’right hand indexes’’) mais plutôt avec le comportement des anciennes requêtes par rapport au partitionnement. Toute requête ne faisant pas appel à la clé de partitionnement fera un ''PARTITION RANGE ALL'' ce qui n’est pas du tout le but du partitionnement à savoir:
    Alors le critere de mes partitions se base non sur des dates mais sur une valeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PARTITION PART_2006 VALUES LESS THAN (64231324),
    C'est une colonne qui est clé primaire de certaine tables mais parfois elle fait seulement partie de la clé primaire.
    Effectivement, je ne maitrise pas ce qu'il va en advenir une fois partitionné, et c'est le but de ce post afin que vous m'aidiez.



    Mais je t'avouerai que la méthode de paritionner pour purger et plus simple et plus rapide que celle avec des deletes (avec des deletes il me faut une vingtaine de scripts sur plus de deux/trois semaine, alors qu'avec les partitions, il me faut 3/4heures grand maximum)


    il faut donc, selon tes conseils, que je regarde aussi comment réorganiser mes index ... sachant qu'on ne peut plus toucher au requetes qui les utilisent ?
    It's me !!

  16. #36
    Membre régulier
    Homme Profil pro
    Inscrit en
    Octobre 2002
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2002
    Messages : 58
    Points : 86
    Points
    86
    Par défaut
    dbms_redefinition.copy_table_dependents() ne copie pas les contraintes système.

    Je n'ai pas eu le problème:

    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
    26
    27
    28
    CREATE TABLE ADA_TEST1 
    (
      ID NUMBER NOT NULL 
    , VAL VARCHAR2(15 BYTE) 
    , UNE_DATE DATE 
    , CONSTRAINT ADA_TEST1_PK PRIMARY KEY (ID) ENABLE 
    ) 
    ;
     
    ALTER TABLE ADA_TEST1
    ADD CONSTRAINT ADA_TEST1_CHK1 CHECK 
    (UNE_DATE IS NOT NULL)
    ENABLE;
     
     
    select constraint_name, constraint_type, table_name, SEARCH_CONDITION from user_constraints where table_name='ADA_TEST1';
     
    CONSTRAINT_NAME                CONSTRAINT_TYPE TABLE_NAME                     SEARCH_CONDITION    
    ------------------------------ --------------- ------------------------------ --------------------
    SYS_C0045016                   C               ADA_TEST1                      "ID" IS NOT NULL    
    ADA_TEST1_CHK1                 C               ADA_TEST1                      UNE_DATE IS NOT NULL
    ADA_TEST1_PK                   P               ADA_TEST1                                          
     
    select count(*) from USER_TAB_PARTITIONS where table_name = 'ADA_TEST1';
     
    COUNT(*)               
    ---------------------- 
    0
    On a une contrainte not null ajoutée à la création et une autre ajoutée en tant que check.

    J'ai ensuite exécuté le script que j'ai mis dans mon précédent message, puis

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    select constraint_name, constraint_type, table_name, SEARCH_CONDITION from user_constraints where table_name='ADA_TEST1';
     
     
    CONSTRAINT_NAME                CONSTRAINT_TYPE TABLE_NAME                     SEARCH_CONDITION      
    ------------------------------ --------------- ------------------------------ ----------------------
    SYS_C0046412                   C               ADA_TEST1                      "ID" IS NOT NULL      
    ADA_TEST1_CHK1                 C               ADA_TEST1                      UNE_DATE IS NOT NULL  
    ADA_TEST1_PK                   P               ADA_TEST1                                            
     
    select count(*) from USER_TAB_PARTITIONS where table_name = 'ADA_TEST1';
     
    COUNT(*)               
    ---------------------- 
    1
    Les contraintes sont bien toutes là. La contrainte SYS_$ a changé de nom, mais elle a bien été "copiée".

    Je pense que cette différence de comportement doit venir de la version d'Oracle. Je suis en

    Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
    With the Partitioning, Real Application Clusters, OLAP, Data Mining
    and Real Application Testing options
    Tuning and optimization are not a fix to a bad design. A good design is a fix to a bad design.

  17. #37
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Mars 2010
    Messages
    536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 536
    Points : 1 359
    Points
    1 359
    Par défaut
    Citation Envoyé par elkamaro Voir le message
    Bonjour Mohamed,
    C'est une colonne qui est clé primaire de certaine tables mais parfois elle fait seulement partie de la clé primaire.
    Voilà par exemple une remarque qui mérite que l'on s'arrête à son niveau. La clé de partitionnement est une clé primaire ou fait partie d'une clé primaire.

    Donc, l'indexe couvrant la clé primaire, sera t-il local ou global?

    Vous avez une restriction importante à ce niveau qui est la suivante:

    L'index couvrant une clé primaire ou une clé unique ne peut être local que s'il inclue la clé de partitionnement dans sa définition.

    https://kr.forums.oracle.com/forums/...rt=15&tstart=0

    Il y a aussi une discussion intéressante dans le lien suivant à propos des indexes partitionnés

    https://forums.oracle.com/forums/thr...art=0&tstart=0

    En conclusion, je veux vous faire passer deux messages:

    1. Oui, quand il s'agit de purge ou d'archivage le partitionnement est la solution adéquate
    2. Lorsque le système est déjà en production passer d'un mode sans partitionnement à une mode avec partitionnement doit être considéré avec une extrême précaution
    Bien Respectueusement
    www.hourim.wordpress.com

    "Ce qui se conçoit bien s'énonce clairement"

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 073
    Points
    19 073
    Par défaut
    Personnellement, je n'ai jamais rencontré de problème à partitionner après coup, il faut juste en effet être prudent sur les indexes et tester. Ceci dit, j'ai toujours profité de l'opération pour faire une réorganisation de l'espace.

  19. #39
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2003
    Messages : 92
    Points : 48
    Points
    48
    Par défaut
    Bonjour et merci pour vos réponses

    Cela dit, je butte sur votre dernier conseil a savoir tester les index et dans ce domaine j'ai encore beaucoup de chose a apprendre.


    OraFrance, dans les partitionnements que tu as déjà effectués, as-tu eu a redéfinir les index ou a y toucher ? si oui, comment as-tu determiner l'action a entreprendre ?

    pour ma part, je pensais tout simplement redefinir les tables avec des partitions et y remettre les index comme il etait au depart sans y toucher, je pensais que le partitionnement n'avait aucune incidence sur les indexes

    As-tu eu d'autres soucis/contraintes/imprévus qui se seraient révéler lors de tes opérations de partitionnements.

    Je te demande tout cela afin que je sois orienté sur le maximum de tests et de possibilités a entreprendre pour que ma procédure de redéfinition soit en béton.

    Je vous remercie
    It's me !!

  20. #40
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2003
    Messages : 92
    Points : 48
    Points
    48
    Par défaut
    Citation Envoyé par Mohamed.Houri Voir le message
    Donc, l'indexe couvrant la clé primaire, sera t-il local ou global?
    Comment puis je determiner cela ou quel test faire pour le determiner ?


    En conclusion, je veux vous faire passer deux messages:

    1. Oui, quand il s'agit de purge ou d'archivage le partitionnement est la solution adéquate
    2. Lorsque le système est déjà en production passer d'un mode sans partitionnement à une mode avec partitionnement doit être considéré avec une extrême précaution
    Merci Mohamed,
    Actuellement, j'ai fini de peaufiner mes scripts de redefinition, je suis donc dans une phase de test et de recherche de tout problème qui pourrait survenir.

    en gros, je recherche toutes les précautions a prendre comme tu me le suggere ... donc si tu as des pistes, je suis preneur
    It's me !!

Discussions similaires

  1. Réponses: 15
    Dernier message: 08/08/2012, 17h35
  2. Page web infectée par une iframe quelle solution?
    Par papisdoums dans le forum Sécurité
    Réponses: 12
    Dernier message: 24/04/2009, 15h20
  3. Réponses: 7
    Dernier message: 18/02/2008, 14h33
  4. Quelles solutions pour créer une Bases de données géographiques ?
    Par subzero82 dans le forum Décisions SGBD
    Réponses: 1
    Dernier message: 25/11/2007, 21h45
  5. Réponses: 4
    Dernier message: 09/10/2007, 16h54

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