################################################################################
# GUIDE ULTRA-COMPLET : CONFIGURATION ORACLE ASM AVEC DEUX UTILISATEURS
# Pour Grands Débutants - Ubuntu 22.04/24.04
# Architecture : Oracle Database 19c + Grid Infrastructure (ASM)
# Date : Décembre 2024
################################################################################

[OK] TABLE DES MATIÈRES DÉTAILLÉE

PARTIE 1 : INTRODUCTION ET CONCEPTS FONDAMENTAUX
  1.1 Qu'est-ce qu'Oracle ASM ?
  1.2 Pourquoi deux utilisateurs (grid et oracle) ?
  1.3 Architecture complète du système
  1.4 Vue d'ensemble du processus d'installation

PARTIE 2 : PRÉPARATION DU SYSTÈME UBUNTU
  2.1 Vérification de la configuration matérielle
  2.2 Configuration du système d'exploitation
  2.3 Installation des packages requis
  2.4 Configuration des paramètres kernel

PARTIE 3 : CRÉATION ET CONFIGURATION DES UTILISATEURS
  3.1 Création des groupes Unix
  3.2 Création de l'utilisateur 'grid'
  3.3 Création de l'utilisateur 'oracle'
  3.4 Configuration des limites système
  3.5 Variables d'environnement

PARTIE 4 : PRÉPARATION DU STOCKAGE
  4.1 Comprendre les besoins en disques
  4.2 Identification des disques physiques
  4.3 Configuration UDEV pour la persistance
  4.4 Vérification des permissions

PARTIE 5 : INSTALLATION DE GRID INFRASTRUCTURE (par l'utilisateur 'grid')
  5.1 Téléchargement du logiciel
  5.2 Installation en mode silencieux
  5.3 Exécution des scripts root
  5.4 Vérification de l'installation

PARTIE 6 : CRÉATION ET GESTION DES DISK GROUPS (par l'utilisateur 'grid')
  6.1 Création du disk group DATA
  6.2 Création du disk group FRA
  6.3 Vérification des disk groups
  6.4 Gestion avec ASMCMD

PARTIE 7 : INSTALLATION ORACLE DATABASE (par l'utilisateur 'oracle')
  7.1 Téléchargement du logiciel
  7.2 Installation du binaire
  7.3 Configuration du listener
  7.4 Création de la base de données sur ASM

PARTIE 8 : ADMINISTRATION QUOTIDIENNE
  8.1 Tâches de l'utilisateur 'grid'
  8.2 Tâches de l'utilisateur 'oracle'
  8.3 Collaboration entre grid et oracle
  8.4 Monitoring et maintenance

PARTIE 9 : SCÉNARIOS PRATIQUES ET EXEMPLES
  9.1 Ajout d'un disque à un disk group
  9.2 Migration d'une table vers ASM
  9.3 Résolution de problèmes courants
  9.4 Sauvegarde et restauration

PARTIE 10 : RÉFÉRENCE COMPLÈTE DES COMMANDES
  10.1 Commandes de l'utilisateur 'grid'
  10.2 Commandes de l'utilisateur 'oracle'
  10.3 Commandes de l'utilisateur 'root'


################################################################################
#                                                                              #
#  PARTIE 1 : INTRODUCTION ET CONCEPTS FONDAMENTAUX                            #
#                                                                              #
################################################################################

═══════════════════════════════════════════════════════════════════════════════
1.1 QU'EST-CE QU'ORACLE ASM ?
═══════════════════════════════════════════════════════════════════════════════

ASM = Automatic Storage Management
-> Gestionnaire de stockage intégré à Oracle Grid Infrastructure
-> Remplace le système de fichiers traditionnel (ext4, XFS, etc.)
-> Optimise automatiquement les performances et la disponibilité

┌────────────────────────────────────────────────────────────────────────────┐
│                     ANALOGIE : LA BIBLIOTHÈQUE INTELLIGENTE                │
└────────────────────────────────────────────────────────────────────────────┘

Imagine une bibliothèque avec 1 million de livres répartis sur 10 salles :

SANS ASM (Système de fichiers classique) :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[DOCS] Tu ranges les livres manuellement dans des salles spécifiques
[X] "Les livres de maths vont dans la salle 3"
[X] "Les livres d'histoire dans la salle 7"
[X] Si la salle 3 est pleine, tu dois DÉPLACER des livres manuellement
[X] Si la salle 7 brûle, tu perds TOUS les livres d'histoire
[X] Pour chercher un livre, tu vas dans UNE SEULE salle (lent)

AVEC ASM (Gestion automatique intelligente) :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[GUIDE] ASM voit les 10 salles comme UN SEUL GRAND ESPACE
[OK] Tu donnes un livre à ASM, il choisit AUTOMATIQUEMENT où le ranger
[OK] ASM découpe chaque livre en chapitres et les répartit sur PLUSIEURS salles
[OK] ASM crée des COPIES de chaque chapitre dans différentes salles
[OK] Si une salle brûle, ASM utilise les copies dans les autres salles
[OK] Pour lire un livre, ASM récupère les chapitres en PARALLÈLE (rapide [RAPIDE])
[OK] Si tu ajoutes une 11ème salle, ASM rééquilibre automatiquement

LES AVANTAGES D'ASM EN CHIFFRES :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Performance :
-> Système classique : lit un fichier de 10 GB sur 1 disque à 100 MB/s = 100s
-> ASM avec 5 disques : lit 2 GB sur chaque disque en parallèle = 20s
-> RÉSULTAT : 5× PLUS RAPIDE [RAPIDE]

Disponibilité :
-> Système classique : 1 disque meurt = perte de données [SKULL]
-> ASM : 1 disque meurt = bascule automatique sur les copies [OK]
-> RÉSULTAT : ZÉRO interruption de service

Simplicité :
-> Système classique : partitions, mount points, resize manuel
-> ASM : "ALTER DISKGROUP DATA ADD DISK '/dev/sdc';" (une seule commande)
-> RÉSULTAT : 90% de commandes en moins


═══════════════════════════════════════════════════════════════════════════════
1.2 POURQUOI DEUX UTILISATEURS (grid ET oracle) ?
═══════════════════════════════════════════════════════════════════════════════

Oracle recommande FORTEMENT de séparer les responsabilités en deux utilisateurs :

┌────────────────────────────────────────────────────────────────────────────┐
│                     UTILISATEUR 'grid' - LE GESTIONNAIRE                   │
└────────────────────────────────────────────────────────────────────────────┘

Rôle : Propriétaire de Grid Infrastructure (qui inclut ASM)
Responsabilités :
  [OK] Gère le STOCKAGE (les disques, les disk groups)
  [OK] Gère l'instance ASM (+ASM)
  [OK] Gère la haute disponibilité (si RAC)
  [OK] Gère le réseau cluster (si RAC)

Analogie :
-> 'grid' = Gestionnaire d'immeuble qui gère les LOCAUX
-> Il décide comment répartir les appartements (disk groups)
-> Il gère les infrastructures communes (électricité, eau, chauffage = ASM)
-> Il ne s'occupe PAS de ce que font les locataires dans leurs appartements

Logiciels possédés :
  /u01/app/19.3.0/grid/          <- Grid Infrastructure Home (GRID_HOME)
  
Processus gérés :
  +ASM                            <- Instance ASM
  LISTENER (optionnel)            <- Listener réseau


┌────────────────────────────────────────────────────────────────────────────┐
│                   UTILISATEUR 'oracle' - L'UTILISATEUR                     │
└────────────────────────────────────────────────────────────────────────────┘

Rôle : Propriétaire du logiciel Oracle Database
Responsabilités :
  [OK] Installe et gère les BASES DE DONNÉES (ORCL, PROD, TEST, etc.)
  [OK] Gère les DONNÉES (tables, index, utilisateurs)
  [OK] Fait les sauvegardes de bases de données (RMAN)
  [OK] Optimise les requêtes SQL

Analogie :
-> 'oracle' = Locataire qui utilise les appartements
-> Il stocke ses meubles (tables) dans les appartements (disk groups)
-> Il utilise les infrastructures fournies par le gestionnaire (ASM)
-> Il ne peut PAS modifier les infrastructures (ajouter/supprimer des disques)

Logiciels possédés :
  /u01/app/oracle/product/19.3.0/dbhome_1/    <- Oracle Home (ORACLE_HOME)
  
Processus gérés :
  ORCL                            <- Instance de base de données
  LISTENER (optionnel)            <- Listener réseau


┌────────────────────────────────────────────────────────────────────────────┐
│                    TABLEAU COMPARATIF : grid VS oracle                     │
└────────────────────────────────────────────────────────────────────────────┘

┌──────────────────────┬───────────────────────┬───────────────────────────┐
│   Aspect             │  Utilisateur 'grid'   │  Utilisateur 'oracle'     │
├──────────────────────┼───────────────────────┼───────────────────────────┤
│ Rôle principal       │ Infrastructure        │ Applications (databases)  │
│ Logiciel             │ Grid Infrastructure   │ Oracle Database           │
│ Instance gérée       │ +ASM                  │ ORCL, PROD, TEST, etc.    │
│ Gère les disques     │ [OK] OUI                │ [X] NON                    │
│ Gère les disk groups │ [OK] OUI                │ [X] NON (lecture seule)    │
│ Crée des tables      │ [X] NON                │ [OK] OUI                    │
│ Fait des backups DB  │ [X] NON                │ [OK] OUI                    │
│ Démarre ASM          │ [OK] OUI                │ [X] NON                    │
│ Démarre databases    │ [X] NON                │ [OK] OUI                    │
│ ORACLE_HOME          │ /u01/app/19.3.0/grid/ │ /u01/app/oracle/.../      │
│ Commandes clés       │ asmcmd, crsctl        │ sqlplus, rman, expdp      │
└──────────────────────┴───────────────────────┴───────────────────────────┘


POURQUOI CETTE SÉPARATION EST IMPORTANTE ?
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

1. SÉCURITÉ [VERROUILLE]
   -> Si un hacker compromet 'oracle', il n'a PAS accès à l'infrastructure ASM
   -> Il ne peut PAS ajouter/supprimer des disques
   -> Il ne peut PAS arrêter ASM (ce qui arrêterait TOUTES les bases)

2. MAINTENANCE [OUTIL]
   -> Tu peux upgrader Grid Infrastructure SANS toucher aux bases de données
   -> Tu peux upgrader une base de données SANS toucher à ASM
   -> Mises à jour indépendantes = moins de downtime

3. ORACLE RAC (Real Application Clusters) [WEB]
   -> Si tu veux faire du RAC (plusieurs serveurs = 1 base de données)
   -> La séparation 'grid'/'oracle' est OBLIGATOIRE
   -> Même si tu n'as pas RAC aujourd'hui, tu es prêt pour le futur

4. BEST PRACTICE ORACLE [LIVRE]
   -> Recommandation officielle d'Oracle
   -> Utilisé dans 90% des installations entreprise
   -> Si tu suis cette pratique, tu comprends les installations "réelles"


═══════════════════════════════════════════════════════════════════════════════
1.3 ARCHITECTURE COMPLÈTE DU SYSTÈME
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│                    VUE D'ENSEMBLE DE L'ARCHITECTURE                        │
└────────────────────────────────────────────────────────────────────────────┘

                    ┌──────────────────────────────────┐
                    │     UTILISATEURS FINAUX          │
                    │  (Développeurs, Applications)    │
                    └────────────┬─────────────────────┘
                                 │ SQL queries
                                 v
        ┌────────────────────────────────────────────────────┐
        │         INSTANCE ORACLE DATABASE (ORCL)            │
        │              Utilisateur: oracle                   │
        │  ┌──────────────────────────────────────────────┐  │
        │  │  SGA (System Global Area)                    │  │
        │  │  - Buffer Cache                              │  │
        │  │  - Shared Pool                               │  │
        │  │  - Redo Log Buffer                           │  │
        │  └──────────────────────────────────────────────┘  │
        │  ┌──────────────────────────────────────────────┐  │
        │  │  Background Processes                        │  │
        │  │  PMON SMON DBWn LGWR CKPT ARCn RECO ...      │  │
        │  └──────────────────────────────────────────────┘  │
        └──────────────┬─────────────────────────────────────┘
                       │ Demandes I/O sur fichiers
                       │ (+DATA/ORCL/datafile/users01.dbf)
                       v
        ┌────────────────────────────────────────────────────┐
        │          INSTANCE ASM (+ASM)                       │
        │              Utilisateur: grid                     │
        │  ┌──────────────────────────────────────────────┐  │
        │  │  SGA ASM (plus petite que DB SGA)            │  │
        │  │  - Metadata cache                            │  │
        │  │  - Disk group info                           │  │
        │  └──────────────────────────────────────────────┘  │
        │  ┌──────────────────────────────────────────────┐  │
        │  │  ASM Background Processes                    │  │
        │  │  RBAL ARBn ASMB GMON ...                     │  │
        │  └──────────────────────────────────────────────┘  │
        └──────┬──────────────────────┬────────────────────────┘
               │                      │
               │ Gère les disques     │ Traduit les demandes
               │                      │ fichier -> blocs disque
               v                      v
    ┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
    │  DISK GROUP     │    │  DISK GROUP     │    │  DISK GROUP     │
    │     DATA        │    │     FRA         │    │     REDO        │
    │  (Redundancy:   │    │  (Redundancy:   │    │  (Redundancy:   │
    │    NORMAL)      │    │    NORMAL)      │    │    HIGH)        │
    └────┬────────────┘    └────┬────────────┘    └────┬────────────┘
         │                      │                      │
         │ Composé de           │                      │
         v                      v                      v
   ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐
   │ /dev/sdb │  │ /dev/sdc │  │ /dev/sdd │  │ /dev/sde │  │ /dev/sdf │
   │  20 GB   │  │  20 GB   │  │  20 GB   │  │  20 GB   │  │  20 GB   │
   │  (SSD)   │  │  (SSD)   │  │  (SSD)   │  │  (HDD)   │  │  (HDD)   │
   └──────────┘  └──────────┘  └──────────┘  └──────────┘  └──────────┘
       ^              ^              ^              ^              ^
       └──────────────┴──────────────┴──────────────┴──────────────┘
                    Disques physiques du serveur


FLUX DE DONNÉES DÉTAILLÉ :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Exemple : Un utilisateur exécute "INSERT INTO clients VALUES (1, 'Dupont');"

Étape 1 : L'application envoie la requête SQL
   │
   v
Étape 2 : Instance ORCL (utilisateur 'oracle') reçoit la requête
   │  -> Parse la requête (analyse syntaxique)
   │  -> Vérifie les permissions
   │  -> Optimise le plan d'exécution
   │  -> Exécute l'INSERT
   │  -> Les données vont dans le Buffer Cache (RAM)
   │  -> Les modifications vont dans le Redo Log Buffer (RAM)
   v
Étape 3 : Au COMMIT, DBWn et LGWR doivent écrire sur disque
   │  -> LGWR écrit dans le Redo Log : +DATA/ORCL/ONLINELOG/redo01.log
   │  -> DBWn écrit dans le Datafile : +DATA/ORCL/DATAFILE/users01.dbf
   │
   v
Étape 4 : L'instance ORCL demande à ASM
   │  -> "ASM, je veux écrire le bloc #12345 dans users01.dbf"
   │  -> "ASM, je veux écrire dans redo01.log"
   │
   v
Étape 5 : Instance ASM (+ASM, utilisateur 'grid') traite la demande
   │  -> Consulte ses métadonnées : "users01.dbf extent 42 = /dev/sdb offset 123456"
   │  -> Traduit : "bloc #12345 du fichier" -> "secteur 987654 du disque /dev/sdb"
   │  -> Prépare l'écriture
   │
   v
Étape 6 : ASM écrit PHYSIQUEMENT sur les disques
   │  -> Écriture primaire sur /dev/sdb (secteur 987654)
   │  -> Si NORMAL redundancy : écriture miroir sur /dev/sdc (secteur 234567)
   │  -> Si HIGH redundancy : 3ème copie sur /dev/sdd
   │  -> Attend la confirmation du disque (fsync)
   │
   v
Étape 7 : ASM confirme à l'instance ORCL
   │  -> "OK, écriture réussie sur disque"
   │
   v
Étape 8 : ORCL confirme à l'application
   │  -> "COMMIT successful"
   │
   v
Étape 9 : L'application reçoit la confirmation
   -> L'utilisateur voit : "1 row inserted."

[TEMPS]  Temps total : 5-20 millisecondes (selon la charge et les disques)


STRUCTURE DES RÉPERTOIRES :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

/u01/                                           <- Base de l'arborescence Oracle
├── app/
│   ├── grid/                                   <- Home de 'grid'
│   │   ├── admin/
│   │   │   └── +ASM/                           <- Admin ASM
│   │   │       ├── adump/                      <- Audit logs ASM
│   │   │       └── pfile/                      <- Parameter files ASM
│   │   ├── cfgtoollogs/                        <- Logs outils config
│   │   ├── diag/                               <- Diagnostics ASM
│   │   │   └── asm/
│   │   │       └── +asm/
│   │   │           └── <hostname>/
│   │   │               ├── alert/              <- Alert log ASM
│   │   │               ├── trace/              <- Trace files
│   │   │               └── ...
│   │   └── crsdata/                            <- Données Cluster (si RAC)
│   │
│   ├── 19.3.0/
│   │   └── grid/                               <- GRID_HOME (logiciel Grid Infrastructure)
│   │       ├── bin/                            <- Exécutables ASM
│   │       │   ├── asmcmd                      <- Utilitaire ligne de commande ASM
│   │       │   ├── sqlplus                     <- SQL*Plus pour ASM
│   │       │   ├── crsctl                      <- Contrôle Cluster/Grid
│   │       │   ├── srvctl                      <- Gestion services
│   │       │   └── ...
│   │       ├── lib/                            <- Bibliothèques
│   │       ├── network/
│   │       │   └── admin/
│   │       │       ├── listener.ora            <- Config listener
│   │       │       ├── tnsnames.ora            <- Alias connexions
│   │       │       └── sqlnet.ora              <- Config réseau
│   │       ├── rdbms/                          <- Code moteur
│   │       ├── OPatch/                         <- Utilitaire patches
│   │       ├── install/                        <- Fichiers installation
│   │       └── ...
│   │
│   ├── oracle/                                 <- Home de 'oracle'
│   │   ├── admin/
│   │   │   └── ORCL/                           <- Admin de la base ORCL
│   │   │       ├── adump/                      <- Audit logs ORCL
│   │   │       ├── dpdump/                     <- Data Pump directory
│   │   │       └── pfile/                      <- Parameter files ORCL
│   │   ├── cfgtoollogs/                        <- Logs outils config
│   │   ├── diag/                               <- Diagnostics ORCL
│   │   │   └── rdbms/
│   │   │       └── orcl/
│   │   │           └── ORCL/
│   │   │               ├── alert/              <- Alert log ORCL
│   │   │               ├── trace/              <- Trace files
│   │   │               └── ...
│   │   └── product/
│   │       └── 19.3.0/
│   │           └── dbhome_1/                   <- ORACLE_HOME (logiciel Database)
│   │               ├── bin/                    <- Exécutables Database
│   │               │   ├── sqlplus             <- SQL*Plus
│   │               │   ├── rman                <- Recovery Manager
│   │               │   ├── expdp/impdp         <- Data Pump
│   │               │   ├── lsnrctl              <- Contrôle listener
│   │               │   └── ...
│   │               ├── dbs/                    <- Fichiers config DB
│   │               │   ├── initORCL.ora        <- Paramètres init
│   │               │   ├── spfileORCL.ora      <- Server param file
│   │               │   └── orapwORCL           <- Fichier passwords
│   │               ├── lib/
│   │               ├── network/
│   │               ├── rdbms/
│   │               ├── OPatch/
│   │               └── ...
│   │
│   └── oraInventory/                           <- Inventaire Oracle (commun)
│       ├── ContentsXML/                        <- Infos installations
│       │   └── inventory.xml
│       ├── logs/                               <- Logs installations
│       └── oraInst.loc                         <- Pointeur inventaire
│
├── stage/                                      <- Zone de staging (temporaire)
│   ├── grid/                                   <- Fichiers install Grid
│   │   ├── LINUX.X64_193000_grid_home.zip
│   │   └── grid_install.rsp                    <- Response file
│   └── database/                               <- Fichiers install Database
│       ├── LINUX.X64_193000_db_home.zip
│       └── db_install.rsp
│
└── oradata/                                    <- Données filesystem (optionnel)
    └── (vide si tout sur ASM)


/dev/oracleasm/                                 <- Disques ASM (liens UDEV)
├── disk1 -> /dev/sdb                            <- Lien vers disque physique
├── disk2 -> /dev/sdc
├── disk3 -> /dev/sdd
├── disk4 -> /dev/sde
├── disk5 -> /dev/sdf
└── disk6 -> /dev/sdg


FICHIERS DE DONNÉES ASM (virtuels, gérés par ASM) :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Les fichiers ne sont PAS visibles comme /u01/oradata/ORCL/users01.dbf
Ils sont dans ASM avec des noms spéciaux :

+DATA/                                          <- Disk group DATA
├── ORCL/                                       <- Base de données ORCL
│   ├── CONTROLFILE/                            <- Fichiers de contrôle
│   │   └── current.256.123456789
│   ├── DATAFILE/                               <- Datafiles
│   │   ├── system.257.123456790                <- Tablespace SYSTEM
│   │   ├── sysaux.258.123456791                <- Tablespace SYSAUX
│   │   ├── undotbs1.259.123456792              <- Tablespace UNDO
│   │   └── users.260.123456793                 <- Tablespace USERS
│   ├── ONLINELOG/                              <- Redo logs
│   │   ├── group_1.261.123456794
│   │   ├── group_2.262.123456795
│   │   └── group_3.263.123456796
│   ├── TEMPFILE/                               <- Fichiers temporaires
│   │   └── temp.264.123456797
│   └── PARAMETERFILE/                          <- SPFILE
│       └── spfile.265.123456798

+FRA/                                           <- Disk group FRA
└── ORCL/                                       <- Base ORCL
    ├── ARCHIVELOG/                             <- Archived redo logs
    │   ├── 2024_12_19/
    │   │   ├── thread_1_seq_123.266.123456799
    │   │   └── thread_1_seq_124.267.123456800
    ├── BACKUPSET/                              <- Sauvegardes RMAN
    │   ├── 2024_12_19/
    │   │   ├── backup_piece_1.268.123456801
    │   │   └── backup_piece_2.269.123456802
    └── FLASHBACK/                              <- Flashback logs
        └── flashback.270.123456803


═══════════════════════════════════════════════════════════════════════════════
1.4 VUE D'ENSEMBLE DU PROCESSUS D'INSTALLATION
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│                    CHRONOLOGIE D'INSTALLATION COMPLÈTE                     │
└────────────────────────────────────────────────────────────────────────────┘

Phase 1 : PRÉPARATION DU SYSTÈME (root)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  [TEMPS]  Durée : 30-60 minutes
  [UTILISATEUR] Utilisateur : root
  
  Étapes :
  [WHITE_SQUARE] 1. Vérifier la configuration matérielle
  [WHITE_SQUARE] 2. Installer les packages Ubuntu requis
  [WHITE_SQUARE] 3. Configurer les paramètres kernel
  [WHITE_SQUARE] 4. Créer les groupes Unix
  [WHITE_SQUARE] 5. Créer les utilisateurs 'grid' et 'oracle'
  [WHITE_SQUARE] 6. Configurer les limites système
  [WHITE_SQUARE] 7. Créer l'arborescence de répertoires
  [WHITE_SQUARE] 8. Identifier et préparer les disques
  [WHITE_SQUARE] 9. Configurer UDEV pour la persistance des disques


Phase 2 : INSTALLATION GRID INFRASTRUCTURE (grid)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  [TEMPS]  Durée : 60-90 minutes
  [UTILISATEUR] Utilisateur : grid (+ root pour les scripts)
  
  Étapes :
  [WHITE_SQUARE] 10. Télécharger Oracle Grid Infrastructure 19c
  [WHITE_SQUARE] 11. Extraire le logiciel dans GRID_HOME
  [WHITE_SQUARE] 12. Créer le fichier de réponse (response file)
  [WHITE_SQUARE] 13. Lancer l'installation en mode silencieux
  [WHITE_SQUARE] 14. Exécuter orainstRoot.sh (root)
  [WHITE_SQUARE] 15. Exécuter root.sh (root)
  [WHITE_SQUARE] 16. Vérifier l'installation ASM
  [WHITE_SQUARE] 17. Vérifier le disk group DATA (créé automatiquement)


Phase 3 : CONFIGURATION ASM (grid)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  [TEMPS]  Durée : 15-30 minutes
  [UTILISATEUR] Utilisateur : grid
  
  Étapes :
  [WHITE_SQUARE] 18. Créer le disk group FRA (Fast Recovery Area)
  [WHITE_SQUARE] 19. Vérifier les disk groups
  [WHITE_SQUARE] 20. Tester les commandes ASMCMD
  [WHITE_SQUARE] 21. Configurer le mot de passe SYSASM


Phase 4 : INSTALLATION ORACLE DATABASE (oracle)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  [TEMPS]  Durée : 60-90 minutes
  [UTILISATEUR] Utilisateur : oracle (+ root pour les scripts)
  
  Étapes :
  [WHITE_SQUARE] 22. Télécharger Oracle Database 19c
  [WHITE_SQUARE] 23. Extraire le logiciel dans ORACLE_HOME
  [WHITE_SQUARE] 24. Installer le logiciel Database (binaires seulement)
  [WHITE_SQUARE] 25. Exécuter root.sh (root)
  [WHITE_SQUARE] 26. Configurer le listener
  [WHITE_SQUARE] 27. Créer la base de données sur ASM
  [WHITE_SQUARE] 28. Vérifier la base de données


Phase 5 : TESTS ET VÉRIFICATIONS (oracle et grid)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  [TEMPS]  Durée : 30-45 minutes
  [UTILISATEUR] Utilisateur : grid et oracle
  
  Étapes :
  [WHITE_SQUARE] 29. Vérifier l'état d'ASM (grid)
  [WHITE_SQUARE] 30. Vérifier l'état de la base (oracle)
  [WHITE_SQUARE] 31. Créer une table de test (oracle)
  [WHITE_SQUARE] 32. Vérifier que les fichiers sont sur ASM (grid)
  [WHITE_SQUARE] 33. Tester une sauvegarde RMAN (oracle)
  [WHITE_SQUARE] 34. Simuler une panne de disque (grid)


TEMPS TOTAL ESTIMÉ : 4-6 heures (pour un débutant)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Répartition par utilisateur :
  root  : ~1.5 heures (préparation système)
  grid  : ~2 heures (installation Grid + configuration ASM)
  oracle: ~2 heures (installation Database + création base)
  tests : ~0.5 heure


################################################################################
#                                                                              #
#  PARTIE 2 : PRÉPARATION DU SYSTÈME UBUNTU                                   #
#                                                                              #
################################################################################

═══════════════════════════════════════════════════════════════════════════════
2.1 VÉRIFICATION DE LA CONFIGURATION MATÉRIELLE
═══════════════════════════════════════════════════════════════════════════════

Avant de commencer, vérifions que ton système répond aux exigences minimales.

┌────────────────────────────────────────────────────────────────────────────┐
│                    EXIGENCES MATÉRIELLES ORACLE 19c                        │
└────────────────────────────────────────────────────────────────────────────┘

PROCESSEUR :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  Minimum : Architecture x86-64 (64 bits)
  Recommandé : 4 cores ou plus
  
  Vérifier :
  $ lscpu | grep -E "Architecture|CPU\(s\):"
  
  Sortie attendue :
  Architecture:            x86_64
  CPU(s):                  4


MÉMOIRE RAM :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  Minimum absolu : 4 GB
  Recommandé : 8 GB ou plus
  Production : 16 GB minimum
  
  Vérifier :
  $ free -h
  
  Sortie attendue (exemple avec 8 GB) :
                total        used        free      shared  buff/cache   available
  Mem:          7.7Gi       2.1Gi       3.2Gi       156Mi       2.4Gi       5.3Gi
  Swap:         2.0Gi          0B       2.0Gi


ESPACE DISQUE :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  /tmp : 1 GB minimum
  Logiciels Grid Infrastructure : 10 GB
  Logiciels Oracle Database : 10 GB
  Disques pour ASM : Au moins 3 disques de 20 GB chacun
  
  Vérifier :
  $ df -h | grep -E "Filesystem|/$|/tmp"
  
  Sortie attendue :
  Filesystem      Size  Used Avail Use% Mounted on
  /dev/sda3        50G   15G   33G  32% /
  tmpfs           3.9G  1.2M  3.9G   1% /tmp


SWAP :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  Si RAM < 8 GB : swap = 2× RAM
  Si RAM >= 8 GB : swap = RAM
  
  Vérifier :
  $ swapon --show
  
  Sortie attendue :
  NAME      TYPE SIZE USED PRIO
  /swapfile file   2G   0B   -2
  
  Si pas de swap, créer un fichier swap :
  $ sudo fallocate -l 2G /swapfile
  $ sudo chmod 600 /swapfile
  $ sudo mkswap /swapfile
  $ sudo swapon /swapfile
  $ echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab


DISQUES POUR ASM :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  Minimum : 3 disques (pour NORMAL redundancy)
  Recommandé : 5-6 disques (meilleure performance)
  
  Lister les disques disponibles :
  $ lsblk
  
  Sortie attendue (exemple) :
  NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
  sda      8:0    0   50G  0 disk 
  ├─sda1   8:1    0    1M  0 part 
  ├─sda2   8:2    0    1G  0 part /boot
  └─sda3   8:3    0   49G  0 part /
  sdb      8:16   0   20G  0 disk            <- Disponible pour ASM
  sdc      8:32   0   20G  0 disk            <- Disponible pour ASM
  sdd      8:48   0   20G  0 disk            <- Disponible pour ASM
  sde      8:64   0   20G  0 disk            <- Disponible pour ASM
  sdf      8:80   0   20G  0 disk            <- Disponible pour ASM
  
  [ATTENTION]  IMPORTANT : Les disques ASM doivent être VIDES (pas de partitions, pas montés)


═══════════════════════════════════════════════════════════════════════════════
2.2 CONFIGURATION DU SYSTÈME D'EXPLOITATION
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│              CONFIGURATION HOSTNAME ET RÉSEAU                              │
└────────────────────────────────────────────────────────────────────────────┘

ÉTAPE 1 : Définir un hostname stable
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Vérifier le hostname actuel
  $ hostname
  
  # Définir un hostname (exemple : oracledb)
  $ sudo hostnamectl set-hostname oracledb
  
  # Vérifier la modification
  $ hostname
  oracledb


ÉTAPE 2 : Configurer /etc/hosts
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Éditer /etc/hosts
  $ sudo nano /etc/hosts
  
  # Ajouter (remplacer par ton IP réelle) :
  127.0.0.1       localhost
  192.168.1.100   oracledb oracledb.localdomain
  
  # Sauvegarder et quitter (Ctrl+O, Enter, Ctrl+X)
  
  # Vérifier
  $ ping -c 2 oracledb
  PING oracledb (192.168.1.100) 56(84) bytes of data.
  64 bytes from oracledb (192.168.1.100): icmp_seq=1 ttl=64 time=0.043 ms
  64 bytes from oracledb (192.168.1.100): icmp_seq=2 ttl=64 time=0.051 ms


ÉTAPE 3 : Désactiver le pare-feu (optionnel pour test)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Pour faciliter les tests initiaux, tu peux désactiver le pare-feu :
  
  $ sudo ufw status
  Status: active
  
  $ sudo ufw disable
  Firewall stopped and disabled on system startup
  
  [ATTENTION]  EN PRODUCTION : Configurer plutôt les règles firewall pour autoriser :
      - Port 1521 (listener Oracle)
      - Port 5500 (Enterprise Manager)
  
  $ sudo ufw allow 1521/tcp
  $ sudo ufw allow 5500/tcp
  $ sudo ufw enable


ÉTAPE 4 : Désactiver SELinux (n'existe pas par défaut sur Ubuntu)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Ubuntu utilise AppArmor au lieu de SELinux.
  
  Vérifier l'état d'AppArmor :
  $ sudo aa-status
  
  Pour désactiver temporairement (optionnel pour test) :
  $ sudo systemctl stop apparmor
  $ sudo systemctl disable apparmor
  
  [ATTENTION]  EN PRODUCTION : Mieux vaut configurer des profils AppArmor plutôt que de désactiver


═══════════════════════════════════════════════════════════════════════════════
2.3 INSTALLATION DES PACKAGES REQUIS
═══════════════════════════════════════════════════════════════════════════════

Oracle Database nécessite de nombreuses bibliothèques système.

ÉTAPE 1 : Mettre à jour le système
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ sudo apt update
  $ sudo apt upgrade -y
  
  [TEMPS]  Temps : 5-10 minutes selon les mises à jour


ÉTAPE 2 : Installer les packages de développement
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ sudo apt install -y \
      build-essential \
      gcc \
      g++ \
      make \
      binutils \
      cpp
  
  Explication :
  build-essential : Meta-package contenant gcc, g++, make
  gcc, g++        : Compilateurs C et C++
  make            : Utilitaire de compilation
  binutils        : Outils binaires (ld, as, etc.)
  cpp             : Préprocesseur C


ÉTAPE 3 : Installer les bibliothèques système requises
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ sudo apt install -y \
      libaio1 \
      libaio-dev \
      libstdc++6 \
      libgcc-s1 \
      libc6 \
      libcap-dev \
      zlib1g \
      zlib1g-dev \
      libelf-dev \
      libmotif-dev \
      libxext6 \
      libxrender1 \
      libxtst6 \
      libxi6 \
      libx11-6
  
  Explication détaillée de chaque package :
  
  libaio1, libaio-dev
  -> Bibliothèques d'I/O asynchrones
  -> OBLIGATOIRES pour Oracle (Oracle utilise intensivement l'async I/O)
  -> Sans elles, Oracle refusera de démarrer
  
  libstdc++6
  -> Bibliothèque standard C++
  -> Requise par les binaires Oracle compilés en C++
  
  libgcc-s1
  -> Bibliothèque runtime GCC
  -> Support des exceptions C++
  
  libc6
  -> Bibliothèque C standard GNU
  -> Fonctions de base (malloc, printf, etc.)
  
  libcap-dev
  -> Gestion des capabilities Linux
  -> Permet à Oracle d'acquérir des privilèges spécifiques
  
  zlib1g, zlib1g-dev
  -> Bibliothèques de compression
  -> Utilisées pour compresser les sauvegardes RMAN
  
  libelf-dev
  -> Manipulation des fichiers ELF (format exécutables Linux)
  -> Utilisé par Oracle Clusterware
  
  libmotif-dev
  -> Bibliothèques Motif (interface graphique X11)
  -> Requises pour l'installeur graphique Oracle
  
  libxext6, libxrender1, libxtst6, libxi6, libx11-6
  -> Bibliothèques X11 (système graphique)
  -> Nécessaires même en mode silencieux (l'installeur les utilise)


ÉTAPE 4 : Installer les utilitaires système
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ sudo apt install -y \
      ksh \
      lsb-release \
      net-tools \
      nfs-common \
      smartmontools \
      sysstat \
      unzip \
      zip \
      xauth \
      xterm
  
  Explication :
  
  ksh
  -> Korn Shell
  -> Certains scripts Oracle sont écrits en ksh
  
  lsb-release
  -> Informations sur la distribution Linux
  -> Oracle vérifie la compatibilité avec ce package
  
  net-tools
  -> Utilitaires réseau (ifconfig, netstat, etc.)
  -> Utilisés par Oracle pour détecter la configuration réseau
  
  nfs-common
  -> Client NFS
  -> Utile si tu veux monter des disques ASM depuis un SAN NFS
  
  smartmontools
  -> Monitoring de la santé des disques (SMART)
  -> Très utile pour surveiller les disques ASM
  
  sysstat
  -> Outils de monitoring système (sar, iostat, mpstat, pidstat)
  -> Essentiels pour diagnostiquer les problèmes de performance
  
  unzip, zip
  -> Compression/décompression
  -> Oracle Grid Infrastructure est distribué en .zip
  
  xauth
  -> Gestion des autorisations X11
  -> Permet d'afficher l'installeur graphique Oracle depuis une connexion SSH
  
  xterm
  -> Émulateur de terminal X11


ÉTAPE 5 : Installer ODBC (optionnel mais recommandé)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ sudo apt install -y \
      unixodbc \
      unixodbc-dev
  
  Explication :
  unixodbc, unixodbc-dev
  -> Implémentation open-source d'ODBC pour Unix
  -> Permet aux applications de se connecter à Oracle via ODBC
  -> Utile pour les outils d'administration tiers


ÉTAPE 6 : Vérifier les installations
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Vérifier gcc
  $ gcc --version
  gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
  
  # Vérifier make
  $ make --version
  GNU Make 4.3
  
  # Vérifier libaio (CRITIQUE)
  $ dpkg -l | grep libaio
  ii  libaio-dev:amd64   0.3.112-13build1   amd64  Linux kernel AIO access library - development files
  ii  libaio1:amd64      0.3.112-13build1   amd64  Linux kernel AIO access library - shared library
  
  # Vérifier ksh
  $ which ksh
  /bin/ksh


═══════════════════════════════════════════════════════════════════════════════
2.4 CONFIGURATION DES PARAMÈTRES KERNEL
═══════════════════════════════════════════════════════════════════════════════

Oracle nécessite des ajustements des paramètres kernel pour :
[OK] Permettre l'allocation de grande quantités de mémoire partagée
[OK] Gérer un grand nombre de processus et de fichiers ouverts
[OK] Optimiser les performances réseau et I/O

ÉTAPE 1 : Configurer les paramètres kernel dans /etc/sysctl.conf
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Sauvegarder le fichier original
  $ sudo cp /etc/sysctl.conf /etc/sysctl.conf.backup
  
  # Ajouter les paramètres Oracle à la fin du fichier
  $ sudo tee -a /etc/sysctl.conf > /dev/null <<'EOF'

#############################################################################
# Paramètres kernel pour Oracle Database 19c et Grid Infrastructure
# Ajouté le : $(date)
#############################################################################

# === MÉMOIRE PARTAGÉE (Shared Memory) ===

# kernel.shmmax : Taille MAXIMUM d'un SEUL segment de mémoire partagée
# Oracle SGA utilise la mémoire partagée pour stocker le buffer cache, shared pool, etc.
# Valeur : 4 TB (4398046511104 bytes)
# Pourquoi ? Permet d'allouer une SGA jusqu'à 4 TB (largement suffisant)
kernel.shmmax = 4398046511104

# kernel.shmall : Nombre TOTAL de pages de mémoire partagée disponibles
# 1 page = 4 KB sur x86_64
# Valeur : 1073741824 pages = 4 TB
# Calcul : 4398046511104 bytes / 4096 bytes/page = 1073741824 pages
# Pourquoi ? Permet d'allouer jusqu'à 4 TB de mémoire partagée au total
kernel.shmall = 1073741824

# kernel.shmmni : Nombre MAXIMUM de segments de mémoire partagée système-wide
# Valeur : 4096 segments
# Pourquoi ? Oracle crée plusieurs segments (1 par SGA, plus segments système)
kernel.shmmni = 4096

# === SÉMAPHORES (Synchronisation de processus) ===

# kernel.sem : Configuration des sémaphores (4 valeurs séparées par des espaces)
# Format : SEMMSL SEMMNS SEMOPM SEMMNI
kernel.sem = 250 32000 100 128

# Détail de chaque valeur :
#
# SEMMSL = 250 : Nombre MAXIMUM de sémaphores par tableau (array)
#   -> Oracle crée des tableaux de sémaphores
#   -> 250 = suffisant pour la plupart des configurations
#
# SEMMNS = 32000 : Nombre TOTAL de sémaphores dans le système
#   -> Toutes applications confondues
#   -> 32000 = adapté pour plusieurs instances Oracle
#
# SEMOPM = 100 : Nombre MAXIMUM d'opérations par appel semop()
#   -> Oracle peut faire jusqu'à 100 opérations atomiques sur des sémaphores
#
# SEMMNI = 128 : Nombre MAXIMUM de tableaux de sémaphores dans le système
#   -> 128 = suffisant pour plusieurs instances

# === I/O ASYNCHRONE (Asynchronous I/O) ===

# fs.aio-max-nr : Nombre MAXIMUM de requêtes d'I/O asynchrones en cours
# Valeur : 1048576 (1 million)
# Pourquoi ? Oracle utilise MASSIVEMENT l'I/O asynchrone pour les datafiles
# Plus il y a de processus Oracle, plus il faut d'AIO slots
fs.aio-max-nr = 1048576

# fs.file-max : Nombre MAXIMUM de file handles (descripteurs de fichiers) système-wide
# Valeur : 6815744
# Pourquoi ? Oracle ouvre BEAUCOUP de fichiers simultanément :
#   - Datafiles, control files, redo logs
#   - Fichiers de trace, alert logs
#   - Connexions réseau (sockets)
#   - Plus tu as de bases/connexions, plus tu as besoin de file handles
fs.file-max = 6815744

# === PORTS RÉSEAU ===

# net.ipv4.ip_local_port_range : Plage de ports pour connexions SORTANTES
# Format : port_min port_max
# Valeur : 9000 à 65500
# Pourquoi ? Oracle listener écoute sur 1521 (par défaut)
# Les connexions clients utilisent des ports éphémères dans cette plage
# Évite les conflits avec les ports Oracle standards (1521, 5500, etc.)
net.ipv4.ip_local_port_range = 9000 65500

# === BUFFERS RÉSEAU ===

# net.core.rmem_default : Taille DEFAULT du buffer de RÉCEPTION réseau
# Valeur : 262144 bytes = 256 KB
# Pourquoi ? Oracle reçoit beaucoup de données via le réseau (connexions clients)
net.core.rmem_default = 262144

# net.core.rmem_max : Taille MAXIMUM du buffer de RÉCEPTION réseau
# Valeur : 4194304 bytes = 4 MB
# Pourquoi ? Pour les transferts de gros volumes (Data Pump, RMAN, etc.)
net.core.rmem_max = 4194304

# net.core.wmem_default : Taille DEFAULT du buffer d'ENVOI réseau
# Valeur : 262144 bytes = 256 KB
net.core.wmem_default = 262144

# net.core.wmem_max : Taille MAXIMUM du buffer d'ENVOI réseau
# Valeur : 1048576 bytes = 1 MB
net.core.wmem_max = 1048576

# === GESTION DE LA MÉMOIRE VIRTUELLE (VM) ===

# vm.swappiness : Agressivité du swap (0-100)
# Valeur : 10
# Pourquoi ?
#   - 0 = ne jamais swapper (sauf urgence absolue)
#   - 100 = swapper agressivement
#   - 10 = utiliser le swap seulement en dernier recours
# Oracle DÉTESTE le swap ! La SGA DOIT rester en RAM.
# Si la SGA est swappée, les performances chutent de 100x ou plus.
vm.swappiness = 10

# vm.dirty_background_ratio : % de RAM avec pages "sales" avant flush en arrière-plan
# Valeur : 3%
# Pourquoi ? "Pages sales" = pages modifiées en RAM pas encore écrites sur disque
# 3% = quand 3% de la RAM est sale, commencer à flusher vers le disque
# Flush agressif = libère la RAM plus rapidement
vm.dirty_background_ratio = 3

# vm.dirty_ratio : % de RAM avec pages sales avant BLOCAGE des écritures
# Valeur : 15%
# Pourquoi ? Si 15% de la RAM est sale, BLOQUER les processus qui écrivent
# jusqu'à ce que le flush soit terminé
# Évite de saturer complètement la RAM avec des pages sales
vm.dirty_ratio = 15

# vm.dirty_expire_centisecs : Temps avant qu'une page sale soit considérée "expirée"
# Valeur : 500 centisecondes = 5 secondes
# Pourquoi ? Les pages sales de plus de 5 secondes seront flushées en priorité
vm.dirty_expire_centisecs = 500

# vm.dirty_writeback_centisecs : Fréquence de réveil du processus de flush
# Valeur : 100 centisecondes = 1 seconde
# Pourquoi ? Le kernel vérifie toutes les 1 seconde s'il faut flusher des pages
vm.dirty_writeback_centisecs = 100

# === NOYAU (Kernel) ===

# kernel.panic_on_oops : Comportement en cas d'erreur kernel grave (oops)
# Valeur : 1 = provoquer un kernel panic (reboot)
# Pourquoi ? En cas d'erreur grave, mieux vaut rebooter que continuer instable
kernel.panic_on_oops = 1

#############################################################################
# Fin des paramètres Oracle
#############################################################################
EOF

  # [TEMPS]  Temps : 1 minute


ÉTAPE 2 : Appliquer les paramètres immédiatement
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Charger les nouveaux paramètres
  $ sudo sysctl -p
  
  # Sortie attendue (extrait) :
  kernel.shmmax = 4398046511104
  kernel.shmall = 1073741824
  kernel.shmmni = 4096
  kernel.sem = 250 32000 100 128
  fs.aio-max-nr = 1048576
  fs.file-max = 6815744
  net.ipv4.ip_local_port_range = 9000 65500
  net.core.rmem_default = 262144
  net.core.rmem_max = 4194304
  net.core.wmem_default = 262144
  net.core.wmem_max = 1048576
  vm.swappiness = 10
  vm.dirty_background_ratio = 3
  vm.dirty_ratio = 15
  vm.dirty_expire_centisecs = 500
  vm.dirty_writeback_centisecs = 100
  kernel.panic_on_oops = 1


ÉTAPE 3 : Vérifier les paramètres kernel individuellement
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Vérifier kernel.shmmax (mémoire partagée max)
  $ sysctl kernel.shmmax
  kernel.shmmax = 4398046511104
  
  # Convertir en unités lisibles
  $ echo "scale=2; 4398046511104 / 1024 / 1024 / 1024" | bc
  4096.00    <- 4 TB
  
  # Vérifier kernel.shmall (pages mémoire partagée)
  $ sysctl kernel.shmall
  kernel.shmall = 1073741824
  
  # Calculer la taille totale (pages × 4 KB)
  $ echo "scale=2; 1073741824 * 4096 / 1024 / 1024 / 1024" | bc
  4096.00    <- 4 TB
  
  # Vérifier les sémaphores
  $ sysctl kernel.sem
  kernel.sem = 250	32000	100	128
  
  # Vérifier l'I/O asynchrone
  $ sysctl fs.aio-max-nr
  fs.aio-max-nr = 1048576
  
  # Vérifier le nombre de file handles
  $ sysctl fs.file-max
  fs.file-max = 6815744
  
  # Vérifier la plage de ports
  $ sysctl net.ipv4.ip_local_port_range
  net.ipv4.ip_local_port_range = 9000	65500
  
  # Vérifier le swappiness
  $ sysctl vm.swappiness
  vm.swappiness = 10


ÉTAPE 4 : Vérifier que les paramètres survivent au reboot
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Les paramètres dans /etc/sysctl.conf sont chargés automatiquement au boot.
  
  Pour tester (optionnel) :
  $ sudo reboot
  
  Après le reboot, se reconnecter et vérifier :
  $ sysctl kernel.shmmax
  kernel.shmmax = 4398046511104
  
  [OK] Si la valeur est correcte, les paramètres sont persistants


┌────────────────────────────────────────────────────────────────────────────┐
│                         POURQUOI CES PARAMÈTRES ?                          │
│                        (Explication approfondie)                           │
└────────────────────────────────────────────────────────────────────────────┘

- MÉMOIRE PARTAGÉE (Shared Memory)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Oracle utilise la mémoire partagée pour la SGA (System Global Area) :
-> Buffer Cache : cache des blocs de données lus depuis les datafiles
-> Shared Pool : cache des requêtes SQL parsées et des métadonnées
-> Redo Log Buffer : buffer des modifications avant écriture dans redo logs
-> Large Pool, Java Pool, Streams Pool, etc.

Sans mémoire partagée suffisante :
[X] Oracle ne peut pas démarrer
[X] Erreur typique : "ORA-27102: out of memory"

Avec kernel.shmmax = 4 TB :
[OK] Tu peux allouer une SGA jusqu'à 4 TB
[OK] Largement suffisant pour 99% des configurations


- SÉMAPHORES (Semaphores)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Oracle utilise les sémaphores pour :
-> Synchroniser les accès aux structures partagées en mémoire
-> Coordonner les processus d'arrière-plan (SMON, PMON, DBWn, LGWR, etc.)
-> Gérer les verrous entre processus

Exemple concret :
-> Process 1 veut modifier le buffer cache
-> Il acquiert un sémaphore (lock)
-> Il fait sa modification
-> Il libère le sémaphore
-> Process 2 peut maintenant acquérir le sémaphore

Sans sémaphores suffisants :
[X] Oracle ne peut pas créer assez de processus
[X] Erreur typique : "ORA-27123: unable to attach to shared memory segment"


- I/O ASYNCHRONE (Asynchronous I/O)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Oracle utilise l'I/O asynchrone pour :
-> Lire/écrire sur les datafiles SANS BLOQUER les processus
-> Maximiser la performance des disques (plusieurs I/O en parallèle)

I/O SYNCHRONE (mauvais) :
  Process demande lecture du bloc 1 -> ATTEND -> reçoit bloc 1
  Process demande lecture du bloc 2 -> ATTEND -> reçoit bloc 2
  Process demande lecture du bloc 3 -> ATTEND -> reçoit bloc 3
  [TEMPS]  Temps total : 3 × 10ms = 30ms

I/O ASYNCHRONE (bon) :
  Process demande lecture blocs 1, 2, 3 simultanément -> CONTINUE son travail
  Blocs 1, 2, 3 arrivent en parallèle
  [TEMPS]  Temps total : 10ms

fs.aio-max-nr = 1048576 :
[OK] Permet jusqu'à 1 million de requêtes I/O asynchrones en attente
[OK] Suffisant pour des milliers de connexions simultanées


- FILE HANDLES (Descripteurs de fichiers)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Oracle ouvre ÉNORMÉMENT de fichiers :
-> Datafiles (system, sysaux, undo, users, etc.)
-> Control files (3 copies)
-> Redo log files (3 groupes × 2 members = 6 fichiers)
-> Fichiers de trace (1 par processus)
-> Alert log
-> Sockets réseau (1 par connexion client)

Calcul approximatif pour une base avec 100 connexions :
  Datafiles : 50
  Control files : 3
  Redo logs : 6
  Fichiers de trace : 200 (processus bg + connexions)
  Sockets : 100
  Divers : 100
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  TOTAL : ~459 file handles

fs.file-max = 6815744 :
[OK] Permet des dizaines de bases de données avec des milliers de connexions


- PORTS RÉSEAU
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Oracle Listener écoute sur le port 1521 (par défaut).
Chaque connexion client utilise un port éphémère (temporaire).

net.ipv4.ip_local_port_range = 9000 65500 :
[OK] Les connexions sortantes utilisent les ports 9000-65500
[OK] Évite les conflits avec :
   - Port 1521 (Oracle Listener)
   - Port 5500 (Oracle Enterprise Manager)
   - Ports < 1024 (services système)


- SWAP
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

vm.swappiness = 10 :

Sans cette configuration (défaut = 60) :
[X] Le kernel swap agressivement la SGA vers le disque
[X] Performance divisée par 100 ou plus
[X] Timeouts des connexions clients
[X] Base de données "gelée"

Avec vm.swappiness = 10 :
[OK] Le kernel garde la SGA en RAM autant que possible
[OK] Swap seulement en cas d'absolue nécessité
[OK] Performances optimales


CONCLUSION SUR LES PARAMÈTRES KERNEL :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Ces paramètres kernel sont CRITIQUES pour Oracle.
Sans eux, Oracle :
[X] Ne démarre pas du tout (erreurs ORA-27102, ORA-27123)
[X] Démarre mais avec des performances catastrophiques
[X] Plante de façon aléatoire

Avec eux :
[OK] Oracle démarre sans problème
[OK] Performances optimales
[OK] Stabilité maximale

[ATTENTION]  NE PAS SAUTER cette étape !


################################################################################
#                                                                              #
#  PARTIE 3 : CRÉATION ET CONFIGURATION DES UTILISATEURS                      #
#                                                                              #
################################################################################

Dans cette partie, nous allons créer les deux utilisateurs principaux :
-> 'grid' : propriétaire de Grid Infrastructure (ASM)
-> 'oracle' : propriétaire d'Oracle Database

Et tous les groupes Unix nécessaires pour gérer les permissions.

═══════════════════════════════════════════════════════════════════════════════
3.1 CRÉATION DES GROUPES UNIX
═══════════════════════════════════════════════════════════════════════════════

Oracle utilise des groupes Unix pour gérer les privilèges d'administration.
Chaque groupe correspond à un rôle administratif spécifique.

┌────────────────────────────────────────────────────────────────────────────┐
│                    GROUPES UNIX ET LEURS RÔLES                             │
└────────────────────────────────────────────────────────────────────────────┘

GROUPES COMMUNS (utilisés par 'grid' ET 'oracle') :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

oinstall (GID 54321)
  -> Groupe propriétaire de l'INVENTAIRE Oracle
  -> TOUS les produits Oracle (Grid, Database, etc.) appartiennent à ce groupe
  -> Groupe primaire de 'grid' et 'oracle'
  -> Permissions : lecture/écriture sur /u01/app/oraInventory/

asmdba (GID 54327)
  -> Groupe pour l'accès ASM depuis les databases
  -> Les utilisateurs de ce groupe peuvent :
     - Se connecter à ASM
     - Lire les disk groups
     - Créer/supprimer des fichiers dans ASM
  -> Membres : 'grid' (admin ASM) et 'oracle' (utilise ASM)


GROUPES SPÉCIFIQUES À GRID INFRASTRUCTURE (utilisateur 'grid') :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

asmadmin (GID 54329)
  -> Groupe d'ADMINISTRATION ASM
  -> Équivalent du rôle SYSASM dans Oracle
  -> Les utilisateurs de ce groupe peuvent :
     - Créer/supprimer des disk groups
     - Ajouter/supprimer des disques
     - Démarrer/arrêter ASM
     - Modifier les paramètres ASM
  -> Membres : 'grid' uniquement

asmoper (GID 54328)
  -> Groupe pour les OPÉRATIONS ASM limitées
  -> Équivalent du rôle SYSOPER dans Oracle
  -> Les utilisateurs de ce groupe peuvent :
     - Démarrer/arrêter ASM
     - Monter/démonter les disk groups
     - Effectuer des backups
  -> Mais NE PEUVENT PAS :
     - Créer/supprimer des disk groups
     - Ajouter/supprimer des disques
  -> Membres : 'grid' (pour les opérations avancées)


GROUPES SPÉCIFIQUES À ORACLE DATABASE (utilisateur 'oracle') :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

dba (GID 54322)
  -> Groupe d'ADMINISTRATION des databases
  -> Équivalent du rôle SYSDBA dans Oracle
  -> Les utilisateurs de ce groupe peuvent :
     - Créer/supprimer des databases
     - Démarrer/arrêter des databases
     - Effectuer toutes opérations d'administration
  -> Membres : 'oracle'

oper (GID 54323)
  -> Groupe pour les OPÉRATIONS limitées sur databases
  -> Équivalent du rôle SYSOPER dans Oracle
  -> Les utilisateurs de ce groupe peuvent :
     - Démarrer/arrêter les databases
     - Effectuer des backups
  -> Mais NE PEUVENT PAS :
     - Créer/supprimer des databases
     - Voir les données utilisateurs
  -> Membres : 'oracle'

backupdba (GID 54324)
  -> Groupe pour les opérations de BACKUP/RESTORE
  -> Équivalent du rôle SYSBACKUP dans Oracle
  -> Les utilisateurs de ce groupe peuvent :
     - Effectuer des sauvegardes RMAN
     - Restaurer des données
  -> Membres : 'oracle'

dgdba (GID 54325)
  -> Groupe pour DATA GUARD
  -> Équivalent du rôle SYSDG dans Oracle
  -> Les utilisateurs de ce groupe peuvent :
     - Gérer Data Guard (réplication)
     - Effectuer des switchovers/failovers
  -> Membres : 'oracle'

kmdba (GID 54326)
  -> Groupe pour KEY MANAGEMENT (chiffrement)
  -> Équivalent du rôle SYSKM dans Oracle
  -> Les utilisateurs de ce groupe peuvent :
     - Gérer les clés de chiffrement TDE
     - Gérer les wallets
  -> Membres : 'oracle'


ÉTAPE 1 : Créer tous les groupes Unix
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Créer le groupe oinstall (inventaire Oracle)
  $ sudo groupadd -g 54321 oinstall
  
  # Créer les groupes Database
  $ sudo groupadd -g 54322 dba
  $ sudo groupadd -g 54323 oper
  $ sudo groupadd -g 54324 backupdba
  $ sudo groupadd -g 54325 dgdba
  $ sudo groupadd -g 54326 kmdba
  
  # Créer les groupes ASM
  $ sudo groupadd -g 54327 asmdba
  $ sudo groupadd -g 54328 asmoper
  $ sudo groupadd -g 54329 asmadmin
  
  Explication des options :
  -g 54321 : Spécifie le GID (Group ID) exact
  
  Pourquoi des GID fixes ?
  -> Facilite la réplication de la configuration sur plusieurs serveurs
  -> Si tu as un cluster RAC, TOUS les serveurs doivent avoir les mêmes GID
  -> Convention Oracle standard


ÉTAPE 2 : Vérifier la création des groupes
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Afficher tous les groupes Oracle
  $ cat /etc/group | grep -E "oinstall|dba|oper|asm"
  
  Sortie attendue :
  oinstall:x:54321:
  dba:x:54322:
  oper:x:54323:
  backupdba:x:54324:
  dgdba:x:54325:
  kmdba:x:54326:
  asmdba:x:54327:
  asmoper:x:54328:
  asmadmin:x:54329:
  
  Format : nom_groupe:x:GID:membres
  
  # Vérifier un groupe spécifique
  $ getent group oinstall
  oinstall:x:54321:
  
  # Lister tous les groupes avec GID 543xx
  $ getent group | awk -F: '$3 >= 54321 && $3 <= 54329 {print $1, $3}' | sort -k2 -n
  oinstall 54321
  dba 54322
  oper 54323
  backupdba 54324
  dgdba 54325
  kmdba 54326
  asmdba 54327
  asmoper 54328
  asmadmin 54329


═══════════════════════════════════════════════════════════════════════════════
3.2 CRÉATION DE L'UTILISATEUR 'grid'
═══════════════════════════════════════════════════════════════════════════════

L'utilisateur 'grid' est le propriétaire de Grid Infrastructure (qui inclut ASM).

ÉTAPE 1 : Créer l'utilisateur 'grid'
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ sudo useradd \
      -u 54331 \
      -g oinstall \
      -G asmadmin,asmdba,asmoper \
      -d /home/grid \
      -s /bin/bash \
      -c "Grid Infrastructure Owner" \
      -m \
      grid
  
  Explication détaillée de chaque option :
  
  -u 54331
  -> UID (User ID) fixe pour 'grid'
  -> Convention : UID différent de 'oracle' (54321)
  -> Si RAC : tous les serveurs doivent avoir le même UID
  
  -g oinstall
  -> Groupe PRIMAIRE : oinstall
  -> Tous les fichiers créés par 'grid' appartiendront à oinstall
  
  -G asmadmin,asmdba,asmoper
  -> Groupes SECONDAIRES (supplémentaires)
  -> asmadmin : administration ASM (SYSASM)
  -> asmdba : accès aux disk groups
  -> asmoper : opérations ASM limitées
  
  -d /home/grid
  -> Répertoire HOME de l'utilisateur
  -> Contiendra les fichiers de configuration (.bash_profile, .bashrc, etc.)
  
  -s /bin/bash
  -> Shell par défaut : bash
  -> Oracle recommande bash ou ksh
  
  -c "Grid Infrastructure Owner"
  -> Commentaire descriptif (champ GECOS)
  -> Apparaît dans les infos utilisateur (finger, etc.)
  
  -m
  -> Créer le répertoire home automatiquement
  -> Copie les fichiers squelettes depuis /etc/skel/
  
  grid
  -> Nom de l'utilisateur


ÉTAPE 2 : Définir un mot de passe pour 'grid'
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ sudo passwd grid
  
  Entrer un mot de passe (exemple : Grid123!@#)
  
  [ATTENTION]  EN PRODUCTION : Utiliser un mot de passe FORT et COMPLEXE
  
  Recommandations :
  [OK] Au moins 12 caractères
  [OK] Majuscules, minuscules, chiffres, symboles
  [OK] Pas de mots du dictionnaire
  [OK] Unique (pas réutilisé ailleurs)


ÉTAPE 3 : Vérifier la création de l'utilisateur 'grid'
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Afficher les infos complètes de 'grid'
  $ id grid
  
  Sortie attendue :
  uid=54331(grid) gid=54321(oinstall) groups=54321(oinstall),54327(asmdba),54328(asmoper),54329(asmadmin)
  
  Interprétation :
  uid=54331(grid)        : UID et nom de l'utilisateur
  gid=54321(oinstall)    : Groupe primaire
  groups=...             : Tous les groupes (primaire + secondaires)
  
  # Vérifier les infos dans /etc/passwd
  $ getent passwd grid
  
  Sortie attendue :
  grid:x:54331:54321:Grid Infrastructure Owner:/home/grid:/bin/bash
  
  Format :
  nom:x:UID:GID:commentaire:home:shell
  
  # Vérifier que le home existe
  $ ls -ld /home/grid
  
  Sortie attendue :
  drwxr-x--- 2 grid oinstall 4096 Dec 19 10:00 /home/grid
  
  Permissions :
  drwxr-x---
  d : répertoire
  rwx : propriétaire (grid) peut lire/écrire/exécuter
  r-x : groupe (oinstall) peut lire/exécuter
  --- : autres n'ont aucun accès


ÉTAPE 4 : Tester la connexion avec l'utilisateur 'grid'
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Se connecter en tant que 'grid'
  $ sudo su - grid
  
  # Vérifier l'utilisateur actuel
  $ whoami
  grid
  
  # Vérifier le répertoire actuel
  $ pwd
  /home/grid
  
  # Vérifier les groupes
  $ groups
  oinstall asmdba asmoper asmadmin
  
  # Sortir de la session grid
  $ exit


═══════════════════════════════════════════════════════════════════════════════
3.3 CRÉATION DE L'UTILISATEUR 'oracle'
═══════════════════════════════════════════════════════════════════════════════

L'utilisateur 'oracle' est le propriétaire d'Oracle Database.

ÉTAPE 1 : Créer l'utilisateur 'oracle'
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ sudo useradd \
      -u 54321 \
      -g oinstall \
      -G dba,oper,backupdba,dgdba,kmdba,asmdba \
      -d /home/oracle \
      -s /bin/bash \
      -c "Oracle Database Owner" \
      -m \
      oracle
  
  Explication détaillée de chaque option :
  
  -u 54321
  -> UID (User ID) fixe pour 'oracle'
  -> Convention Oracle : UID 54321 (différent de grid = 54331)
  -> Si RAC : tous les serveurs doivent avoir le même UID
  
  -g oinstall
  -> Groupe PRIMAIRE : oinstall (comme 'grid')
  -> Tous les fichiers créés par 'oracle' appartiendront à oinstall
  -> Permet à 'oracle' et 'grid' de partager l'inventaire Oracle
  
  -G dba,oper,backupdba,dgdba,kmdba,asmdba
  -> Groupes SECONDAIRES (supplémentaires)
  -> dba : administration database (SYSDBA)
  -> oper : opérations database limitées (SYSOPER)
  -> backupdba : backup/restore (SYSBACKUP)
  -> dgdba : Data Guard (SYSDG)
  -> kmdba : gestion des clés de chiffrement (SYSKM)
  -> asmdba : accès aux disk groups ASM (IMPORTANT !)
  
  [ATTENTION]  TRÈS IMPORTANT : 'oracle' DOIT être membre d'asmdba
  -> Sans asmdba, 'oracle' ne peut PAS accéder aux fichiers sur ASM
  -> La base de données ne pourra PAS démarrer
  
  -d /home/oracle
  -> Répertoire HOME de l'utilisateur
  -> Contiendra les fichiers de configuration (.bash_profile, .bashrc, etc.)
  
  -s /bin/bash
  -> Shell par défaut : bash
  
  -c "Oracle Database Owner"
  -> Commentaire descriptif
  
  -m
  -> Créer le répertoire home automatiquement
  
  oracle
  -> Nom de l'utilisateur


ÉTAPE 2 : Définir un mot de passe pour 'oracle'
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ sudo passwd oracle
  
  Entrer un mot de passe (exemple : Oracle123!@#)
  
  [ATTENTION]  EN PRODUCTION : Utiliser un mot de passe FORT et COMPLEXE
  [ATTENTION]  Différent du mot de passe de 'grid'


ÉTAPE 3 : Vérifier la création de l'utilisateur 'oracle'
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Afficher les infos complètes de 'oracle'
  $ id oracle
  
  Sortie attendue :
  uid=54321(oracle) gid=54321(oinstall) groups=54321(oinstall),54322(dba),54323(oper),54324(backupdba),54325(dgdba),54326(kmdba),54327(asmdba)
  
  [OK] VÉRIFIER QUE : asmdba (54327) est bien dans la liste des groupes
  
  # Vérifier les infos dans /etc/passwd
  $ getent passwd oracle
  
  Sortie attendue :
  oracle:x:54321:54321:Oracle Database Owner:/home/oracle:/bin/bash
  
  # Vérifier que le home existe
  $ ls -ld /home/oracle
  
  Sortie attendue :
  drwxr-x--- 2 oracle oinstall 4096 Dec 19 10:05 /home/oracle


ÉTAPE 4 : Tester la connexion avec l'utilisateur 'oracle'
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Se connecter en tant que 'oracle'
  $ sudo su - oracle
  
  # Vérifier l'utilisateur actuel
  $ whoami
  oracle
  
  # Vérifier le répertoire actuel
  $ pwd
  /home/oracle
  
  # Vérifier les groupes
  $ groups
  oinstall dba oper backupdba dgdba kmdba asmdba
  
  # Sortir de la session oracle
  $ exit


ÉTAPE 5 : Tableau comparatif grid vs oracle
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

┌──────────────────┬───────────────────────┬───────────────────────────────┐
│   Attribut       │  Utilisateur 'grid'   │  Utilisateur 'oracle'         │
├──────────────────┼───────────────────────┼───────────────────────────────┤
│ UID              │ 54331                 │ 54321                         │
│ Groupe primaire  │ oinstall (54321)      │ oinstall (54321)              │
│ Groupes          │ asmadmin, asmdba,     │ dba, oper, backupdba,         │
│ secondaires      │ asmoper               │ dgdba, kmdba, asmdba          │
│ Home directory   │ /home/grid            │ /home/oracle                  │
│ Shell            │ /bin/bash             │ /bin/bash                     │
│ Rôle principal   │ Admin infrastructure  │ Admin databases               │
│ Peut gérer ASM   │ [OK] OUI (asmadmin)     │ [X] NON (lecture seule)        │
│ Peut gérer DB    │ [X] NON                │ [OK] OUI (dba)                  │
│ Accès aux disk   │ [OK] OUI (asmdba)       │ [OK] OUI (asmdba)               │
│ groups           │                       │                               │
└──────────────────┴───────────────────────┴───────────────────────────────┘


═══════════════════════════════════════════════════════════════════════════════
3.4 CONFIGURATION DES LIMITES SYSTÈME
═══════════════════════════════════════════════════════════════════════════════

Les limites système contrôlent les ressources qu'un utilisateur peut consommer.
Oracle nécessite des limites élevées pour fonctionner correctement.

┌────────────────────────────────────────────────────────────────────────────┐
│                     QU'EST-CE QU'UNE "LIMITE SYSTÈME" ?                    │
└────────────────────────────────────────────────────────────────────────────┘

Exemple concret :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Imagine que tu lances une base de données Oracle.
Oracle essaie d'ouvrir 1000 fichiers simultanément.

SANS configuration des limites :
[X] Linux dit : "Désolé, limite = 1024 fichiers ouverts par processus"
[X] Oracle peut ouvrir seulement 1024 fichiers
[X] Oracle manque de file handles -> CRASH
[X] Erreur : "ORA-27054: NFS file system where the file is created or resides is not mounted"

AVEC configuration des limites :
[OK] Linux dit : "OK, tu peux ouvrir jusqu'à 65536 fichiers"
[OK] Oracle ouvre tranquillement ses 1000 fichiers
[OK] Tout fonctionne parfaitement


TYPES DE LIMITES :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

nofile (Number of Open Files)
  -> Nombre de fichiers qu'un processus peut ouvrir simultanément
  -> Inclut : fichiers réguliers, sockets, pipes, etc.
  -> Oracle a besoin de beaucoup de file handles

nproc (Number of Processes)
  -> Nombre de processus qu'un utilisateur peut créer
  -> Oracle crée des dizaines de processus d'arrière-plan
  -> Plus tu as de connexions, plus tu as de processus

stack (Stack Size)
  -> Taille de la pile (stack) pour chaque processus
  -> La pile stocke les variables locales et les appels de fonctions
  -> Oracle utilise beaucoup la récursivité -> besoin d'une grande pile

memlock (Memory Lock)
  -> Quantité de mémoire qu'un processus peut "verrouiller" en RAM
  -> Mémoire verrouillée = ne peut PAS être swappée
  -> Oracle veut verrouiller la SGA en RAM (pas de swap !)


ÉTAPE 1 : Configurer les limites dans /etc/security/limits.conf
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Sauvegarder le fichier original
  $ sudo cp /etc/security/limits.conf /etc/security/limits.conf.backup
  
  # Ajouter les limites Oracle à la fin du fichier
  $ sudo tee -a /etc/security/limits.conf > /dev/null <<'EOF'

#############################################################################
# Limites système pour Oracle Database 19c et Grid Infrastructure
# Ajouté le : $(date)
#############################################################################

# === LIMITES POUR L'UTILISATEUR 'grid' (Grid Infrastructure / ASM) ===

# nofile : Nombre de fichiers ouverts
# soft = limite par défaut (peut être augmentée par l'utilisateur)
# hard = limite maximale absolue (ne peut PAS être dépassée)
grid   soft   nofile    65536
grid   hard   nofile    65536

# Explication :
# Grid Infrastructure ouvre :
#   - Disques ASM (1 file handle par disque)
#   - Fichiers de métadonnées ASM
#   - Sockets réseau (si RAC)
#   - Fichiers de trace
#   - Fichiers de log
# 65536 = suffisant pour des configurations complexes avec RAC

# nproc : Nombre de processus
grid   soft   nproc     16384
grid   hard   nproc     16384

# Explication :
# Grid Infrastructure crée :
#   - Instance ASM (+ASM) : ~20 processus d'arrière-plan
#   - Oracle Clusterware (si RAC) : ~50 processus
#   - Processes de monitoring : ~10 processus
# 16384 = largement suffisant, même pour RAC

# stack : Taille de la pile (stack) en KB
grid   soft   stack     10240
grid   hard   stack     32768

# Explication :
# 10240 KB = 10 MB (soft)
# 32768 KB = 32 MB (hard)
# Oracle utilise des fonctions récursives complexes
# Une pile trop petite -> Stack Overflow -> CRASH

# memlock : Mémoire verrouillée en KB
grid   soft   memlock   unlimited
grid   hard   memlock   unlimited

# Explication :
# unlimited = peut verrouiller TOUTE la RAM disponible
# Nécessaire pour :
#   - Verrouiller la SGA ASM en RAM (pas de swap)
#   - Utiliser les Huge Pages (optimisation mémoire)


# === LIMITES POUR L'UTILISATEUR 'oracle' (Oracle Database) ===

# nofile : Nombre de fichiers ouverts
oracle soft   nofile    65536
oracle hard   nofile    65536

# Explication :
# Oracle Database ouvre ENCORE PLUS de fichiers que Grid :
#   - Datafiles : 10-100+ fichiers
#   - Control files : 3 fichiers
#   - Redo log files : 6-12 fichiers
#   - Temp files : 1-5 fichiers
#   - Archive logs : 100+ fichiers
#   - Fichiers de trace : 1 par connexion client (peut être 1000+)
#   - Sockets réseau : 1 par connexion (peut être 1000+)
# 65536 = suffisant pour 1000+ connexions simultanées

# nproc : Nombre de processus
oracle soft   nproc     16384
oracle hard   nproc     16384

# Explication :
# Oracle Database crée :
#   - Processus d'arrière-plan : ~30 (SMON, PMON, DBWn, LGWR, etc.)
#   - 1 processus serveur par connexion client (mode dédié)
#     OU 1 processus partagé pour N clients (mode partagé)
#   - Processus pour les jobs automatiques
# Exemple : 1000 connexions = ~1050 processus
# 16384 = suffisant pour 10000+ connexions

# stack : Taille de la pile en KB
oracle soft   stack     10240
oracle hard   stack     32768

# Explication :
# Identique à 'grid'
# Requêtes SQL complexes peuvent être très récursives
# Exemple : requête avec 50 niveaux de sous-requêtes imbriquées

# memlock : Mémoire verrouillée en KB
oracle soft   memlock   unlimited
oracle hard   memlock   unlimited

# Explication :
# Oracle Database a une SGA BEAUCOUP plus grande que ASM
# Exemples de tailles SGA :
#   - Petite base : 1-2 GB
#   - Moyenne base : 4-16 GB
#   - Grande base : 32-128 GB
#   - Très grande base : 256 GB - 1 TB
# La SGA DOIT être verrouillée en RAM (pas de swap)

#############################################################################
# Fin des limites Oracle
#############################################################################
EOF


ÉTAPE 2 : Configurer PAM (Pluggable Authentication Modules)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  PAM = système d'authentification modulaire de Linux
  Il faut lui dire d'appliquer les limites définies dans limits.conf
  
  # Vérifier que PAM est configuré pour lire limits.conf
  $ grep pam_limits /etc/pam.d/common-session
  
  Si rien n'apparaît, ajouter la ligne :
  $ echo "session required pam_limits.so" | sudo tee -a /etc/pam.d/common-session
  
  Si la ligne existe déjà :
  session required pam_limits.so
  [OK] C'est bon, PAM est déjà configuré


ÉTAPE 3 : Vérifier les limites pour 'grid'
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Se connecter en tant que 'grid'
  $ sudo su - grid
  
  # Afficher TOUTES les limites actuelles
  $ ulimit -a
  
  Sortie attendue (extrait) :
  core file size          (blocks, -c) unlimited
  data seg size           (kbytes, -d) unlimited
  scheduling priority             (-e) 0
  file size               (blocks, -f) unlimited
  pending signals                 (-i) 31219
  max locked memory       (kbytes, -l) unlimited    <- memlock
  max memory size         (kbytes, -m) unlimited
  open files                      (-n) 65536        <- nofile
  pipe size            (512 bytes, -p) 8
  POSIX message queues     (bytes, -q) 819200
  real-time priority              (-r) 0
  stack size              (kbytes, -s) 10240        <- stack
  cpu time               (seconds, -t) unlimited
  max user processes              (-u) 16384        <- nproc
  virtual memory          (kbytes, -v) unlimited
  file locks                      (-x) unlimited
  
  # Vérifier des limites spécifiques
  $ ulimit -n    # nofile
  65536
  
  $ ulimit -u    # nproc
  16384
  
  $ ulimit -s    # stack (en KB)
  10240
  
  $ ulimit -l    # memlock (en KB)
  unlimited
  
  # Sortir de la session grid
  $ exit


ÉTAPE 4 : Vérifier les limites pour 'oracle'
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Se connecter en tant que 'oracle'
  $ sudo su - oracle
  
  # Vérifier les limites
  $ ulimit -n    # nofile
  65536          [OK]
  
  $ ulimit -u    # nproc
  16384          [OK]
  
  $ ulimit -s    # stack
  10240          [OK]
  
  $ ulimit -l    # memlock
  unlimited      [OK]
  
  # Sortir
  $ exit


ÉTAPE 5 : Que faire si les limites ne sont PAS appliquées ?
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Si tu vois encore les limites par défaut (1024, 4096, etc.) :
  
  1. VÉRIFIER que /etc/security/limits.conf contient bien les lignes Oracle
     $ grep -A2 "grid\|oracle" /etc/security/limits.conf
  
  2. VÉRIFIER que PAM est configuré
     $ grep pam_limits /etc/pam.d/common-session
     Doit afficher : session required pam_limits.so
  
  3. SE RECONNECTER (les limites ne sont appliquées QU'À LA CONNEXION)
     $ sudo su - grid
     OU
     Se déconnecter complètement et se reconnecter via SSH
  
  4. REDÉMARRER le système (en dernier recours)
     $ sudo reboot


═══════════════════════════════════════════════════════════════════════════════
3.5 VARIABLES D'ENVIRONNEMENT
═══════════════════════════════════════════════════════════════════════════════

Les variables d'environnement indiquent à Oracle où trouver ses fichiers.

┌────────────────────────────────────────────────────────────────────────────┐
│                  VARIABLES D'ENVIRONNEMENT ESSENTIELLES                    │
└────────────────────────────────────────────────────────────────────────────┘

ORACLE_BASE
  -> Répertoire racine de TOUTES les installations Oracle
  -> Convention : /u01/app/grid OU /u01/app/oracle
  -> Sous ORACLE_BASE, on trouve les logs, admin files, etc.

ORACLE_HOME
  -> Répertoire contenant le logiciel Oracle (binaires)
  -> Pour grid : /u01/app/19.3.0/grid
  -> Pour oracle : /u01/app/oracle/product/19.3.0/dbhome_1
  -> Contient les exécutables (sqlplus, asmcmd, etc.)

ORACLE_SID
  -> Identifiant de l'instance
  -> Pour ASM : +ASM
  -> Pour database : ORCL, PROD, TEST, etc.
  -> Utilisé pour différencier plusieurs instances sur le même serveur

PATH
  -> Liste des répertoires où chercher les exécutables
  -> Doit inclure $ORACLE_HOME/bin
  -> Sinon, tu dois taper le chemin complet : /u01/app/.../bin/sqlplus

LD_LIBRARY_PATH
  -> Liste des répertoires où chercher les bibliothèques partagées (.so)
  -> Doit inclure $ORACLE_HOME/lib
  -> Sans ça, les binaires Oracle ne trouvent pas leurs bibliothèques


ÉTAPE 1 : Configurer les variables d'environnement pour 'grid'
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Se connecter en tant que 'grid'
  $ sudo su - grid
  
  # Créer/éditer le fichier .bash_profile
  $ cat > ~/.bash_profile << 'EOF'
#############################################################################
# .bash_profile pour l'utilisateur 'grid'
# Grid Infrastructure / Oracle ASM
# Créé le : $(date)
#############################################################################

# === VARIABLES ORACLE DE BASE ===

# ORACLE_BASE : Répertoire racine pour l'utilisateur grid
# Tous les fichiers admin, logs, etc. seront sous ce répertoire
export ORACLE_BASE=/u01/app/grid

# ORACLE_HOME : Répertoire du logiciel Grid Infrastructure
# C'est ici que se trouvent les binaires (asmcmd, sqlplus, crsctl, etc.)
export ORACLE_HOME=/u01/app/19.3.0/grid

# ORACLE_SID : Identifiant de l'instance ASM
# Pour ASM, le SID est TOUJOURS +ASM (ou +ASM1, +ASM2 en RAC)
export ORACLE_SID=+ASM

# ORACLE_TERM : Type de terminal (pour l'affichage)
export ORACLE_TERM=xterm

# === VARIABLES NLS (National Language Support) ===

# NLS_LANG : Langue et jeu de caractères
# Format : language_territory.characterset
export NLS_LANG=AMERICAN_AMERICA.UTF8

# NLS_DATE_FORMAT : Format d'affichage des dates
export NLS_DATE_FORMAT="YYYY-MM-DD HH24:MI:SS"

# === VARIABLES PATH ===

# PATH : Ajouter les binaires Oracle en PREMIER
# $ORACLE_HOME/bin : binaires Grid (asmcmd, crsctl, srvctl, sqlplus)
# $PATH : conserve les autres chemins (système)
export PATH=$ORACLE_HOME/bin:$PATH

# LD_LIBRARY_PATH : Bibliothèques partagées Oracle
# $ORACLE_HOME/lib : bibliothèques .so nécessaires aux binaires Oracle
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH

# === VARIABLES DE CONFIGURATION ===

# ORACLE_HOSTNAME : Nom du serveur (utile pour RAC)
# On utilise la commande hostname pour le récupérer automatiquement
export ORACLE_HOSTNAME=$(hostname)

# TNS_ADMIN : Répertoire contenant les fichiers de config réseau
# listener.ora, tnsnames.ora, sqlnet.ora
export TNS_ADMIN=$ORACLE_HOME/network/admin

# === VARIABLES POUR ASMCMD ===

# ORACLE_ASM : Indique qu'on travaille avec ASM (optionnel mais utile)
export ORACLE_ASM=true

# === VARIABLES DE TERMINAL ===

# EDITOR : Éditeur de texte par défaut (pour les commandes comme 'edit')
export EDITOR=vi

# VISUAL : Éditeur visuel (pour certaines commandes interactives)
export VISUAL=vi

# === ALIAS UTILES ===

# Raccourcis pour les commandes fréquentes
alias sqlplus='rlwrap sqlplus'        # sqlplus avec historique (si rlwrap installé)
alias asmcmd='rlwrap asmcmd'          # asmcmd avec historique
alias ll='ls -la'                      # Liste détaillée
alias alertlog='tail -f $ORACLE_BASE/diag/asm/+asm/$(hostname)/trace/alert_+ASM.log'

# === INVITE DE COMMANDE (PROMPT) ===

# Personnaliser le prompt pour afficher :
# [utilisateur@hôte ORACLE_SID]$ chemin
export PS1='[\u@\h \$ORACLE_SID]\$ '

#############################################################################
# Fin du .bash_profile pour grid
#############################################################################

# Charger également .bashrc s'il existe
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi
EOF

  # [TEMPS]  Temps : 1 minute


ÉTAPE 2 : Recharger le profil de 'grid'
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Toujours en tant que 'grid'
  $ source ~/.bash_profile
  
  OU
  
  # Sortir et se reconnecter (méthode recommandée)
  $ exit
  $ sudo su - grid


ÉTAPE 3 : Vérifier les variables d'environnement de 'grid'
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'grid'
  $ echo $ORACLE_BASE
  /u01/app/grid
  
  $ echo $ORACLE_HOME
  /u01/app/19.3.0/grid
  
  $ echo $ORACLE_SID
  +ASM
  
  $ echo $PATH | tr ':' '\n'
  /u01/app/19.3.0/grid/bin    <- Le répertoire Oracle doit être EN PREMIER
  /usr/local/sbin
  /usr/local/bin
  /usr/sbin
  /usr/bin
  /sbin
  /bin
  
  $ echo $LD_LIBRARY_PATH
  /u01/app/19.3.0/grid/lib
  
  # Afficher TOUTES les variables Oracle
  $ env | grep ORACLE
  ORACLE_BASE=/u01/app/grid
  ORACLE_HOME=/u01/app/19.3.0/grid
  ORACLE_SID=+ASM
  ORACLE_TERM=xterm
  ORACLE_HOSTNAME=oracledb
  ORACLE_ASM=true
  
  # Tester qu'on peut appeler sqlplus (même s'il n'est pas encore installé)
  $ which sqlplus
  /u01/app/19.3.0/grid/bin/sqlplus
  
  OU (si pas encore installé) :
  which: no sqlplus in (/u01/app/19.3.0/grid/bin:...)
  -> C'est normal à ce stade, on n'a pas encore installé Grid Infrastructure


ÉTAPE 4 : Configurer les variables d'environnement pour 'oracle'
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Sortir de la session grid et se connecter en tant que 'oracle'
  $ exit
  $ sudo su - oracle
  
  # Créer/éditer le fichier .bash_profile
  $ cat > ~/.bash_profile << 'EOF'
#############################################################################
# .bash_profile pour l'utilisateur 'oracle'
# Oracle Database
# Créé le : $(date)
#############################################################################

# === VARIABLES ORACLE DE BASE ===

# ORACLE_BASE : Répertoire racine pour l'utilisateur oracle
export ORACLE_BASE=/u01/app/oracle

# ORACLE_HOME : Répertoire du logiciel Oracle Database
export ORACLE_HOME=$ORACLE_BASE/product/19.3.0/dbhome_1

# ORACLE_SID : Identifiant de l'instance de base de données
# Valeur par défaut : ORCL
# Si tu as plusieurs bases, tu changeras cette variable selon la base active
export ORACLE_SID=ORCL

# ORACLE_UNQNAME : Nom unique de la base (pour Data Guard)
# Généralement identique à ORACLE_SID pour une base standalone
export ORACLE_UNQNAME=ORCL

# ORACLE_TERM : Type de terminal
export ORACLE_TERM=xterm

# === VARIABLES NLS (National Language Support) ===

# NLS_LANG : Langue et jeu de caractères
export NLS_LANG=AMERICAN_AMERICA.UTF8

# NLS_DATE_FORMAT : Format d'affichage des dates
export NLS_DATE_FORMAT="YYYY-MM-DD HH24:MI:SS"

# NLS_TIMESTAMP_FORMAT : Format des timestamps
export NLS_TIMESTAMP_FORMAT="YYYY-MM-DD HH24:MI:SS.FF"

# === VARIABLES PATH ===

# PATH : Ajouter les binaires Oracle en PREMIER
export PATH=$ORACLE_HOME/bin:$PATH

# LD_LIBRARY_PATH : Bibliothèques partagées Oracle
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH

# === VARIABLES DE CONFIGURATION ===

# ORACLE_HOSTNAME : Nom du serveur
export ORACLE_HOSTNAME=$(hostname)

# TNS_ADMIN : Répertoire de config réseau
export TNS_ADMIN=$ORACLE_HOME/network/admin

# === VARIABLES POUR RMAN (Recovery Manager) ===

# NLS_DATE_FORMAT pour RMAN
export NLS_DATE_FORMAT_RMAN="DD-MON-YYYY HH24:MI:SS"

# === VARIABLES POUR SQLPLUS ===

# SQLPATH : Répertoires où chercher les scripts SQL
# Permet de faire : @mon_script.sql sans spécifier le chemin
export SQLPATH=$ORACLE_HOME/sqlplus/admin:~/sql

# SQLPROMPT : Personnaliser le prompt SQL*Plus
# Affiche : SQL (SID)>
export SQLPROMPT='SQL (\$ORACLE_SID)> '

# === VARIABLES DE TERMINAL ===

# EDITOR : Éditeur par défaut
export EDITOR=vi

# VISUAL : Éditeur visuel
export VISUAL=vi

# === ALIAS UTILES ===

# Raccourcis pour les commandes fréquentes
alias sqlplus='rlwrap sqlplus'
alias rman='rlwrap rman'
alias ll='ls -la'
alias alertlog='tail -f $ORACLE_BASE/diag/rdbms/$(echo $ORACLE_SID | tr A-Z a-z)/$ORACLE_SID/trace/alert_$ORACLE_SID.log'
alias listenerlog='tail -f $ORACLE_BASE/diag/tnslsnr/$(hostname)/listener/trace/listener.log'

# Alias pour changer de base de données
alias setorcl='export ORACLE_SID=ORCL; export ORACLE_UNQNAME=ORCL'
alias setprod='export ORACLE_SID=PROD; export ORACLE_UNQNAME=PROD'
alias settest='export ORACLE_SID=TEST; export ORACLE_UNQNAME=TEST'

# === INVITE DE COMMANDE (PROMPT) ===

# Prompt personnalisé : [oracle@hôte SID]$ chemin
export PS1='[\u@\h \$ORACLE_SID]\$ '

# === FONCTION UTILE : Changer de SID facilement ===

# Fonction pour changer d'instance
setsid() {
    if [ -z "$1" ]; then
        echo "Usage: setsid <SID>"
        echo "Exemple: setsid PROD"
        return 1
    fi
    export ORACLE_SID=$1
    export ORACLE_UNQNAME=$1
    echo "ORACLE_SID et ORACLE_UNQNAME définis sur : $1"
}

#############################################################################
# Fin du .bash_profile pour oracle
#############################################################################

# Charger .bashrc s'il existe
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi
EOF

  # [TEMPS]  Temps : 1 minute


ÉTAPE 5 : Recharger le profil de 'oracle'
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Recharger les variables
  $ source ~/.bash_profile
  
  OU
  
  $ exit
  $ sudo su - oracle


ÉTAPE 6 : Vérifier les variables d'environnement de 'oracle'
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'oracle'
  $ echo $ORACLE_BASE
  /u01/app/oracle
  
  $ echo $ORACLE_HOME
  /u01/app/oracle/product/19.3.0/dbhome_1
  
  $ echo $ORACLE_SID
  ORCL
  
  $ echo $PATH | tr ':' '\n' | head -3
  /u01/app/oracle/product/19.3.0/dbhome_1/bin    <- Oracle en premier
  /usr/local/sbin
  /usr/local/bin
  
  $ echo $LD_LIBRARY_PATH
  /u01/app/oracle/product/19.3.0/dbhome_1/lib
  
  # Afficher toutes les variables Oracle
  $ env | grep ORACLE
  ORACLE_BASE=/u01/app/oracle
  ORACLE_HOME=/u01/app/oracle/product/19.3.0/dbhome_1
  ORACLE_SID=ORCL
  ORACLE_UNQNAME=ORCL
  ORACLE_TERM=xterm
  ORACLE_HOSTNAME=oracledb
  
  # Tester la fonction setsid
  $ setsid PROD
  ORACLE_SID et ORACLE_UNQNAME définis sur : PROD
  
  $ echo $ORACLE_SID
  PROD
  
  $ setsid ORCL
  ORACLE_SID et ORACLE_UNQNAME définis sur : ORCL


ÉTAPE 7 : Comprendre la différence entre les variables de grid et oracle
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

┌──────────────────┬────────────────────────────────┬────────────────────────────────────┐
│   Variable       │  Utilisateur 'grid'            │  Utilisateur 'oracle'              │
├──────────────────┼────────────────────────────────┼────────────────────────────────────┤
│ ORACLE_BASE      │ /u01/app/grid                  │ /u01/app/oracle                    │
│ ORACLE_HOME      │ /u01/app/19.3.0/grid           │ /u01/app/oracle/.../dbhome_1       │
│ ORACLE_SID       │ +ASM                           │ ORCL (ou PROD, TEST, etc.)         │
│ PATH             │ $ORACLE_HOME/bin:...           │ $ORACLE_HOME/bin:...               │
│ LD_LIBRARY_PATH  │ $ORACLE_HOME/lib:...           │ $ORACLE_HOME/lib:...               │
│ Binaires dispos  │ asmcmd, crsctl, srvctl         │ sqlplus, rman, expdp, impdp        │
└──────────────────┴────────────────────────────────┴────────────────────────────────────┘

  [ATTENTION]  IMPORTANT :
  Si tu es connecté en tant que 'grid' et que tu tapes 'sqlplus' :
  -> Tu utilises le sqlplus de GRID_HOME (pour ASM)
  
  Si tu es connecté en tant que 'oracle' et que tu tapes 'sqlplus' :
  -> Tu utilises le sqlplus d'ORACLE_HOME (pour la base de données)
  
  Ce sont deux binaires DIFFÉRENTS, même s'ils s'appellent tous les deux 'sqlplus' !


┌────────────────────────────────────────────────────────────────────────────┐
│                      RÉCAPITULATIF DE LA PARTIE 3                          │
└────────────────────────────────────────────────────────────────────────────┘

[OK] Groupes Unix créés (9 groupes)
   oinstall, dba, oper, backupdba, dgdba, kmdba, asmdba, asmoper, asmadmin

[OK] Utilisateur 'grid' créé
   UID 54331, groupe primaire oinstall, groupes secondaires asmadmin/asmdba/asmoper

[OK] Utilisateur 'oracle' créé
   UID 54321, groupe primaire oinstall, groupes secondaires dba/oper/.../asmdba

[OK] Limites système configurées
   nofile=65536, nproc=16384, stack=10240, memlock=unlimited

[OK] Variables d'environnement configurées
   ORACLE_BASE, ORACLE_HOME, ORACLE_SID, PATH, LD_LIBRARY_PATH

[TEMPS]  Temps total de la partie 3 : 30-45 minutes


################################################################################
#                                                                              #
#  PARTIE 4 : PRÉPARATION DU STOCKAGE                                         #
#                                                                              #
################################################################################

Dans cette partie, nous allons :
1. Identifier les disques physiques disponibles
2. Les préparer pour ASM (partition, formatage, etc.)
3. Configurer UDEV pour des noms de disques persistants
4. Définir les permissions appropriées

═══════════════════════════════════════════════════════════════════════════════
4.1 COMPRENDRE LES BESOINS EN DISQUES
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│                    QU'EST-CE QU'UN "DISK GROUP" ASM ?                      │
└────────────────────────────────────────────────────────────────────────────┘

Un disk group = Pool de stockage logique composé de plusieurs disques physiques

Analogie :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Imagine que tu as 5 disques durs de 20 GB chacun.

SANS ASM (système de fichiers classique) :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  /dev/sdb -> Monté sur /oradata1 (20 GB)
  /dev/sdc -> Monté sur /oradata2 (20 GB)
  /dev/sdd -> Monté sur /oradata3 (20 GB)
  /dev/sde -> Monté sur /oradata4 (20 GB)
  /dev/sdf -> Monté sur /oradata5 (20 GB)

  Tu dois MANUELLEMENT répartir tes fichiers :
  - users01.dbf -> /oradata1/users01.dbf
  - users02.dbf -> /oradata2/users02.dbf
  - users03.dbf -> /oradata3/users03.dbf

  Si /oradata1 est plein -> Tu dois MANUELLEMENT déplacer des fichiers


AVEC ASM (disk group) :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  /dev/sdb ───┐
  /dev/sdc ───┤
  /dev/sdd ───┼──-> DISK GROUP "DATA" (100 GB logique)
  /dev/sde ───┤
  /dev/sdf ───┘

  ASM voit 1 SEUL GRAND ESPACE de 100 GB.
  Tu créer un fichier :
  - CREATE TABLESPACE users DATAFILE '+DATA' SIZE 50G;

  ASM répartit AUTOMATIQUEMENT les 50 GB sur les 5 disques :
  - /dev/sdb : 10 GB
  - /dev/sdc : 10 GB
  - /dev/sdd : 10 GB
  - /dev/sde : 10 GB
  - /dev/sdf : 10 GB

  Si tu ajoutes un 6ème disque :
  - ASM RÉÉQUILIBRE automatiquement
  - Chaque disque aura maintenant 8.3 GB du fichier


NIVEAUX DE REDONDANCE (Redundancy) :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

EXTERNAL (pas de redondance ASM)
  -> 1 seule copie des données
  -> Utiliser si :
     - Tu as du RAID matériel (contrôleur RAID)
     - Tu es en mode test/développement
     - Tu veux la capacité maximale
  -> Capacité utilisable : 100% (5 × 20 GB = 100 GB)
  -> Si 1 disque meurt -> PERTE DE DONNÉES

NORMAL (mirroring 2-way)
  -> 2 copies des données (miroir)
  -> ASM stocke chaque bloc sur 2 disques différents
  -> Recommandé pour la plupart des configurations
  -> Capacité utilisable : 50% (5 × 20 GB ÷ 2 = 50 GB)
  -> Si 1 disque meurt -> Pas de perte, bascule sur la copie miroir

HIGH (mirroring 3-way)
  -> 3 copies des données (triple miroir)
  -> ASM stocke chaque bloc sur 3 disques différents
  -> Utilisé pour les données CRITIQUES (redo logs, voting disk)
  -> Capacité utilisable : 33% (5 × 20 GB ÷ 3 = 33 GB)
  -> Peut perdre jusqu'à 2 disques sans perte de données


DISK GROUPS TYPIQUES DANS UNE INSTALLATION ORACLE :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

1. DISK GROUP "DATA" (obligatoire)
   -> Contenu :
      - Datafiles (system, sysaux, users, etc.)
      - Control files
      - SPFILE
   -> Redondance : NORMAL (mirroring 2-way)
   -> Taille recommandée : 50-100 GB minimum (selon la taille de ta base)

2. DISK GROUP "FRA" (Fast Recovery Area, fortement recommandé)
   -> Contenu :
      - Archived redo logs
      - Backups RMAN
      - Flashback logs
   -> Redondance : NORMAL
   -> Taille recommandée : 2-3× la taille de DATA

3. DISK GROUP "REDO" (optionnel, pour les bases critiques)
   -> Contenu :
      - Online redo logs
   -> Redondance : HIGH (triple miroir)
   -> Taille : 10-20 GB suffit
   -> Pourquoi séparé ? Les redo logs sont CRITIQUES. Si tu les perds, tu perds TOUTES les transactions non commitées.


CONFIGURATION RECOMMANDÉE POUR CE GUIDE :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Nous allons créer 2 disk groups :

DISK GROUP DATA :
  - 3 disques de 20 GB chacun
  - Redondance NORMAL (2-way mirror)
  - Capacité utilisable : 30 GB (60 GB total ÷ 2)
  - Disques : /dev/sdb, /dev/sdc, /dev/sdd

DISK GROUP FRA :
  - 2 disques de 20 GB chacun
  - Redondance NORMAL
  - Capacité utilisable : 20 GB (40 GB total ÷ 2)
  - Disques : /dev/sde, /dev/sdf

TOTAL : 5 disques de 20 GB = 100 GB physique -> 50 GB utilisable


═══════════════════════════════════════════════════════════════════════════════
4.2 IDENTIFICATION DES DISQUES PHYSIQUES
═══════════════════════════════════════════════════════════════════════════════

ÉTAPE 1 : Lister tous les disques du système
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Lister tous les périphériques de bloc
  $ lsblk
  
  Sortie exemple :
  NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
  sda      8:0    0   50G  0 disk 
  ├─sda1   8:1    0    1M  0 part 
  ├─sda2   8:2    0    1G  0 part /boot
  └─sda3   8:3    0   49G  0 part /
  sdb      8:16   0   20G  0 disk            <- Disque LIBRE (pas de partitions)
  sdc      8:32   0   20G  0 disk            <- Disque LIBRE
  sdd      8:48   0   20G  0 disk            <- Disque LIBRE
  sde      8:64   0   20G  0 disk            <- Disque LIBRE
  sdf      8:80   0   20G  0 disk            <- Disque LIBRE
  sr0     11:0    1 1024M  0 rom
  
  Interprétation :
  sda      : Disque système (50 GB) avec 3 partitions -> NE PAS TOUCHER
  sdb-sdf  : Disques de 20 GB sans partitions -> DISPONIBLES pour ASM
  sr0      : Lecteur CD/DVD -> Ignorer
  
  [ATTENTION]  Les disques pour ASM doivent être :
     - VIDES (pas de partitions)
     - NON MONTÉS (pas de MOUNTPOINT)
     - PAS utilisés par LVM ou RAID logiciel


ÉTAPE 2 : Vérifier qu'aucun disque n'est monté
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Afficher tous les points de montage
  $ df -h | grep -E "sdb|sdc|sdd|sde|sdf"
  
  Résultat attendu : AUCUNE sortie
  
  Si tu vois quelque chose comme :
  /dev/sdb1       20G  100M   19G   1% /mnt/data
  
  [X] Ce disque est MONTÉ -> il faut le démonter et supprimer les partitions


ÉTAPE 3 : Vérifier qu'aucun disque n'a de système de fichiers
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Vérifier le type de système de fichiers sur chaque disque
  $ sudo blkid /dev/sdb /dev/sdc /dev/sdd /dev/sde /dev/sdf
  
  Résultat attendu : AUCUNE sortie (ou "no such device")
  
  Si tu vois quelque chose comme :
  /dev/sdb: UUID="abc123" TYPE="ext4"
  
  [X] Ce disque a un système de fichiers -> il faut l'effacer


ÉTAPE 4 : Vérifier qu'aucun disque n'est utilisé par LVM
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Lister les volumes physiques LVM
  $ sudo pvs
  
  Résultat attendu : Ne PAS voir sdb, sdc, sdd, sde, sdf dans la liste
  
  Si tu vois :
  PV         VG     Fmt  Attr PSize  PFree 
  /dev/sdb   vg01   lvm2 a--  20.00g 20.00g
  
  [X] Ce disque est utilisé par LVM -> il faut retirer le PV :
  $ sudo vgremove vg01
  $ sudo pvremove /dev/sdb


ÉTAPE 5 : Vérifier les signatures de disque (magic bytes)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Vérifier la présence de signatures filesystem/LVM/RAID
  $ sudo wipefs /dev/sdb /dev/sdc /dev/sdd /dev/sde /dev/sdf
  
  Résultat attendu : AUCUNE sortie
  
  Si tu vois des signatures :
  DEVICE OFFSET  TYPE
  sdb    0x438   ext4
  sdb    0x0     dos
  
  [X] Il y a des signatures -> les effacer avec :
  $ sudo wipefs -a /dev/sdb


ÉTAPE 6 : Afficher les détails techniques des disques
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Utiliser fdisk pour voir les détails
  $ sudo fdisk -l /dev/sdb
  
  Sortie attendue :
  Disk /dev/sdb: 20 GiB, 21474836480 bytes, 41943040 sectors
  Disk model: VMware Virtual S
  Units: sectors of 1 * 512 = 512 bytes
  Sector size (logical/physical): 512 bytes / 512 bytes
  I/O size (minimum/optimal): 512 bytes / 512 bytes
  Disklabel type: dos
  Disk identifier: 0x00000000
  
  [ATTENTION]  Si tu vois "Disklabel type: dos" ou "gpt" :
  -> Il y a une table de partitions
  -> Mais si aucune partition n'est listée en dessous, c'est OK (table vide)
  
  [ATTENTION]  Si tu vois des partitions listées :
  Device     Boot Start      End  Sectors Size Id Type
  /dev/sdb1        2048 41943039 41940992  20G 83 Linux
  
  -> Il faut supprimer ces partitions (voir étape suivante)


═══════════════════════════════════════════════════════════════════════════════
4.3 NETTOYAGE ET PRÉPARATION DES DISQUES (SI NÉCESSAIRE)
═══════════════════════════════════════════════════════════════════════════════

[ATTENTION]  ATTENTION : Cette étape DÉTRUIT TOUTES LES DONNÉES sur les disques !
[ATTENTION]  VÉRIFIE que tu sélectionnes les BONS disques (pas sda, le disque système !)

Si tes disques sont déjà vierges (pas de partitions, pas de filesystem) :
[OK] Tu peux SAUTER cette section et passer à la section 4.4


ÉTAPE 1 : Démonter les disques (si montés)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Pour chaque disque monté
  $ sudo umount /dev/sdb1
  $ sudo umount /dev/sdc1
  # ... etc


ÉTAPE 2 : Effacer toutes les signatures
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Pour chaque disque
  $ sudo wipefs -a /dev/sdb
  $ sudo wipefs -a /dev/sdc
  $ sudo wipefs -a /dev/sdd
  $ sudo wipefs -a /dev/sde
  $ sudo wipefs -a /dev/sdf
  
  Sortie attendue :
  /dev/sdb: 2 bytes were erased at offset 0x00000438 (ext4): 53 ef
  /dev/sdb: 8 bytes were erased at offset 0x00000000 (dos): 00 00 00 00 00 00 00 00


ÉTAPE 3 : Effacer le début des disques (zeros)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Pour être sûr qu'il ne reste aucune trace :
  
  # Écrire des zeros sur les 10 premiers MB de chaque disque
  $ sudo dd if=/dev/zero of=/dev/sdb bs=1M count=10 oflag=direct
  $ sudo dd if=/dev/zero of=/dev/sdc bs=1M count=10 oflag=direct
  $ sudo dd if=/dev/zero of=/dev/sdd bs=1M count=10 oflag=direct
  $ sudo dd if=/dev/zero of=/dev/sde bs=1M count=10 oflag=direct
  $ sudo dd if=/dev/zero of=/dev/sdf bs=1M count=10 oflag=direct
  
  Explication de la commande :
  dd                : Commande de copie bas niveau
  if=/dev/zero      : Input file = source de zeros (fichier spécial)
  of=/dev/sdb       : Output file = destination (le disque)
  bs=1M             : Block size = 1 MB (taille des blocs)
  count=10          : Nombre de blocs = 10 (donc 10 MB au total)
  oflag=direct      : Écriture directe (bypass du cache système)
  
  Sortie attendue :
  10+0 records in
  10+0 records out
  10485760 bytes (10 MB, 10 MiB) copied, 0.5 s, 21 MB/s


ÉTAPE 4 : Vérifier que les disques sont maintenant vierges
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ lsblk | grep -E "sdb|sdc|sdd|sde|sdf"
  
  Sortie attendue :
  sdb      8:16   0   20G  0 disk 
  sdc      8:32   0   20G  0 disk 
  sdd      8:48   0   20G  0 disk 
  sde      8:64   0   20G  0 disk 
  sdf      8:80   0   20G  0 disk 
  
  [OK] Aucune partition, aucun point de montage = PARFAIT
  
  $ sudo blkid /dev/sdb /dev/sdc /dev/sdd /dev/sde /dev/sdf
  
  Résultat attendu : AUCUNE sortie
  
  [OK] Les disques sont maintenant propres et prêts pour ASM


═══════════════════════════════════════════════════════════════════════════════
4.4 CONFIGURATION UDEV POUR LA PERSISTANCE DES NOMS
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│                   POURQUOI CONFIGURER UDEV ?                               │
└────────────────────────────────────────────────────────────────────────────┘

PROBLÈME : Les noms de périphériques peuvent CHANGER après un reboot
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Avant reboot :
  Disque 1 : /dev/sdb (pour disk group DATA)
  Disque 2 : /dev/sdc (pour disk group DATA)
  Disque 3 : /dev/sdd (pour disk group DATA)

Après reboot :
  Disque 1 : /dev/sdc (oups, changé !)
  Disque 2 : /dev/sdd (oups, changé !)
  Disque 3 : /dev/sdb (oups, changé !)

[X] ASM ne retrouve plus ses disques
[X] L'instance ASM ne démarre pas
[X] Les bases de données ne démarrent pas
[X] CATASTROPHE !


SOLUTION : Utiliser UDEV pour créer des liens persistants
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

UDEV = gestionnaire de périphériques dynamique de Linux
Il peut créer des liens symboliques basés sur des attributs FIXES du disque :
  - Numéro de série du disque
  - UUID (identifiant unique)
  - WWN (World Wide Name, pour disques SAN)

Exemple :
  Disque physique : /dev/sdb (peut changer)
  Lien UDEV persistant : /dev/oracleasm/disk1 -> /dev/sdb (ne change JAMAIS)

ASM utilise /dev/oracleasm/disk1 (qui pointe toujours vers le bon disque physique)


ÉTAPE 1 : Créer le répertoire pour les liens UDEV
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ sudo mkdir -p /dev/oracleasm
  
  Ce répertoire contiendra les liens symboliques vers les disques ASM.


ÉTAPE 2 : Identifier les attributs uniques de chaque disque
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Obtenir les attributs UDEV de chaque disque
  $ sudo udevadm info --query=all --name=/dev/sdb | grep -E "ID_SERIAL|ID_WWN"
  
  Sortie exemple :
  E: ID_SERIAL=VMware_Virtual_disk_12345678
  E: ID_SERIAL_SHORT=12345678
  E: ID_WWN=0x600508b1001c1234
  
  Répéter pour chaque disque :
  $ sudo udevadm info --query=all --name=/dev/sdc | grep -E "ID_SERIAL"
  $ sudo udevadm info --query=all --name=/dev/sdd | grep -E "ID_SERIAL"
  $ sudo udevadm info --query=all --name=/dev/sde | grep -E "ID_SERIAL"
  $ sudo udevadm info --query=all --name=/dev/sdf | grep -E "ID_SERIAL"
  
  Noter le ID_SERIAL ou ID_WWN de chaque disque.
  
  [ATTENTION]  Si tu n'as PAS de numéro de série (par exemple sur des disques virtuels) :
  Tu peux utiliser la SIZE (taille) ET la position du disque, mais c'est moins fiable.
  Alternative : utiliser UUID (voir plus bas).


ÉTAPE 3 : Créer une règle UDEV
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Créer le fichier de règles UDEV
  $ sudo nano /etc/udev/rules.d/99-oracle-asmdevices.rules
  
  Ajouter le contenu suivant (adapter selon tes ID_SERIAL réels) :
  
  #############################################################################
  # Règles UDEV pour les disques Oracle ASM
  # Créé le : $(date)
  #
  # Format : KERNEL=="sd*", ATTR{size}=="taille", SYMLINK+="oracleasm/diskN"
  # OU : KERNEL=="sd*", ENV{ID_SERIAL}=="serial", SYMLINK+="oracleasm/diskN"
  #############################################################################
  
  # Disk 1 pour DATA disk group
  KERNEL=="sd*", ENV{ID_SERIAL}=="VMware_Virtual_disk_12345678", SYMLINK+="oracleasm/disk1", OWNER="grid", GROUP="asmadmin", MODE="0660"
  
  # Disk 2 pour DATA disk group
  KERNEL=="sd*", ENV{ID_SERIAL}=="VMware_Virtual_disk_23456789", SYMLINK+="oracleasm/disk2", OWNER="grid", GROUP="asmadmin", MODE="0660"
  
  # Disk 3 pour DATA disk group
  KERNEL=="sd*", ENV{ID_SERIAL}=="VMware_Virtual_disk_34567890", SYMLINK+="oracleasm/disk3", OWNER="grid", GROUP="asmadmin", MODE="0660"
  
  # Disk 4 pour FRA disk group
  KERNEL=="sd*", ENV{ID_SERIAL}=="VMware_Virtual_disk_45678901", SYMLINK+="oracleasm/disk4", OWNER="grid", GROUP="asmadmin", MODE="0660"
  
  # Disk 5 pour FRA disk group
  KERNEL=="sd*", ENV{ID_SERIAL}=="VMware_Virtual_disk_56789012", SYMLINK+="oracleasm/disk5", OWNER="grid", GROUP="asmadmin", MODE="0660"
  
  Explication de chaque ligne :
  
  KERNEL=="sd*"
  -> Appliquer cette règle à tous les périphériques sdX
  
  ENV{ID_SERIAL}=="VMware_Virtual_disk_12345678"
  -> Condition : ce périphérique a ce numéro de série spécifique
  
  SYMLINK+="oracleasm/disk1"
  -> Créer un lien symbolique : /dev/oracleasm/disk1 -> /dev/sdX
  
  OWNER="grid"
  -> Le propriétaire du lien sera 'grid'
  
  GROUP="asmadmin"
  -> Le groupe sera 'asmadmin'
  
  MODE="0660"
  -> Permissions : rw-rw---- (lecture/écriture pour owner et group, rien pour others)
  
  Sauvegarder et quitter (Ctrl+O, Enter, Ctrl+X)


ALTERNATIVE : Si tu n'as PAS de numéro de série (disques virtuels simples)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Tu peux utiliser le nom du périphérique kernel directement (moins fiable) :
  
  # Disques ASM (méthode simple, moins robuste)
  KERNEL=="sdb", SYMLINK+="oracleasm/disk1", OWNER="grid", GROUP="asmadmin", MODE="0660"
  KERNEL=="sdc", SYMLINK+="oracleasm/disk2", OWNER="grid", GROUP="asmadmin", MODE="0660"
  KERNEL=="sdd", SYMLINK+="oracleasm/disk3", OWNER="grid", GROUP="asmadmin", MODE="0660"
  KERNEL=="sde", SYMLINK+="oracleasm/disk4", OWNER="grid", GROUP="asmadmin", MODE="0660"
  KERNEL=="sdf", SYMLINK+="oracleasm/disk5", OWNER="grid", GROUP="asmadmin", MODE="0660"
  
  [ATTENTION]  ATTENTION : Cette méthode n'est PAS persistante si l'ordre des disques change !
  [ATTENTION]  À utiliser UNIQUEMENT pour des tests ou si tu ne peux pas obtenir de numéro de série


ÉTAPE 4 : Recharger les règles UDEV
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Recharger les règles UDEV
  $ sudo udevadm control --reload-rules
  
  # Appliquer les règles aux périphériques existants
  $ sudo udevadm trigger
  
  # Attendre que UDEV termine
  $ sudo udevadm settle


ÉTAPE 5 : Vérifier que les liens sont créés
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Lister le répertoire oracleasm
  $ ls -l /dev/oracleasm/
  
  Sortie attendue :
  total 0
  lrwxrwxrwx 1 root root 6 Dec 19 12:00 disk1 -> ../sdb
  lrwxrwxrwx 1 root root 6 Dec 19 12:00 disk2 -> ../sdc
  lrwxrwxrwx 1 root root 6 Dec 19 12:00 disk3 -> ../sdd
  lrwxrwxrwx 1 root root 6 Dec 19 12:00 disk4 -> ../sde
  lrwxrwxrwx 1 root root 6 Dec 19 12:00 disk5 -> ../sdf
  
  [OK] Les liens symboliques sont créés
  
  # Vérifier les permissions
  $ ls -lh /dev/oracleasm/
  
  Sortie attendue (vérifier OWNER et GROUP) :
  lrwxrwxrwx 1 grid asmadmin 6 Dec 19 12:00 disk1 -> ../sdb
  lrwxrwxrwx 1 grid asmadmin 6 Dec 19 12:00 disk2 -> ../sdc
  ...
  
  # Vérifier que les périphériques cibles ont les bonnes permissions
  $ ls -lh /dev/sd[b-f]
  
  Sortie attendue :
  brw-rw---- 1 grid asmadmin 8, 16 Dec 19 12:00 /dev/sdb
  brw-rw---- 1 grid asmadmin 8, 32 Dec 19 12:00 /dev/sdc
  brw-rw---- 1 grid asmadmin 8, 48 Dec 19 12:00 /dev/sdd
  brw-rw---- 1 grid asmadmin 8, 64 Dec 19 12:00 /dev/sde
  brw-rw---- 1 grid asmadmin 8, 80 Dec 19 12:00 /dev/sdf
  
  Interprétation des permissions :
  brw-rw----
  b   : block device (périphérique de bloc = disque)
  rw- : propriétaire (grid) peut lire/écrire
  rw- : groupe (asmadmin) peut lire/écrire
  --- : autres n'ont AUCUN accès
  
  [OK] Les permissions sont correctes


ÉTAPE 6 : Tester que les liens survivent à un reboot
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Noter les cibles actuelles des liens
  $ ls -l /dev/oracleasm/
  disk1 -> ../sdb
  disk2 -> ../sdc
  disk3 -> ../sdd
  disk4 -> ../sde
  disk5 -> ../sdf
  
  # Redémarrer le système
  $ sudo reboot
  
  # Après le reboot, vérifier que les liens existent toujours
  $ ls -l /dev/oracleasm/
  disk1 -> ../sdb    <- Devrait pointer vers le MÊME disque physique
  disk2 -> ../sdc    <- (même si l'ordre des disques a changé)
  disk3 -> ../sdd
  disk4 -> ../sde
  disk5 -> ../sdf
  
  [OK] Si les liens existent et pointent vers les bons disques, UDEV est bien configuré


═══════════════════════════════════════════════════════════════════════════════
4.5 VÉRIFICATION FINALE DU STOCKAGE
═══════════════════════════════════════════════════════════════════════════════

ÉTAPE 1 : Vérifier que 'grid' peut accéder aux disques
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Se connecter en tant que 'grid'
  $ sudo su - grid
  
  # Tenter de lire depuis chaque disque
  $ dd if=/dev/oracleasm/disk1 of=/dev/null bs=1M count=1
  1+0 records in
  1+0 records out
  1048576 bytes (1.0 MB, 1.0 MiB) copied, 0.002 s, 524 MB/s
  [OK] Lecture réussie
  
  # Tenter d'écrire sur un disque (attention, ça écrase les données !)
  $ dd if=/dev/zero of=/dev/oracleasm/disk1 bs=1M count=1 oflag=direct
  1+0 records in
  1+0 records out
  1048576 bytes (1.0 MB, 1.0 MiB) copied, 0.010 s, 105 MB/s
  [OK] Écriture réussie
  
  # Sortir de la session grid
  $ exit


ÉTAPE 2 : Vérifier que 'oracle' peut aussi accéder aux disques
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Se connecter en tant que 'oracle'
  $ sudo su - oracle
  
  # Vérifier la lecture
  $ dd if=/dev/oracleasm/disk1 of=/dev/null bs=1M count=1
  1+0 records in
  1+0 records out
  [OK] 'oracle' peut lire (c'est le groupe asmdba qui donne ce droit)
  
  # Vérifier l'écriture
  $ dd if=/dev/zero of=/dev/oracleasm/disk1 bs=1M count=1 oflag=direct
  dd: failed to open '/dev/oracleasm/disk1': Permission denied
  [X] 'oracle' ne peut PAS écrire directement sur les disques (NORMAL)
  
  Pourquoi ?
  -> Les permissions sont rw-rw----
  -> Propriétaire = grid (rw)
  -> Groupe = asmadmin (rw)
  -> 'oracle' est membre de asmdba, PAS de asmadmin
  -> 'oracle' peut LIRE (pour accéder aux fichiers ASM)
  -> Mais ne peut PAS écrire directement sur les disques (sécurité)
  -> L'écriture se fait via l'instance ASM (gérée par 'grid')
  
  # Sortir
  $ exit


ÉTAPE 3 : Créer un fichier récapitulatif
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Créer un fichier documentant la configuration des disques
  $ sudo tee /root/asm_disk_mapping.txt > /dev/null <<'EOF'
#############################################################################
# Configuration des disques ASM
# Date : $(date)
# Serveur : $(hostname)
#############################################################################

DISK GROUP DATA (3 disques, NORMAL redundancy, ~30 GB utilisable)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  /dev/oracleasm/disk1 -> /dev/sdb (20 GB)
  /dev/oracleasm/disk2 -> /dev/sdc (20 GB)
  /dev/oracleasm/disk3 -> /dev/sdd (20 GB)

DISK GROUP FRA (2 disques, NORMAL redundancy, ~20 GB utilisable)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  /dev/oracleasm/disk4 -> /dev/sde (20 GB)
  /dev/oracleasm/disk5 -> /dev/sdf (20 GB)

PERMISSIONS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  Owner: grid
  Group: asmadmin
  Mode: 0660 (rw-rw----)
  
  'grid' (membre de asmadmin) : lecture + écriture
  'oracle' (membre de asmdba) : lecture seule
  Autres : aucun accès

#############################################################################
EOF
  
  # Afficher le fichier
  $ cat /root/asm_disk_mapping.txt


┌────────────────────────────────────────────────────────────────────────────┐
│                      RÉCAPITULATIF DE LA PARTIE 4                          │
└────────────────────────────────────────────────────────────────────────────┘

[OK] 5 disques de 20 GB identifiés et nettoyés
   /dev/sdb, /dev/sdc, /dev/sdd, /dev/sde, /dev/sdf

[OK] Règles UDEV créées pour des liens persistants
   /dev/oracleasm/disk1 -> disk5

[OK] Permissions configurées
   Owner: grid, Group: asmadmin, Mode: 0660

[OK] Accès vérifié pour 'grid' (lecture + écriture)
[OK] Accès vérifié pour 'oracle' (lecture seule via asmdba)

[TEMPS]  Temps total de la partie 4 : 20-30 minutes

PROCHAINE ÉTAPE : Installation de Grid Infrastructure
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Dans la partie 5, nous allons :
1. Télécharger Oracle Grid Infrastructure 19c
2. Créer l'arborescence de répertoires
3. Installer Grid Infrastructure en mode silencieux
4. Créer automatiquement le disk group DATA
5. Vérifier que l'instance ASM (+ASM) fonctionne

################################################################################
#                                                                              #
#  PARTIE 5 : INSTALLATION DE GRID INFRASTRUCTURE                             #
#            (par l'utilisateur 'grid')                                        #
#                                                                              #
################################################################################

Dans cette partie, nous allons :
1. Créer l'arborescence de répertoires pour Oracle
2. Télécharger Oracle Grid Infrastructure 19c
3. Préparer l'installation (extraction, response file)
4. Installer Grid Infrastructure en mode silencieux
5. Exécuter les scripts root requis
6. Vérifier que l'instance ASM (+ASM) fonctionne
7. Vérifier le disk group DATA (créé automatiquement)

[TEMPS]  Durée estimée : 90-120 minutes

═══════════════════════════════════════════════════════════════════════════════
5.1 CRÉATION DE L'ARBORESCENCE DE RÉPERTOIRES
═══════════════════════════════════════════════════════════════════════════════

Oracle nécessite une structure de répertoires spécifique pour :
[OK] Stocker les logiciels (binaires)
[OK] Stocker les fichiers d'administration
[OK] Stocker les logs et diagnostics
[OK] Zone de staging (fichiers temporaires d'installation)

ÉTAPE 1 : Créer les répertoires de base en tant que root
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Se connecter en tant que root (ou utiliser sudo)
  $ sudo mkdir -p /u01/app/grid
  $ sudo mkdir -p /u01/app/19.3.0/grid
  $ sudo mkdir -p /u01/app/oracle
  $ sudo mkdir -p /u01/app/oracle/product/19.3.0/dbhome_1
  $ sudo mkdir -p /u01/app/oraInventory
  $ sudo mkdir -p /u01/stage/grid
  $ sudo mkdir -p /u01/stage/database
  
  Explication de chaque répertoire :
  
  /u01/app/grid
  -> ORACLE_BASE pour l'utilisateur 'grid'
  -> Contiendra les fichiers d'administration ASM
  -> Propriétaire : grid:oinstall
  
  /u01/app/19.3.0/grid
  -> GRID_HOME (Oracle Home pour Grid Infrastructure)
  -> Contiendra les binaires Grid Infrastructure (asmcmd, crsctl, etc.)
  -> Propriétaire : grid:oinstall
  
  /u01/app/oracle
  -> ORACLE_BASE pour l'utilisateur 'oracle'
  -> Contiendra les fichiers d'administration des databases
  -> Propriétaire : oracle:oinstall
  
  /u01/app/oracle/product/19.3.0/dbhome_1
  -> ORACLE_HOME (Oracle Home pour Database)
  -> Contiendra les binaires Oracle Database (sqlplus, rman, etc.)
  -> Propriétaire : oracle:oinstall
  
  /u01/app/oraInventory
  -> Inventaire Oracle (registre de tous les produits Oracle installés)
  -> Partagé entre 'grid' et 'oracle'
  -> Propriétaire : grid:oinstall (par convention)
  
  /u01/stage/grid
  -> Zone de staging pour les fichiers d'installation Grid
  -> Fichiers .zip, response files, patches, etc.
  -> Propriétaire : grid:oinstall
  
  /u01/stage/database
  -> Zone de staging pour les fichiers d'installation Database
  -> Propriétaire : oracle:oinstall


ÉTAPE 2 : Définir les propriétaires et permissions
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Répertoires appartenant à 'grid'
  $ sudo chown -R grid:oinstall /u01/app/grid
  $ sudo chown -R grid:oinstall /u01/app/19.3.0
  $ sudo chown -R grid:oinstall /u01/app/oraInventory
  $ sudo chown -R grid:oinstall /u01/stage/grid
  
  # Répertoires appartenant à 'oracle'
  $ sudo chown -R oracle:oinstall /u01/app/oracle
  $ sudo chown -R oracle:oinstall /u01/stage/database
  
  # Permissions : 755 pour les répertoires
  $ sudo chmod -R 755 /u01/app
  $ sudo chmod -R 755 /u01/stage
  
  Explication des permissions 755 :
  7 (rwx) : propriétaire peut lire/écrire/exécuter (traverser)
  5 (r-x) : groupe peut lire/exécuter
  5 (r-x) : autres peuvent lire/exécuter
  
  Pourquoi ces permissions ?
  -> Le propriétaire (grid ou oracle) a un contrôle total
  -> Les autres membres d'oinstall peuvent lire et naviguer
  -> Les autres utilisateurs peuvent aussi naviguer (nécessaire pour certaines opérations)


ÉTAPE 3 : Vérifier la structure créée
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Afficher l'arborescence complète
  $ tree -L 4 -d /u01/
  
  Si 'tree' n'est pas installé :
  $ sudo apt install tree
  
  Sortie attendue :
  /u01/
  ├── app
  │   ├── 19.3.0
  │   │   └── grid                    <- GRID_HOME (vide pour l'instant)
  │   ├── grid                         <- ORACLE_BASE pour grid
  │   ├── oracle                       <- ORACLE_BASE pour oracle
  │   │   └── product
  │   │       └── 19.3.0
  │   │           └── dbhome_1         <- ORACLE_HOME pour Database (vide)
  │   └── oraInventory                 <- Inventaire Oracle (vide)
  └── stage
      ├── database                     <- Zone staging Database
      └── grid                         <- Zone staging Grid
  
  # Vérifier les propriétaires
  $ ls -l /u01/app/
  
  Sortie attendue :
  drwxr-xr-x 3 grid   oinstall 4096 Dec 19 14:00 19.3.0
  drwxr-xr-x 2 grid   oinstall 4096 Dec 19 14:00 grid
  drwxr-xr-x 3 oracle oinstall 4096 Dec 19 14:00 oracle
  drwxr-xr-x 2 grid   oinstall 4096 Dec 19 14:00 oraInventory
  
  # Vérifier que 'grid' peut écrire dans ses répertoires
  $ sudo su - grid
  $ touch /u01/app/grid/test.txt
  $ ls -l /u01/app/grid/test.txt
  -rw-r--r-- 1 grid oinstall 0 Dec 19 14:05 /u01/app/grid/test.txt
  [OK] 'grid' peut écrire
  
  $ rm /u01/app/grid/test.txt
  $ exit


═══════════════════════════════════════════════════════════════════════════════
5.2 TÉLÉCHARGEMENT D'ORACLE GRID INFRASTRUCTURE 19c
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│                    OÙ TÉLÉCHARGER ORACLE GRID INFRASTRUCTURE ?             │
└────────────────────────────────────────────────────────────────────────────┘

Oracle Grid Infrastructure 19c est disponible sur le site officiel d'Oracle :
-> https://www.oracle.com/database/technologies/oracle19c-linux-downloads.html

[ATTENTION]  IMPORTANT : Tu as besoin d'un compte Oracle (gratuit) pour télécharger
[ATTENTION]  Accepter la licence Oracle Technology Network (OTN)


ÉTAPE 1 : Télécharger le fichier ZIP
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Fichier à télécharger :
  Nom : LINUX.X64_193000_grid_home.zip
  Taille : ~3.0 GB
  Checksum (SHA256) : Vérifie sur le site Oracle
  
  Option A : Télécharger depuis un navigateur web
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  1. Aller sur https://www.oracle.com/database/technologies/oracle19c-linux-downloads.html
  2. Se connecter avec ton compte Oracle
  3. Accepter la licence OTN
  4. Télécharger "Oracle Database 19c Grid Infrastructure (19.3) for Linux x86-64"
  5. Transférer le fichier vers le serveur Ubuntu :
     $ scp LINUX.X64_193000_grid_home.zip user@oracledb:/tmp/
  6. Sur le serveur, déplacer le fichier :
     $ sudo mv /tmp/LINUX.X64_193000_grid_home.zip /u01/stage/grid/
     $ sudo chown grid:oinstall /u01/stage/grid/LINUX.X64_193000_grid_home.zip
  
  Option B : Télécharger directement depuis le serveur (avec wget ou curl)
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  [ATTENTION]  Nécessite un compte Oracle et un cookie de session
  
  # Se connecter en tant que 'grid'
  $ sudo su - grid
  
  # Aller dans le répertoire de staging
  $ cd /u01/stage/grid
  
  # Télécharger avec wget (exemple, nécessite authentification Oracle)
  # Cette commande ne fonctionnera PAS directement, c'est un exemple
  $ wget --http-user=ton_email@example.com \
         --http-password=ton_mot_de_passe \
         https://download.oracle.com/.../LINUX.X64_193000_grid_home.zip
  
  [ATTENTION]  Pour des raisons de sécurité, Oracle ne permet généralement PAS
      le téléchargement automatisé sans passer par le site web.
      -> Privilégie l'Option A (téléchargement manuel + transfert)


ÉTAPE 2 : Vérifier le fichier téléchargé
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Se connecter en tant que 'grid'
  $ sudo su - grid
  
  # Vérifier la présence du fichier
  $ ls -lh /u01/stage/grid/
  
  Sortie attendue :
  -rw-r--r-- 1 grid oinstall 3.0G Dec 19 14:30 LINUX.X64_193000_grid_home.zip
  
  # Vérifier la taille (doit être ~3 GB)
  $ du -sh /u01/stage/grid/LINUX.X64_193000_grid_home.zip
  3.0G    /u01/stage/grid/LINUX.X64_193000_grid_home.zip
  
  # Vérifier que le fichier n'est pas corrompu (optionnel mais recommandé)
  $ unzip -t /u01/stage/grid/LINUX.X64_193000_grid_home.zip | tail -5
  
  Sortie attendue (dernières lignes) :
  ...
  testing: install/utl/scripts/orainstroot.sh   OK
  testing: install/utl/scripts/ronly.sql   OK
  No errors detected in compressed data of LINUX.X64_193000_grid_home.zip.
  
  [OK] Le fichier ZIP est valide


═══════════════════════════════════════════════════════════════════════════════
5.3 EXTRACTION ET PRÉPARATION DE L'INSTALLATION
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│               NOUVELLE MÉTHODE D'INSTALLATION ORACLE 19c                   │
└────────────────────────────────────────────────────────────────────────────┘

À partir d'Oracle 18c, la méthode d'installation a CHANGÉ :

ANCIENNE MÉTHODE (Oracle 11g, 12c) :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. Extraire le ZIP dans un répertoire temporaire
2. Lancer ./runInstaller depuis ce répertoire
3. L'installeur copie les fichiers vers ORACLE_HOME

NOUVELLE MÉTHODE (Oracle 18c, 19c, 21c, 23c) :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. Extraire le ZIP DIRECTEMENT dans ORACLE_HOME (ou GRID_HOME)
2. Lancer ./gridSetup.sh DEPUIS ORACLE_HOME
3. L'installation se fait "in-place" (sur place)

Avantages :
[OK] Plus rapide (pas de copie de fichiers)
[OK] Moins d'espace disque nécessaire
[OK] Simplifie les installations multiples


ÉTAPE 1 : Extraire le ZIP directement dans GRID_HOME
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'grid'
  $ cd /u01/app/19.3.0/grid
  
  # Vérifier que le répertoire est vide
  $ ls -la
  total 8
  drwxr-xr-x 2 grid oinstall 4096 Dec 19 14:00 .
  drwxr-xr-x 3 grid oinstall 4096 Dec 19 14:00 ..
  [OK] Vide
  
  # Extraire le ZIP
  $ unzip -q /u01/stage/grid/LINUX.X64_193000_grid_home.zip
  
  Options :
  -q : mode silencieux (quiet), n'affiche pas chaque fichier extrait
  
  [TEMPS]  Temps : 5-10 minutes (selon la vitesse du disque)
  
  [ATTENTION]  SI tu vois une erreur "No space left on device" :
  -> Vérifie l'espace disque : df -h /u01
  -> Tu as besoin d'au moins 12 GB libres sur /u01


ÉTAPE 2 : Vérifier l'extraction
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Lister le contenu de GRID_HOME
  $ ls -l /u01/app/19.3.0/grid/
  
  Sortie attendue (répertoires principaux) :
  drwxr-xr-x  2 grid oinstall  4096 Dec 19 15:00 addnode
  drwxr-xr-x  5 grid oinstall  4096 Dec 19 15:00 assistants
  drwxr-xr-x  2 grid oinstall  4096 Dec 19 15:00 bin           <- Binaires
  drwxr-xr-x  3 grid oinstall  4096 Dec 19 15:00 clone
  drwxr-xr-x  4 grid oinstall  4096 Dec 19 15:00 crs           <- Clusterware
  drwxr-xr-x  3 grid oinstall  4096 Dec 19 15:00 css
  drwxr-xr-x  4 grid oinstall  4096 Dec 19 15:00 ctx
  drwxr-xr-x  2 grid oinstall  4096 Dec 19 15:00 cv
  drwxr-xr-x  5 grid oinstall  4096 Dec 19 15:00 deinstall
  drwxr-xr-x  2 grid oinstall  4096 Dec 19 15:00 demo
  drwxr-xr-x  3 grid oinstall  4096 Dec 19 15:00 dmu
  drwxr-xr-x  2 grid oinstall  4096 Dec 19 15:00 has
  drwxr-xr-x  6 grid oinstall  4096 Dec 19 15:00 install       <- Scripts install
  drwxr-xr-x  2 grid oinstall  4096 Dec 19 15:00 instantclient
  drwxr-xr-x  2 grid oinstall  4096 Dec 19 15:00 inventory
  drwxr-xr-x  6 grid oinstall  4096 Dec 19 15:00 javavm
  drwxr-xr-x  4 grid oinstall  4096 Dec 19 15:00 jdbc
  drwxr-xr-x  8 grid oinstall  4096 Dec 19 15:00 jdk           <- Java JDK
  drwxr-xr-x  4 grid oinstall  4096 Dec 19 15:00 jlib
  drwxr-xr-x  2 grid oinstall  4096 Dec 19 15:00 ldap
  drwxr-xr-x  6 grid oinstall  4096 Dec 19 15:00 lib           <- Bibliothèques
  drwxr-xr-x  4 grid oinstall  4096 Dec 19 15:00 md
  drwxr-xr-x  4 grid oinstall  4096 Dec 19 15:00 network       <- Config réseau
  drwxr-xr-x  3 grid oinstall  4096 Dec 19 15:00 nls
  drwxr-xr-x  3 grid oinstall  4096 Dec 19 15:00 odbc
  drwxr-xr-x  5 grid oinstall  4096 Dec 19 15:00 OPatch        <- Gestion patches
  drwxr-xr-x  2 grid oinstall  4096 Dec 19 15:00 opmn
  drwxr-xr-x  2 grid oinstall  4096 Dec 19 15:00 oracore
  drwxr-xr-x 10 grid oinstall  4096 Dec 19 15:00 ord
  drwxr-xr-x  2 grid oinstall  4096 Dec 19 15:00 ords
  drwxr-xr-x  2 grid oinstall  4096 Dec 19 15:00 oui
  drwxr-xr-x  3 grid oinstall  4096 Dec 19 15:00 owm
  drwxr-xr-x  5 grid oinstall  4096 Dec 19 15:00 perl          <- Perl
  drwxr-xr-x  2 grid oinstall  4096 Dec 19 15:00 plsql
  drwxr-xr-x  3 grid oinstall  4096 Dec 19 15:00 precomp
  drwxr-xr-x  2 grid oinstall  4096 Dec 19 15:00 QOpatch
  drwxr-xr-x  9 grid oinstall  4096 Dec 19 15:00 racg
  drwxr-xr-x 11 grid oinstall  4096 Dec 19 15:00 rdbms         <- Moteur DB
  -rw-r--r--  1 grid oinstall   134 Dec 19 15:00 root.sh       <- Script root
  -rw-r--r--  1 grid oinstall   115 Dec 19 15:00 runInstaller  <- Installeur
  drwxr-xr-x  4 grid oinstall  4096 Dec 19 15:00 sdk
  drwxr-xr-x  2 grid oinstall  4096 Dec 19 15:00 slax
  drwxr-xr-x  3 grid oinstall  4096 Dec 19 15:00 sqlpatch
  drwxr-xr-x  9 grid oinstall  4096 Dec 19 15:00 sqlplus       <- SQL*Plus
  drwxr-xr-x  3 grid oinstall  4096 Dec 19 15:00 srvm
  drwxr-xr-x  2 grid oinstall  4096 Dec 19 15:00 suptools
  drwxr-xr-x  2 grid oinstall  4096 Dec 19 15:00 ucp
  drwxr-xr-x  4 grid oinstall  4096 Dec 19 15:00 usm
  drwxr-xr-x  3 grid oinstall  4096 Dec 19 15:00 wwg
  drwxr-xr-x  2 grid oinstall  4096 Dec 19 15:00 xdk
  
  # Vérifier la présence des exécutables clés
  $ ls -l /u01/app/19.3.0/grid/gridSetup.sh
  -rwxr-x--- 1 grid oinstall 3241 Apr 17  2019 /u01/app/19.3.0/grid/gridSetup.sh
  [OK] Installeur présent
  
  $ ls -l /u01/app/19.3.0/grid/bin/asmcmd
  -rwxr-x--- 1 grid oinstall 28488 Apr 17  2019 /u01/app/19.3.0/grid/bin/asmcmd
  [OK] Binaires présents
  
  # Compter le nombre de fichiers extraits
  $ find /u01/app/19.3.0/grid -type f | wc -l
  ~15000-20000 fichiers
  
  # Vérifier l'espace utilisé
  $ du -sh /u01/app/19.3.0/grid
  8.5G    /u01/app/19.3.0/grid


ÉTAPE 3 : Vérifier les permissions
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Tous les fichiers doivent appartenir à grid:oinstall
  $ ls -ld /u01/app/19.3.0/grid
  drwxr-xr-x 58 grid oinstall 4096 Dec 19 15:00 /u01/app/19.3.0/grid
  [OK] Propriétaire correct
  
  # Vérifier quelques fichiers clés
  $ ls -l /u01/app/19.3.0/grid/gridSetup.sh
  -rwxr-x--- 1 grid oinstall 3241 Apr 17  2019 /u01/app/19.3.0/grid/gridSetup.sh
  [OK] Exécutable, propriétaire grid
  
  # Si certains fichiers ont les mauvaises permissions :
  $ cd /u01/app/19.3.0/grid
  $ chown -R grid:oinstall .
  $ find . -type d -exec chmod 755 {} \;
  $ find . -type f -exec chmod 644 {} \;
  $ find . -name "*.sh" -exec chmod 755 {} \;
  $ find . -name "*.pl" -exec chmod 755 {} \;
  $ chmod 755 bin/*


═══════════════════════════════════════════════════════════════════════════════
5.4 CRÉATION DU FICHIER DE RÉPONSE (RESPONSE FILE)
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│                    QU'EST-CE QU'UN "RESPONSE FILE" ?                       │
└────────────────────────────────────────────────────────────────────────────┘

Un response file = fichier texte contenant les réponses aux questions de l'installeur
-> Permet une installation SILENCIEUSE (sans interface graphique)
-> Idéal pour :
   - Serveurs sans X11
   - Installations automatisées
   - Déploiements répétables

MODES D'INSTALLATION ORACLE :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Mode INTERACTIF (GUI) :
  $ ./gridSetup.sh
  -> Lance l'interface graphique (nécessite X11)
  -> Tu cliques sur "Next" et remplis les formulaires

Mode SILENCIEUX (Silent) :
  $ ./gridSetup.sh -silent -responseFile /chemin/vers/grid.rsp
  -> Pas d'interface graphique
  -> L'installeur lit les réponses depuis le fichier .rsp
  -> Affiche la progression en mode texte

Dans ce guide, nous utilisons le mode SILENCIEUX.


ÉTAPE 1 : Créer le fichier de réponse
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'grid'
  $ cd /u01/stage/grid
  
  # Créer le fichier grid_install.rsp
  $ cat > grid_install.rsp << 'EOF'
#############################################################################
# Response File pour l'installation de Grid Infrastructure 19c
# Configuration : Standalone Server (pas de RAC)
# Date : 2024-12-20
#############################################################################

#-----------------------------------------------------------------------------
# INFORMATIONS GÉNÉRALES
#-----------------------------------------------------------------------------

# Inventaire Oracle (registre des installations Oracle)
oracle.install.responseFileVersion=/oracle/install/rspfmt_crsinstall_response_schema_v19.0.0
INVENTORY_LOCATION=/u01/app/oraInventory

# Type d'installation
# Options possibles :
#   - CRS_CONFIG : Cluster (RAC)
#   - HA_CONFIG : Oracle Restart (standalone avec haute dispo)
#   - UPGRADE : Upgrade d'une version existante
oracle.install.option=HA_CONFIG

# Nom du système d'exploitation (détection auto)
ORACLE_HOSTNAME=

#-----------------------------------------------------------------------------
# LOCALISATIONS DES RÉPERTOIRES
#-----------------------------------------------------------------------------

# ORACLE_BASE : Répertoire racine pour l'utilisateur grid
ORACLE_BASE=/u01/app/grid

# GRID_HOME : Répertoire du logiciel Grid Infrastructure
# C'est là où nous avons extrait le ZIP
ORACLE_HOME=/u01/app/19.3.0/grid

#-----------------------------------------------------------------------------
# CONFIGURATION DES GROUPES UNIX
#-----------------------------------------------------------------------------

# Groupe d'installation Oracle (oinstall)
# Tous les produits Oracle appartiennent à ce groupe
oracle.install.asm.OSDBA=asmdba

# Groupe pour les opérations ASM (asmoper)
oracle.install.asm.OSOPER=asmoper

# Groupe d'administration ASM (asmadmin)
# Équivalent de SYSDBA pour ASM
oracle.install.asm.OSASM=asmadmin

#-----------------------------------------------------------------------------
# CONFIGURATION ASM - DISK GROUP "DATA"
#-----------------------------------------------------------------------------

# Créer un disk group pendant l'installation ?
# true = oui, créer le disk group DATA
# false = non, je le créerai plus tard manuellement
oracle.install.asm.configureAFD=false
oracle.install.asm.storageOption=ASM

# Nom du disk group à créer
oracle.install.asm.diskGroup.name=DATA

# Niveau de redondance
# Options :
#   - EXTERNAL : pas de redondance ASM (utiliser si RAID matériel)
#   - NORMAL : mirroring 2-way (recommandé)
#   - HIGH : mirroring 3-way (pour données critiques)
oracle.install.asm.diskGroup.redundancy=NORMAL

# Taille d'AU (Allocation Unit) en MB
# L'AU est la plus petite unité d'allocation dans ASM
# Options : 1, 2, 4, 8, 16, 32, 64 MB
# Recommandé : 4 MB (par défaut pour la plupart des workloads)
oracle.install.asm.diskGroup.AUSize=4

# Disques à ajouter au disk group DATA
# Format : /chemin/vers/disque1,/chemin/vers/disque2,...
# Nous utilisons les 3 premiers disques pour DATA
oracle.install.asm.diskGroup.disks=/dev/oracleasm/disk1,/dev/oracleasm/disk2,/dev/oracleasm/disk3

# Chaîne de découverte des disques ASM
# ASM cherchera les disques correspondant à ce pattern
# "*" = tous les disques, mais on peut spécifier "/dev/oracleasm/*"
oracle.install.asm.diskGroup.diskDiscoveryString=/dev/oracleasm/*

# Configurer AFD (ASM Filter Driver) ?
# AFD est une alternative à UDEV pour gérer les disques ASM
# false = utiliser UDEV (notre configuration)
# true = utiliser AFD (nécessite configuration supplémentaire)
oracle.install.crs.configureRHPS=false

#-----------------------------------------------------------------------------
# CONFIGURATION RÉSEAU (non applicable pour standalone, mais requis)
#-----------------------------------------------------------------------------

# Interfaces réseau publiques
# Si tu as plusieurs interfaces réseau, liste-les : eth0,eth1
# Laisser vide pour détection automatique
oracle.install.crs.config.networkInterfaceList=

# Scan Name (pour RAC uniquement, laisser vide pour standalone)
oracle.install.crs.config.gpnp.scanName=

# Scan Port (pour RAC uniquement)
oracle.install.crs.config.gpnp.scanPort=

#-----------------------------------------------------------------------------
# MOTS DE PASSE
#-----------------------------------------------------------------------------

# Mot de passe pour les comptes SYS et SYSTEM de l'instance ASM
# Ces comptes permettent de se connecter à ASM :
#   sqlplus / as sysasm
#   sqlplus sys@+ASM as sysasm
# 
# [ATTENTION]  IMPORTANT : Change ce mot de passe en production !
# [ATTENTION]  Respecte la politique de mots de passe Oracle :
#     - Au moins 8 caractères
#     - Au moins 1 majuscule
#     - Au moins 1 minuscule
#     - Au moins 1 chiffre
#     - Commence par une lettre
oracle.install.asm.SYSASMPassword=Oracle19c#ASM

# Confirmer le mot de passe (doit être identique)
oracle.install.asm.monitorPassword=Oracle19c#ASM

#-----------------------------------------------------------------------------
# CONFIGURATION ORACLE RESTART
#-----------------------------------------------------------------------------

# Configurer Oracle Restart ?
# Oracle Restart = système de haute disponibilité pour standalone
# Il redémarre automatiquement ASM et les databases en cas de crash
# true = activer (recommandé)
# false = désactiver
oracle.install.crs.config.configureAsExtendedCluster=false
oracle.install.crs.config.clusterType=STANDALONE

# Activer GIMR (Grid Infrastructure Management Repository) ?
# GIMR = base de données interne pour stocker les métriques de monitoring
# false pour standalone (pas nécessaire)
oracle.install.crs.config.useIPMI=false
oracle.install.asm.configureGIMRDataDG=false

#-----------------------------------------------------------------------------
# CONFIGURATION DES MISES À JOUR
#-----------------------------------------------------------------------------

# Spécifier un répertoire contenant des patches à appliquer ?
# Laisser vide si pas de patches pour l'instant
oracle.install.crs.config.ignoreDownNodes=false

# Ignorer les pré-requis ?
# [ATTENTION]  NE PAS METTRE À true, sauf si tu SAIS ce que tu fais
# L'installeur vérifie :
#   - Packages système installés
#   - Paramètres kernel
#   - Espace disque
#   - Permissions
oracle.installer.ignorePrereqs=false

# Activer la vérification des pré-requis en mode "warning only" ?
# true = afficher des warnings mais continuer l'installation
# false = arrêter si un pré-requis n'est pas satisfait (recommandé)
oracle.installer.continueOnPrereqFailure=false

#-----------------------------------------------------------------------------
# CONFIGURATION MY ORACLE SUPPORT (optionnel)
#-----------------------------------------------------------------------------

# Recevoir les notifications de sécurité et updates d'Oracle ?
# true = oui, configure My Oracle Support
# false = non (on peut configurer plus tard)
oracle.installer.autoupdates.option=SKIP_UPDATES
oracle.installer.autoupdates.downloadUpdatesLoc=

# Email pour les notifications (optionnel)
MYORACLESUPPORT_USERNAME=
MYORACLESUPPORT_PASSWORD=

# Accepter de recevoir des emails marketing d'Oracle ?
DECLINE_SECURITY_UPDATES=true

#-----------------------------------------------------------------------------
# OPTIONS AVANCÉES
#-----------------------------------------------------------------------------

# Configurer GNS (Grid Naming Service) ? (pour RAC uniquement)
oracle.install.crs.config.configureGNS=false

# Configurer le stockage partagé pour RAC ?
oracle.install.crs.config.sharedFileSystemStorage=false

#############################################################################
# Fin du fichier de réponse
#############################################################################
EOF

  # [TEMPS]  Temps : 2 minutes


ÉTAPE 2 : Vérifier le fichier de réponse
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Afficher le fichier
  $ cat /u01/stage/grid/grid_install.rsp
  
  # Vérifier les paramètres clés
  $ grep -E "^[^#]" /u01/stage/grid/grid_install.rsp | grep -v "^$"
  
  Sortie attendue (paramètres non commentés) :
  oracle.install.responseFileVersion=/oracle/install/rspfmt_crsinstall_response_schema_v19.0.0
  INVENTORY_LOCATION=/u01/app/oraInventory
  oracle.install.option=HA_CONFIG
  ORACLE_HOSTNAME=
  ORACLE_BASE=/u01/app/grid
  ORACLE_HOME=/u01/app/19.3.0/grid
  oracle.install.asm.OSDBA=asmdba
  oracle.install.asm.OSOPER=asmoper
  oracle.install.asm.OSASM=asmadmin
  oracle.install.asm.configureAFD=false
  oracle.install.asm.storageOption=ASM
  oracle.install.asm.diskGroup.name=DATA
  oracle.install.asm.diskGroup.redundancy=NORMAL
  oracle.install.asm.diskGroup.AUSize=4
  oracle.install.asm.diskGroup.disks=/dev/oracleasm/disk1,/dev/oracleasm/disk2,/dev/oracleasm/disk3
  oracle.install.asm.diskGroup.diskDiscoveryString=/dev/oracleasm/*
  oracle.install.crs.configureRHPS=false
  oracle.install.crs.config.networkInterfaceList=
  oracle.install.crs.config.gpnp.scanName=
  oracle.install.crs.config.gpnp.scanPort=
  oracle.install.asm.SYSASMPassword=Oracle19c#ASM
  oracle.install.asm.monitorPassword=Oracle19c#ASM
  oracle.install.crs.config.configureAsExtendedCluster=false
  oracle.install.crs.config.clusterType=STANDALONE
  oracle.install.crs.config.useIPMI=false
  oracle.install.asm.configureGIMRDataDG=false
  oracle.install.crs.config.ignoreDownNodes=false
  oracle.installer.ignorePrereqs=false
  oracle.installer.continueOnPrereqFailure=false
  oracle.installer.autoupdates.option=SKIP_UPDATES
  oracle.installer.autoupdates.downloadUpdatesLoc=
  MYORACLESUPPORT_USERNAME=
  MYORACLESUPPORT_PASSWORD=
  DECLINE_SECURITY_UPDATES=true
  oracle.install.crs.config.configureGNS=false
  oracle.install.crs.config.sharedFileSystemStorage=false
  
  # Vérifier la syntaxe (pas de lignes vides, pas de caractères bizarres)
  $ file /u01/stage/grid/grid_install.rsp
  /u01/stage/grid/grid_install.rsp: ASCII text
  [OK] Fichier texte valide


ÉTAPE 3 : PERSONNALISER le fichier selon ton environnement
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  [ATTENTION]  IMPORTANT : Vérifie et adapte ces paramètres :
  
  1. ORACLE_HOSTNAME
     -> Si tu as un nom de serveur différent de ce que retourne `hostname`
     -> Sinon, laisser vide (détection auto)
  
  2. oracle.install.asm.diskGroup.disks
     -> Vérifie que les chemins correspondent à tes disques :
       /dev/oracleasm/disk1,/dev/oracleasm/disk2,/dev/oracleasm/disk3
     -> Si tu as utilisé d'autres noms, modifie
  
  3. oracle.install.asm.diskGroup.diskDiscoveryString
     -> Vérifie que c'est bien /dev/oracleasm/*
     -> Si tes liens sont ailleurs : /autre/chemin/*
  
  4. oracle.install.asm.SYSASMPassword
     -> [ATTENTION]  CHANGE CE MOT DE PASSE en production !
     -> Doit respecter la politique Oracle :
        - Au moins 8 caractères
        - Au moins 1 majuscule, 1 minuscule, 1 chiffre
        - Commence par une lettre
     -> Exemple : MySecurePass123#
  
  5. oracle.install.asm.diskGroup.redundancy
     -> Si tu veux EXTERNAL (pas de redondance) : change NORMAL -> EXTERNAL
     -> Si tu veux HIGH (triple miroir) : change NORMAL -> HIGH
  
  Pour éditer le fichier :
  $ nano /u01/stage/grid/grid_install.rsp
  
  Modifier les valeurs, puis sauvegarder (Ctrl+O, Enter, Ctrl+X)


═══════════════════════════════════════════════════════════════════════════════
5.5 LANCEMENT DE L'INSTALLATION GRID INFRASTRUCTURE
═══════════════════════════════════════════════════════════════════════════════

[ATTENTION]  AVANT DE COMMENCER L'INSTALLATION :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Checklist finale :
  [x] Les disques ASM sont préparés et accessibles
  [x] Les liens UDEV existent : /dev/oracleasm/disk1..5
  [x] L'utilisateur 'grid' a les bonnes variables d'environnement
  [x] Le fichier de réponse est prêt
  [x] Tu as au moins 12 GB libres sur /u01
  [x] Tu as au moins 2 GB de RAM libre


ÉTAPE 1 : Lancer l'installation en mode silencieux
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'grid'
  $ cd /u01/app/19.3.0/grid
  
  # Lancer l'installeur en mode silencieux
  $ ./gridSetup.sh \
      -silent \
      -responseFile /u01/stage/grid/grid_install.rsp \
      -ignorePrereqFailure
  
  Explication des options :
  
  -silent
  -> Mode silencieux (pas d'interface graphique)
  -> Affiche la progression en mode texte
  
  -responseFile /chemin/vers/fichier.rsp
  -> Fichier contenant les réponses aux questions de l'installeur
  
  -ignorePrereqFailure (optionnel, À UTILISER AVEC PRÉCAUTION)
  -> Continue l'installation même si certains pré-requis échouent
  -> Utile sur Ubuntu car Oracle vérifie pour RHEL/OEL/SLES
  -> [ATTENTION]  Utilise cette option SEULEMENT si tu es SÛR d'avoir bien configuré :
        - Les packages système (partie 2.3)
        - Les paramètres kernel (partie 2.4)
        - Les limites système (partie 3.4)
  
  [TEMPS]  Temps : 30-60 minutes (selon la puissance du serveur)


ÉTAPE 2 : Surveiller la progression de l'installation
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  L'installeur affiche des messages en temps réel :
  
  Sortie exemple :
  
  Launching Oracle Grid Infrastructure Setup Wizard...
  
  [WARNING] [INS-13014] Target environment does not meet some optional requirements.
     CAUSE: Some of the optional prerequisites are not met. See logs for details.
     ACTION: Identify the list of failed prerequisite checks from the log...
  
  [ATTENTION]  Les WARNINGS sont normaux sur Ubuntu (Oracle vérifie pour RHEL/OEL)
  [ATTENTION]  Tant qu'on ne voit pas "SEVERE" ou "FATAL", c'est OK
  
  The response file for this session can be found at:
   /u01/app/grid/install/response/grid_2024-12-20_03-15-30PM.rsp
  
  You can find the log of this install session at:
   /u01/app/oraInventory/logs/GridSetupActions2024-12-20_03-15-30PM.log
  
  -> Noter le chemin du log (tu pourras le consulter en cas de problème)
  
  [...]
  
  Preparing the home to patch...
  Applying the patch /u01/app/19.3.0/grid/...
  Successfully applied the patch.
  The log can be found at: /u01/app/oraInventory/logs/...
  
  [...]
  
  Copy /u01/app/19.3.0/grid/install/utl/roothas.pl to the upper level directory...
  
  Execute /u01/app/oraInventory/orainstRoot.sh on the following nodes: 
  [oracledb]
  Execute /u01/app/19.3.0/grid/root.sh on the following nodes: 
  [oracledb]
  
  -> L'installeur s'arrête et ATTEND que tu exécutes les scripts root
  -> NE PAS FERMER ce terminal !
  -> Ouvre un NOUVEAU terminal pour exécuter les scripts
  
  Run the script on the local node and remote nodes
  After execution of the script on all nodes, enter 'YES' to continue:
  
  -> L'installeur attend ta confirmation (tu tapes "YES" après avoir exécuté les scripts)


ÉTAPE 3 : Pendant l'installation, surveiller les logs (optionnel)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Dans un AUTRE terminal (en tant que 'grid') :
  
  # Identifier le fichier log (le nom contient la date/heure)
  $ ls -lrt /u01/app/oraInventory/logs/ | tail -5
  
  # Suivre le log en temps réel
  $ tail -f /u01/app/oraInventory/logs/GridSetupActions2024-12-20_03-15-30PM.log
  
  Tu verras défiler les étapes :
  - Vérification des pré-requis
  - Copie des fichiers
  - Création des liens symboliques
  - Compilation des binaires
  - Configuration de l'inventaire Oracle
  - Préparation de l'environnement ASM
  
  Appuie sur Ctrl+C pour arrêter de suivre le log (l'installation continue)


═══════════════════════════════════════════════════════════════════════════════
5.6 EXÉCUTION DES SCRIPTS ROOT
═══════════════════════════════════════════════════════════════════════════════

À un moment, l'installeur s'arrête et affiche un message comme :

  Execute /u01/app/oraInventory/orainstRoot.sh on the following nodes: 
  [oracledb]
  Execute /u01/app/19.3.0/grid/root.sh on the following nodes: 
  [oracledb]
  
  Run the script on the local node and remote nodes
  After execution of the script on all nodes, enter 'YES' to continue:

Ces scripts doivent être exécutés avec les privilèges ROOT.


ÉTAPE 1 : Exécuter le premier script root (orainstRoot.sh)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Dans un NOUVEAU terminal :
  
  # Se connecter en tant que root
  $ sudo su -
  
  # Exécuter le script
  # cd /u01/app/oraInventory
  # ./orainstRoot.sh
  
  Sortie attendue :
  
  Changing permissions of /u01/app/oraInventory.
  Adding read,write permissions for group.
  Removing read,write,execute permissions for world.
  
  Changing groupname of /u01/app/oraInventory to oinstall.
  The execution of the script is complete.
  
  [OK] Le script s'exécute en quelques secondes
  [OK] Il configure les permissions de l'inventaire Oracle


ÉTAPE 2 : Exécuter le deuxième script root (root.sh)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Toujours en tant que root :
  
  # cd /u01/app/19.3.0/grid
  # ./root.sh
  
  Sortie attendue (extraits) :
  
  Performing root user operation.
  
  The following environment variables are set as:
      ORACLE_OWNER= grid
      ORACLE_HOME=  /u01/app/19.3.0/grid
  
  Enter the full pathname of the local bin directory: [/usr/local/bin]: 
  -> Appuie sur ENTER (accepter le défaut /usr/local/bin)
  
  Copying dbhome to /usr/local/bin ...
  Copying oraenv to /usr/local/bin ...
  Copying coraenv to /usr/local/bin ...
  
  Creating /etc/oratab file...
  Entries will be added to the /etc/oratab file as needed by
  Database Configuration Assistant when a database is created
  Finished running generic part of root script.
  Now product-specific root actions will be performed.
  
  Relinking oracle with rac_on option
  Using configuration parameter file: /u01/app/19.3.0/grid/crs/install/crsconfig_params
  The log of current session can be found at:
    /u01/app/grid/crsdata/oracledb/crsconfig/rootcrs_oracledb_2024-12-20_03-45-12PM.log
  
  2024/12/20 15:45:20 CLSRSC-594: Executing installation step 1 of 19: 'SetupTFA'.
  2024/12/20 15:45:20 CLSRSC-594: Executing installation step 2 of 19: 'ValidateEnv'.
  2024/12/20 15:45:25 CLSRSC-594: Executing installation step 3 of 19: 'CheckFirstNode'.
  2024/12/20 15:45:28 CLSRSC-594: Executing installation step 4 of 19: 'GenSiteGUIDs'.
  2024/12/20 15:45:32 CLSRSC-594: Executing installation step 5 of 19: 'SetupOSD'.
  2024/12/20 15:45:35 CLSRSC-594: Executing installation step 6 of 19: 'CheckCRSConfig'.
  2024/12/20 15:45:40 CLSRSC-594: Executing installation step 7 of 19: 'SetupLocalGPNP'.
  2024/12/20 15:46:10 CLSRSC-594: Executing installation step 8 of 19: 'CreateRootCert'.
  2024/12/20 15:46:18 CLSRSC-594: Executing installation step 9 of 19: 'ConfigOLR'.
  2024/12/20 15:46:35 CLSRSC-594: Executing installation step 10 of 19: 'ConfigCHMOS'.
  2024/12/20 15:46:40 CLSRSC-594: Executing installation step 11 of 19: 'CreateOHASD'.
  2024/12/20 15:47:02 CLSRSC-594: Executing installation step 12 of 19: 'ConfigOHASD'.
  2024/12/20 15:47:10 CLSRSC-330: Adding Clusterware entries to file 'oracle-ohasd.service'
  2024/12/20 15:47:55 CLSRSC-594: Executing installation step 13 of 19: 'InstallAFD'.
  2024/12/20 15:48:10 CLSRSC-594: Executing installation step 14 of 19: 'InstallACFS'.
  2024/12/20 15:48:25 CLSRSC-594: Executing installation step 15 of 19: 'InstallKA'.
  2024/12/20 15:48:35 CLSRSC-594: Executing installation step 16 of 19: 'InitConfig'.
  
  -> Le script exécute 19 étapes (peut prendre 10-20 minutes)
  -> C'est l'étape la plus longue
  
  2024/12/20 15:52:10 CLSRSC-594: Executing installation step 17 of 19: 'StartCluster'.
  2024/12/20 15:53:25 CLSRSC-343: Successfully started Oracle Clusterware stack
  2024/12/20 15:53:30 CLSRSC-594: Executing installation step 18 of 19: 'ConfigNode'.
  2024/12/20 15:55:45 CLSRSC-594: Executing installation step 19 of 19: 'PostConfig'.
  
  -> Configuration du nœud et post-configuration
  
  2024/12/20 15:58:20 CLSRSC-325: Configure Oracle Grid Infrastructure for a Standalone Server successfully
  
  [OK] Message de succès !
  
  [TEMPS]  Temps total du script root.sh : 10-20 minutes


ÉTAPE 3 : Comprendre ce que fait le script root.sh
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Le script root.sh effectue des opérations CRITIQUES :
  
  1. Configuration de l'Oracle Local Registry (OLR)
     -> Registre local stockant la configuration Grid Infrastructure
     -> Fichier : /u01/app/grid/crsdata/<hostname>/olr/<hostname>.olr
  
  2. Création du service systemd oracle-ohasd.service
     -> Service qui démarre automatiquement au boot du système
     -> OHASD = Oracle High Availability Services Daemon
     -> C'est lui qui démarre ASM, le listener, et Oracle Restart
  
  3. Configuration d'ACFS (ASM Cluster File System)
     -> Même si on ne l'utilise pas, les drivers sont installés
  
  4. Création du disk group DATA
     -> Avec les 3 disques spécifiés dans le response file
     -> Redondance NORMAL (mirroring 2-way)
  
  5. Démarrage de l'instance ASM (+ASM)
     -> L'instance ASM est maintenant ACTIVE
     -> Le disk group DATA est monté et accessible
  
  6. Configuration d'Oracle Restart
     -> Enregistre ASM comme ressource à gérer
     -> En cas de crash, Oracle Restart redémarrera ASM automatiquement


ÉTAPE 4 : Confirmer à l'installeur que les scripts sont terminés
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Retourne au terminal où l'installeur attend (terminal de 'grid') :
  
  Run the script on the local node and remote nodes
  After execution of the script on all nodes, enter 'YES' to continue: YES
  
  -> Tape : YES
  -> Appuie sur ENTER
  
  L'installeur continue et se termine :
  
  Successfully Setup Software with warning(s).
  Moved the install session logs to:
   /u01/app/oraInventory/logs/GridSetupActions2024-12-20_03-15-30PM.log
  
  [OK] Installation terminée !


═══════════════════════════════════════════════════════════════════════════════
5.7 VÉRIFICATION DE L'INSTALLATION GRID INFRASTRUCTURE
═══════════════════════════════════════════════════════════════════════════════

Maintenant que Grid Infrastructure est installé, vérifions que tout fonctionne.

ÉTAPE 1 : Vérifier que le service OHASD est actif
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que root
  $ sudo systemctl status oracle-ohasd.service
  
  Sortie attendue :
  [BLACK_CIRCLE] oracle-ohasd.service - Oracle High Availability Services
       Loaded: loaded (/etc/systemd/system/oracle-ohasd.service; enabled; vendor preset: enabled)
       Active: active (running) since Thu 2024-12-20 15:47:10 UTC; 15min ago
      Process: 12345 ExecStart=/etc/init.d/init.ohasd run >/dev/null 2>&1 (code=exited, status=0/SUCCESS)
     Main PID: 12346 (init.ohasd)
        Tasks: 1 (limit: 4915)
       Memory: 8.2M
          CPU: 1.234s
       CGroup: /system.slice/oracle-ohasd.service
               └─12346 /bin/sh /etc/init.d/init.ohasd run
  
  Dec 20 15:47:10 oracledb systemd[1]: Starting Oracle High Availability Services...
  Dec 20 15:47:10 oracledb systemd[1]: Started Oracle High Availability Services.
  
  [OK] Le service est actif (active (running))
  [OK] Il démarrera automatiquement au boot (enabled)


ÉTAPE 2 : Vérifier l'état du Cluster/Grid avec crsctl
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'grid'
  $ sudo su - grid
  
  # Vérifier l'état de Grid Infrastructure (CRS = Cluster Ready Services)
  $ crsctl check crs
  
  Sortie attendue :
  CRS-4638: Oracle High Availability Services is online
  CRS-4537: Cluster Ready Services is online
  CRS-4529: Cluster Synchronization Services is online
  CRS-4533: Event Manager is online
  
  [OK] Tous les services sont "online"
  
  Explication :
  - Oracle High Availability Services (OHASD) : Démon principal
  - Cluster Ready Services (CRS) : Gestionnaire de ressources
  - Cluster Synchronization Services (CSS) : Synchronisation des nœuds
  - Event Manager (EVM) : Gestion des événements


ÉTAPE 3 : Vérifier l'état de l'instance ASM
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'grid'
  $ crsctl stat res -t
  
  Sortie attendue :
  --------------------------------------------------------------------------------
  Name           Target  State        Server                   State details       
  --------------------------------------------------------------------------------
  Local Resources
  --------------------------------------------------------------------------------
  ora.DATA.dg
                 ONLINE  ONLINE       oracledb                 STABLE
  ora.LISTENER.lsnr
                 ONLINE  ONLINE       oracledb                 STABLE
  ora.asm
                 ONLINE  ONLINE       oracledb                 Started,STABLE
  ora.ons
                 OFFLINE OFFLINE      oracledb                 STABLE
  --------------------------------------------------------------------------------
  Cluster Resources
  --------------------------------------------------------------------------------
  ora.cssd
        1        ONLINE  ONLINE       oracledb                 STABLE
  ora.diskmon
        1        OFFLINE OFFLINE                               STABLE
  ora.evmd
        1        ONLINE  ONLINE       oracledb                 STABLE
  --------------------------------------------------------------------------------
  
  Interprétation :
  
  ora.DATA.dg (Disk Group DATA)
  -> Target: ONLINE -> Doit être en ligne
  -> State: ONLINE -> Est effectivement en ligne
  -> STABLE -> Aucune transition en cours
  [OK] Le disk group DATA est monté et disponible
  
  ora.LISTENER.lsnr (Listener réseau)
  -> ONLINE -> Le listener est actif
  -> Il écoute sur le port 1521 (par défaut)
  [OK] Les connexions réseau vers ASM sont possibles
  
  ora.asm (Instance ASM)
  -> ONLINE -> L'instance ASM (+ASM) est démarrée
  -> Started,STABLE -> Démarrée et stable
  [OK] ASM fonctionne correctement
  
  ora.cssd, ora.evmd
  -> Services du cluster
  -> ONLINE -> Actifs
  [OK] L'infrastructure cluster fonctionne


ÉTAPE 4 : Se connecter à l'instance ASM avec SQL*Plus
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'grid'
  $ sqlplus / as sysasm
  
  Sortie attendue :
  
  SQL*Plus: Release 19.0.0.0.0 - Production on Thu Dec 20 16:15:30 2024
  Version 19.3.0.0.0
  
  Copyright (c) 1982, 2019, Oracle.  All rights reserved.
  
  
  Connected to:
  Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
  Version 19.3.0.0.0
  
  SQL> 
  
  [OK] Connexion réussie à l'instance ASM
  
  # Afficher la version
  SQL> SELECT banner FROM v$version;
  
  BANNER
  --------------------------------------------------------------------------------
  Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
  
  # Afficher le nom de l'instance
  SQL> SELECT instance_name, status FROM v$instance;
  
  INSTANCE_NAME    STATUS
  ---------------- ------------
  +ASM             STARTED
  
  [OK] Instance : +ASM
  [OK] Status : STARTED (c'est normal pour ASM, pas "OPEN" comme une database)
  
  # Quitter SQL*Plus
  SQL> EXIT


ÉTAPE 5 : Vérifier le disk group DATA
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'grid', avec SQL*Plus
  $ sqlplus / as sysasm
  
  SQL> SELECT name, state, type, total_mb, free_mb FROM v$asm_diskgroup;
  
  Sortie attendue :
  
  NAME  STATE    TYPE    TOTAL_MB    FREE_MB
  ----- -------- ------- ----------- ---------
  DATA  MOUNTED  NORMAL       61440     61200
  
  Interprétation :
  
  NAME = DATA
  -> C'est le disk group créé pendant l'installation
  
  STATE = MOUNTED
  -> Le disk group est monté et accessible
  -> Les autres états possibles : DISMOUNTED, RESTRICTED, BROKEN
  
  TYPE = NORMAL
  -> Redondance NORMAL (mirroring 2-way)
  -> Chaque bloc est stocké sur 2 disques différents
  
  TOTAL_MB = 61440
  -> Capacité totale brute : 61440 MB ≈ 60 GB
  -> On a 3 disques de 20 GB = 60 GB total
  -> Avec NORMAL redundancy : capacité utilisable = 60 GB / 2 = 30 GB
  
  FREE_MB = 61200
  -> Espace libre : 61200 MB ≈ 60 GB
  -> Presque tout l'espace est libre (normal après installation)
  
  [OK] Le disk group DATA est opérationnel
  
  SQL> EXIT


ÉTAPE 6 : Vérifier les disques du disk group DATA
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ sqlplus / as sysasm
  
  SQL> SELECT group_number, disk_number, name, path, total_mb, free_mb, header_status
       FROM v$asm_disk
       ORDER BY group_number, disk_number;
  
  Sortie attendue :
  
  GROUP_NUMBER DISK_NUMBER NAME      PATH                     TOTAL_MB FREE_MB HEADER_STATUS
  ------------ ----------- --------- ----------------------- --------- ------- -------------
             1           0 DATA_0000 /dev/oracleasm/disk1        20480   20400 MEMBER
             1           1 DATA_0001 /dev/oracleasm/disk2        20480   20400 MEMBER
             1           2 DATA_0002 /dev/oracleasm/disk3        20480   20400 MEMBER
  
  Interprétation :
  
  GROUP_NUMBER = 1
  -> Identifiant du disk group DATA (1 = premier disk group créé)
  
  DISK_NUMBER = 0, 1, 2
  -> Identifiant du disque dans le groupe
  
  NAME = DATA_0000, DATA_0001, DATA_0002
  -> Noms internes ASM des disques
  -> Format : <GROUP_NAME>_<4 chiffres>
  
  PATH = /dev/oracleasm/disk1, /dev/oracleasm/disk2, /dev/oracleasm/disk3
  -> Chemins des liens UDEV vers les disques physiques
  [OK] Ce sont bien les disques qu'on a configurés
  
  TOTAL_MB = 20480 pour chaque disque
  -> 20480 MB = 20 GB
  [OK] Correspond à nos disques de 20 GB
  
  FREE_MB ≈ 20400 pour chaque disque
  -> Presque tout l'espace est libre
  -> Quelques MB utilisés pour les métadonnées ASM
  
  HEADER_STATUS = MEMBER
  -> Le disque est membre actif du disk group
  -> Autres valeurs possibles : CANDIDATE, FORMER, PROVISIONED
  
  [OK] Les 3 disques sont correctement intégrés au disk group DATA
  
  SQL> EXIT


ÉTAPE 7 : Tester la création d'un répertoire et d'un fichier dans ASM
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'grid', utiliser ASMCMD
  $ asmcmd
  
  ASMCMD> pwd
  +
  
  -> Tu es à la racine d'ASM (équivalent de / dans un filesystem classique)
  
  ASMCMD> ls
  DATA/
  
  -> Le disk group DATA est visible
  
  ASMCMD> cd DATA
  ASMCMD> pwd
  +DATA
  
  ASMCMD> ls
  
  -> Le disk group est vide (normal après installation)
  
  ASMCMD> mkdir TEST
  ASMCMD> ls
  TEST/
  
  [OK] Création de répertoire réussie
  
  ASMCMD> cd TEST
  ASMCMD> pwd
  +DATA/TEST
  
  # Créer un petit fichier de test (en dehors d'ASMCMD)
  ASMCMD> exit
  
  $ sqlplus / as sysasm
  
  SQL> -- Créer un alias (lien) vers un fichier
  SQL> ALTER DISKGROUP DATA ADD DIRECTORY '+DATA/TEST';
  
  Diskgroup altered.
  
  SQL> EXIT
  
  [OK] ASM fonctionne correctement et accepte les opérations


ÉTAPE 8 : Vérifier les logs ASM (optionnel)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Localiser le fichier alert log ASM
  $ find /u01/app/grid/diag -name "alert*.log" -type f
  
  Sortie typique :
  /u01/app/grid/diag/asm/+asm/+ASM/trace/alert_+ASM.log
  
  # Afficher les dernières lignes du alert log
  $ tail -50 /u01/app/grid/diag/asm/+asm/+ASM/trace/alert_+ASM.log
  
  Tu devrais voir :
  - SUCCESS messages
  - Disk group DATA mounted
  - ASM instance started
  - Pas d'erreurs ORA- ou CLSRSC-


┌────────────────────────────────────────────────────────────────────────────┐
│                      RÉCAPITULATIF DE LA PARTIE 5                          │
└────────────────────────────────────────────────────────────────────────────┘

[OK] Arborescence de répertoires créée
   /u01/app/grid, /u01/app/19.3.0/grid, /u01/stage/grid

[OK] Oracle Grid Infrastructure 19c téléchargé et extrait
   LINUX.X64_193000_grid_home.zip -> /u01/app/19.3.0/grid

[OK] Fichier de réponse créé
   /u01/stage/grid/grid_install.rsp

[OK] Installation Grid Infrastructure réussie
   Mode silencieux avec response file

[OK] Scripts root exécutés
   orainstRoot.sh et root.sh

[OK] Instance ASM (+ASM) démarrée et fonctionnelle
   Status: STARTED, connexion réussie avec SQL*Plus

[OK] Disk group DATA créé et monté
   3 disques, NORMAL redundancy, ~30 GB utilisable

[OK] Oracle Restart configuré
   Service systemd oracle-ohasd.service actif

[TEMPS]  Temps total de la partie 5 : 90-120 minutes

PROCHAINE ÉTAPE : Création du disk group FRA
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Dans la partie 6, nous allons :
1. Créer le disk group FRA (Fast Recovery Area)
2. Configurer les paramètres ASM avancés
3. Apprendre à gérer les disk groups avec ASMCMD
4. Effectuer des opérations de maintenance courantes

################################################################################
#                                                                              #
#  PARTIE 6 : CRÉATION ET GESTION DES DISK GROUPS                             #
#            (par l'utilisateur 'grid')                                        #
#                                                                              #
################################################################################

Dans cette partie, nous allons :
1. Créer le disk group FRA (Fast Recovery Area)
2. Explorer et gérer les disk groups avec ASMCMD
3. Comprendre les métadonnées ASM
4. Effectuer des opérations de maintenance sur les disk groups
5. Simuler des scénarios de panne et récupération

[TEMPS]  Durée estimée : 45-60 minutes

═══════════════════════════════════════════════════════════════════════════════
6.1 CRÉATION DU DISK GROUP FRA (FAST RECOVERY AREA)
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│                    QU'EST-CE QUE LA FAST RECOVERY AREA (FRA) ?             │
└────────────────────────────────────────────────────────────────────────────┘

La Fast Recovery Area (FRA) = Zone de récupération rapide
-> Espace de stockage DÉDIÉ pour les fichiers de sauvegarde et récupération
-> Gérée automatiquement par Oracle

CONTENU TYPIQUE DE LA FRA :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

1. Archived Redo Logs
   -> Copies des redo logs une fois remplis
   -> Nécessaires pour la récupération point-in-time
   -> Taille : peut atteindre plusieurs GB par jour dans une base active

2. Backups RMAN
   -> Sauvegardes de la base de données
   -> Backup sets (format propriétaire compressé)
   -> Image copies (copies complètes des datafiles)

3. Flashback Logs
   -> Pour la fonctionnalité Flashback Database
   -> Permet de "remonter le temps" en cas d'erreur
   -> Très utile pour annuler des modifications accidentelles

4. Control File Autobackups
   -> Sauvegardes automatiques du fichier de contrôle


POURQUOI SÉPARER DATA ET FRA ?
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Avantages de la séparation :

1. SÉCURITÉ
   -> Si le disk group DATA est corrompu -> tu as les backups dans FRA
   -> Si le disk group FRA est corrompu -> tu as toujours la base dans DATA
   -> Principe de redondance géographique

2. PERFORMANCE
   -> Les backups n'impactent pas les lectures/écritures sur DATA
   -> Les archived logs sont écrits sur FRA (pas de contention avec DATA)

3. GESTION
   -> Oracle gère automatiquement l'espace FRA
   -> Supprime les anciens backups quand l'espace devient limité
   -> Tu définis une politique de rétention, Oracle fait le reste

4. CONFORMITÉ
   -> Beaucoup de régulations imposent une séparation physique des backups


TAILLE RECOMMANDÉE POUR FRA :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Règle générale : FRA = 2× à 3× la taille de DATA

Exemple :
  Taille de la base : 30 GB
  FRA recommandée : 60-90 GB

Pourquoi ?
  - Archived logs : ~10-20% de la taille de la base par jour
  - Backup complet : ~50-70% de la taille de la base (avec compression)
  - Flashback logs : ~10-20% de la taille de la base
  - Marge de sécurité : toujours avoir de l'espace libre

Dans notre configuration :
  DATA : 30 GB utilisable (avec NORMAL redundancy)
  FRA : 20 GB utilisable (2 disques de 20 GB, NORMAL redundancy)


ÉTAPE 1 : Vérifier les disques disponibles pour FRA
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'grid'
  $ sudo su - grid
  
  # Lister tous les disques visibles par ASM
  $ sqlplus / as sysasm
  
  SQL> SELECT path, header_status, total_mb
       FROM v$asm_disk
       ORDER BY path;
  
  Sortie attendue :
  
  PATH                         HEADER_STATUS    TOTAL_MB
  ---------------------------- ---------------- ---------
  /dev/oracleasm/disk1         MEMBER                20480
  /dev/oracleasm/disk2         MEMBER                20480
  /dev/oracleasm/disk3         MEMBER                20480
  /dev/oracleasm/disk4         CANDIDATE             20480
  /dev/oracleasm/disk5         CANDIDATE             20480
  
  Interprétation :
  
  disk1, disk2, disk3 : MEMBER
  -> Ces disques sont déjà membres du disk group DATA
  -> On ne peut PAS les réutiliser pour FRA
  
  disk4, disk5 : CANDIDATE
  -> Ces disques sont visibles par ASM mais pas encore utilisés
  -> CANDIDATE = candidat pour être ajouté à un disk group
  -> Ce sont ces 2 disques qu'on va utiliser pour FRA
  
  [OK] Nous avons 2 disques disponibles pour créer FRA
  
  SQL> EXIT


ÉTAPE 2 : Créer le disk group FRA avec SQL*Plus
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'grid'
  $ sqlplus / as sysasm
  
  SQL> -- Créer le disk group FRA
  SQL> CREATE DISKGROUP FRA
       NORMAL REDUNDANCY
       DISK '/dev/oracleasm/disk4',
            '/dev/oracleasm/disk5'
       ATTRIBUTE
         'compatible.asm' = '19.0.0.0.0',
         'compatible.rdbms' = '19.0.0.0.0',
         'au_size' = '4M';
  
  Explication de la commande ligne par ligne :
  
  CREATE DISKGROUP FRA
  -> Créer un nouveau disk group nommé "FRA"
  -> Le nom peut être n'importe quoi (max 30 caractères)
  -> Convention : noms en MAJUSCULES
  
  NORMAL REDUNDANCY
  -> Niveau de redondance : NORMAL (mirroring 2-way)
  -> Chaque bloc sera écrit sur 2 disques différents
  -> Alternatives : EXTERNAL, HIGH
  
  DISK '/dev/oracleasm/disk4', '/dev/oracleasm/disk5'
  -> Liste des disques à inclure dans le disk group
  -> Syntaxe : chemins séparés par des virgules
  -> On peut aussi spécifier des noms : DISK 'disk4', 'disk5'
  
  ATTRIBUTE
  -> Section définissant les attributs du disk group
  
  'compatible.asm' = '19.0.0.0.0'
  -> Version de compatibilité ASM
  -> Une fois définie, tu ne peux PAS revenir en arrière
  -> 19.0.0.0.0 = Oracle 19c
  -> [ATTENTION]  Assure-toi d'utiliser la bonne version !
  
  'compatible.rdbms' = '19.0.0.0.0'
  -> Version de compatibilité avec les databases
  -> Les databases < 19c ne pourront PAS utiliser ce disk group
  
  'au_size' = '4M'
  -> Taille d'Allocation Unit (AU)
  -> Plus petite unité d'allocation dans ASM
  -> Options : 1, 2, 4, 8, 16, 32, 64 MB
  -> 4 MB = bon compromis pour la plupart des workloads
  -> [ATTENTION]  Ne peut PAS être modifié après création !
  
  Sortie attendue :
  
  Diskgroup created.
  
  [OK] Le disk group FRA est créé
  
  [TEMPS]  Temps : 10-30 secondes


ÉTAPE 3 : Vérifier la création du disk group FRA
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  SQL> -- Lister tous les disk groups
  SQL> SELECT name, state, type, total_mb, free_mb, 
              usable_file_mb, offline_disks
       FROM v$asm_diskgroup;
  
  Sortie attendue :
  
  NAME  STATE    TYPE    TOTAL_MB  FREE_MB  USABLE_FILE_MB  OFFLINE_DISKS
  ----- -------- ------- --------- -------- --------------- -------------
  DATA  MOUNTED  NORMAL      61440    61200           30600             0
  FRA   MOUNTED  NORMAL      40960    40800           20400             0
  
  Interprétation :
  
  FRA ajouté à la liste
  -> NAME = FRA
  -> STATE = MOUNTED (le disk group est monté automatiquement)
  
  TOTAL_MB = 40960
  -> 40960 MB = 40 GB (2 disques × 20 GB)
  -> Capacité brute totale
  
  FREE_MB = 40800
  -> 40800 MB ≈ 40 GB libre
  -> Quelques MB utilisés pour les métadonnées ASM
  
  USABLE_FILE_MB = 20400
  -> Espace réellement UTILISABLE pour les fichiers
  -> Avec NORMAL redundancy (2-way mirror) : 40 GB / 2 = 20 GB
  -> C'est cette valeur qui compte pour toi
  
  OFFLINE_DISKS = 0
  -> Aucun disque hors ligne
  -> Si > 0 : problème, un disque est défaillant
  
  [OK] Le disk group FRA est opérationnel avec ~20 GB utilisable


ÉTAPE 4 : Vérifier les disques du disk group FRA
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  SQL> SELECT group_number, disk_number, name, path, 
              total_mb, free_mb, header_status
       FROM v$asm_disk
       WHERE group_number = (SELECT group_number FROM v$asm_diskgroup WHERE name = 'FRA')
       ORDER BY disk_number;
  
  Sortie attendue :
  
  GROUP_NUMBER  DISK_NUMBER  NAME       PATH                     TOTAL_MB  FREE_MB  HEADER_STATUS
  ------------- ------------ ---------- ----------------------- --------- -------- -------------
              2            0 FRA_0000   /dev/oracleasm/disk4        20480    20400 MEMBER
              2            1 FRA_0001   /dev/oracleasm/disk5        20480    20400 MEMBER
  
  Interprétation :
  
  GROUP_NUMBER = 2
  -> FRA est le 2ème disk group créé (DATA = 1, FRA = 2)
  
  DISK_NUMBER = 0, 1
  -> Identifiant du disque dans le groupe
  
  NAME = FRA_0000, FRA_0001
  -> Noms internes ASM
  
  PATH = /dev/oracleasm/disk4, /dev/oracleasm/disk5
  -> Liens vers les disques physiques
  [OK] Ce sont bien les disques candidats qu'on a utilisés
  
  HEADER_STATUS = MEMBER
  -> Les disques sont membres actifs du disk group
  
  [OK] Les 2 disques sont correctement intégrés au disk group FRA
  
  SQL> EXIT


ÉTAPE 5 : Vérifier que FRA est enregistré dans Oracle Restart
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'grid'
  $ crsctl stat res -t
  
  Sortie attendue (extrait) :
  
  Local Resources
  --------------------------------------------------------------------------------
  ora.DATA.dg
                 ONLINE  ONLINE       oracledb                 STABLE
  ora.FRA.dg
                 ONLINE  ONLINE       oracledb                 STABLE
  ora.LISTENER.lsnr
                 ONLINE  ONLINE       oracledb                 STABLE
  ora.asm
                 ONLINE  ONLINE       oracledb                 Started,STABLE
  
  [OK] ora.FRA.dg est maintenant géré par Oracle Restart
  [OK] Il démarrera automatiquement avec ASM au boot


═══════════════════════════════════════════════════════════════════════════════
6.2 EXPLORATION DES DISK GROUPS AVEC ASMCMD
═══════════════════════════════════════════════════════════════════════════════

ASMCMD = Utilitaire en ligne de commande pour gérer ASM
-> Interface similaire à un shell Unix (cd, ls, pwd, mkdir, etc.)
-> Plus convivial que SQL*Plus pour naviguer dans les disk groups

┌────────────────────────────────────────────────────────────────────────────┐
│                    COMMANDES ASMCMD ESSENTIELLES                           │
└────────────────────────────────────────────────────────────────────────────┘

NAVIGATION :
  pwd             : Afficher le répertoire courant
  cd <dir>        : Changer de répertoire
  ls [-l]         : Lister le contenu (option -l pour détails)
  find            : Rechercher des fichiers

GESTION DES FICHIERS/RÉPERTOIRES :
  mkdir <dir>     : Créer un répertoire
  rm <file>       : Supprimer un fichier
  cp <src> <dest> : Copier un fichier
  md_backup       : Sauvegarder les métadonnées ASM
  md_restore      : Restaurer les métadonnées ASM

INFORMATIONS :
  lsdg            : Lister les disk groups
  lsdsk           : Lister les disques ASM
  lsof            : Lister les fichiers ouverts
  iostat          : Statistiques I/O

GESTION DES DISK GROUPS :
  mount           : Monter un disk group
  umount          : Démonter un disk group
  remap           : Remapper un extent

AIDE :
  help            : Afficher l'aide générale
  help <commande> : Aide sur une commande spécifique


ÉTAPE 1 : Lancer ASMCMD
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'grid'
  $ asmcmd
  
  ASMCMD>
  
  -> Tu es maintenant dans le shell ASMCMD
  -> L'invite "ASMCMD>" indique que tu peux taper des commandes
  
  Pour quitter ASMCMD :
  ASMCMD> exit
  
  OU
  
  ASMCMD> quit


ÉTAPE 2 : Navigation de base dans ASM
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ asmcmd
  
  # Afficher le répertoire courant
  ASMCMD> pwd
  +
  
  -> "+" = racine d'ASM (comme "/" dans un filesystem Unix)
  
  # Lister le contenu de la racine
  ASMCMD> ls
  DATA/
  FRA/
  
  -> Les 2 disk groups sont visibles comme des répertoires
  
  # Changer de répertoire vers DATA
  ASMCMD> cd DATA
  ASMCMD> pwd
  +DATA
  
  # Lister le contenu de DATA
  ASMCMD> ls
  TEST/
  
  -> Le répertoire TEST qu'on a créé précédemment
  
  # Aller dans FRA
  ASMCMD> cd /FRA
  ASMCMD> pwd
  +FRA
  
  # FRA est vide pour l'instant
  ASMCMD> ls
  ASMCMD>
  
  -> Aucun fichier (normal, on n'a pas encore créé de base de données)
  
  # Revenir à la racine
  ASMCMD> cd /
  ASMCMD> pwd
  +


ÉTAPE 3 : Lister les disk groups avec détails
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  ASMCMD> lsdg
  
  Sortie attendue :
  
  State    Type    Rebal  Sector  Block       AU  Total_MB  Free_MB  Req_mir_free_MB  Usable_file_MB  Offline_disks  Voting_files  Name
  MOUNTED  NORMAL  N         512   4096  4194304     61440    61200            20480           20360              0             N  DATA/
  MOUNTED  NORMAL  N         512   4096  4194304     40960    40800            20480           10160              0             N  FRA/
  
  Colonnes importantes :
  
  State = MOUNTED
  -> Le disk group est monté et accessible
  
  Type = NORMAL
  -> Redondance NORMAL (2-way mirror)
  
  Rebal = N
  -> Pas de rééquilibrage en cours
  -> Si "Y" : ASM est en train de redistribuer les données
  
  Block = 4096
  -> Taille de bloc : 4 KB
  -> Standard pour ASM
  
  AU = 4194304
  -> Allocation Unit : 4194304 bytes = 4 MB
  -> C'est ce qu'on a spécifié lors de la création
  
  Total_MB
  -> Capacité brute totale
  -> DATA : 61440 MB (3 × 20 GB)
  -> FRA : 40960 MB (2 × 20 GB)
  
  Free_MB
  -> Espace libre brut
  
  Req_mir_free_MB
  -> Required Mirror Free Space
  -> Espace à réserver pour le mirroring
  -> DATA : 20480 MB (1 disque complet, pour tolérer 1 panne)
  -> FRA : 20480 MB (1 disque complet)
  
  Usable_file_MB
  -> Espace RÉELLEMENT utilisable pour créer des fichiers
  -> DATA : 20360 MB ≈ 20 GB
  -> FRA : 10160 MB ≈ 10 GB
  -> Formule : (Free_MB - Req_mir_free_MB) / facteur_miroir
  
  Voting_files = N
  -> Pas de voting disk (utilisé en RAC seulement)


ÉTAPE 4 : Lister les disques avec détails
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  ASMCMD> lsdsk
  
  Sortie attendue :
  
  Path
  /dev/oracleasm/disk1
  /dev/oracleasm/disk2
  /dev/oracleasm/disk3
  /dev/oracleasm/disk4
  /dev/oracleasm/disk5
  
  -> Liste simple de tous les disques visibles par ASM
  
  # Pour plus de détails
  ASMCMD> lsdsk -k
  
  Sortie attendue :
  
  Total_MB  Free_MB  OS_MB  Name           Failgroup  Library        Label        UDID                 Product       Redund  Path
     20480    20400  20480  DATA_0000      DATA_0000  System                                          ORCLDISK      NORMAL  /dev/oracleasm/disk1
     20480    20400  20480  DATA_0001      DATA_0001  System                                          ORCLDISK      NORMAL  /dev/oracleasm/disk2
     20480    20400  20480  DATA_0002      DATA_0002  System                                          ORCLDISK      NORMAL  /dev/oracleasm/disk3
     20480    20400  20480  FRA_0000       FRA_0000   System                                          ORCLDISK      NORMAL  /dev/oracleasm/disk4
     20480    20400  20480  FRA_0001       FRA_0001   System                                          ORCLDISK      NORMAL  /dev/oracleasm/disk5
  
  Colonnes importantes :
  
  Total_MB, Free_MB
  -> Capacité totale et libre de chaque disque
  
  Name
  -> Nom interne ASM du disque
  
  Failgroup
  -> Groupe de défaillance
  -> ASM évite de mettre les 2 copies d'un même bloc dans le même failgroup
  -> Par défaut : 1 failgroup par disque
  
  Library = System
  -> Bibliothèque utilisée pour accéder au disque
  -> System = accès direct via le kernel Linux
  -> Alternative : ASMLIB (obsolète)
  
  Product = ORCLDISK
  -> Type de produit ASM
  
  Redund = NORMAL
  -> Niveau de redondance du disk group


ÉTAPE 5 : Créer une structure de répertoires dans les disk groups
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Créer une structure pour une future base de données "ORCL"
  ASMCMD> cd /DATA
  ASMCMD> mkdir ORCL
  ASMCMD> cd ORCL
  ASMCMD> mkdir CONTROLFILE DATAFILE ONLINELOG TEMPFILE PARAMETERFILE
  
  # Vérifier
  ASMCMD> ls -l
  Type      Redund  Striped  Time             Sys  Name
  DIRECTORY UNPROT  COARSE   DEC 20 17:00:00  Y    CONTROLFILE/
  DIRECTORY UNPROT  COARSE   DEC 20 17:00:00  Y    DATAFILE/
  DIRECTORY UNPROT  COARSE   DEC 20 17:00:00  Y    ONLINELOG/
  DIRECTORY UNPROT  COARSE   DEC 20 17:00:00  Y    PARAMETERFILE/
  DIRECTORY UNPROT  COARSE   DEC 20 17:00:00  Y    TEMPFILE/
  
  [OK] Structure de répertoires créée
  [OK] Prête à accueillir les fichiers de la base ORCL
  
  # Faire de même pour FRA
  ASMCMD> cd /FRA
  ASMCMD> mkdir ORCL
  ASMCMD> cd ORCL
  ASMCMD> mkdir ARCHIVELOG BACKUPSET AUTOBACKUP FLASHBACK
  
  ASMCMD> ls
  ARCHIVELOG/
  AUTOBACKUP/
  BACKUPSET/
  FLASHBACK/
  
  [OK] Structure FRA créée


═══════════════════════════════════════════════════════════════════════════════
6.3 COMPRENDRE LES MÉTADONNÉES ASM
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│                    COMMENT ASM STOCKE LES DONNÉES ?                        │
└────────────────────────────────────────────────────────────────────────────┘

ASM découpe chaque fichier en EXTENTS
-> Extent = bloc contigu d'allocation units (AU)
-> Par défaut : 1 extent = 1 AU = 4 MB

PROCESSUS D'ÉCRITURE D'UN FICHIER :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Exemple : Tu crées un datafile de 100 MB

1. ASM alloue 25 extents de 4 MB chacun
   -> 25 × 4 MB = 100 MB

2. ASM répartit ces extents sur TOUS les disques du disk group
   -> Disque 1 : extents 0, 3, 6, 9, 12, 15, 18, 21, 24
   -> Disque 2 : extents 1, 4, 7, 10, 13, 16, 19, 22
   -> Disque 3 : extents 2, 5, 8, 11, 14, 17, 20, 23

3. Avec NORMAL redundancy : chaque extent est DUPLIQUÉ
   -> Extent 0 : copie primaire sur Disque 1, copie miroir sur Disque 2
   -> Extent 1 : copie primaire sur Disque 2, copie miroir sur Disque 3
   -> Extent 2 : copie primaire sur Disque 3, copie miroir sur Disque 1
   -> etc.

4. Lecture d'un bloc :
   -> ASM consulte ses métadonnées pour savoir où se trouve l'extent
   -> Lit depuis le disque approprié
   -> Si le disque primaire est défaillant -> lit depuis le miroir


VUES SYSTÈME POUR EXPLORER LES MÉTADONNÉES ASM :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Vue                      Description
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
v$asm_diskgroup          Informations sur les disk groups
v$asm_disk               Informations sur les disques
v$asm_file               Liste des fichiers stockés dans ASM
v$asm_alias              Alias (noms symboliques) des fichiers
v$asm_template           Templates (modèles) de fichiers
v$asm_client             Clients (databases) utilisant ASM
v$asm_operation          Opérations en cours (rebalance, etc.)


ÉTAPE 1 : Explorer v$asm_diskgroup en détail
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ sqlplus / as sysasm
  
  SQL> SELECT group_number, name, allocation_unit_size, 
              state, type, total_mb, free_mb,
              required_mirror_free_mb, usable_file_mb
       FROM v$asm_diskgroup;
  
  Sortie attendue :
  
  GROUP_NUMBER  NAME  ALLOCATION_UNIT_SIZE  STATE    TYPE    TOTAL_MB  FREE_MB  REQUIRED_MIRROR_FREE_MB  USABLE_FILE_MB
  ------------- ----- --------------------- -------- ------- --------- -------- ------------------------ ---------------
              1 DATA               4194304  MOUNTED  NORMAL      61440    61200                    20480           20360
              2 FRA                4194304  MOUNTED  NORMAL      40960    40800                    20480           10160
  
  ALLOCATION_UNIT_SIZE = 4194304
  -> 4194304 bytes = 4 MB
  -> Taille de l'AU (plus petite unité d'allocation)


ÉTAPE 2 : Explorer les templates ASM
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Les templates définissent les propriétés par défaut des fichiers ASM.
  
  SQL> SELECT group_number, name, stripe, redundancy 
       FROM v$asm_template
       WHERE group_number = 1  -- DATA
       ORDER BY name;
  
  Sortie attendue (extrait) :
  
  GROUP_NUMBER  NAME                    STRIPE  REDUNDANCY
  ------------- ----------------------- ------- -----------
              1 ARCHIVELOG              COARSE  MIRROR
              1 AUTOBACKUP              COARSE  MIRROR
              1 BACKUPSET               COARSE  MIRROR
              1 CONTROLFILE             FINE    MIRROR
              1 DATAFILE                COARSE  MIRROR
              1 FLASHBACK               COARSE  MIRROR
              1 ONLINELOG               FINE    MIRROR
              1 PARAMETERFILE           COARSE  MIRROR
              1 TEMPFILE                COARSE  MIRROR
  
  Colonnes importantes :
  
  NAME
  -> Type de fichier
  -> Chaque type a des propriétés optimisées
  
  STRIPE
  -> COARSE : striping grossier (fichier découpé en extents de plusieurs AU)
  -> FINE : striping fin (fichier découpé en extents de 128 KB)
  -> FINE utilisé pour les fichiers critiques : CONTROLFILE, ONLINELOG
  -> COARSE utilisé pour les fichiers normaux : DATAFILE, ARCHIVELOG
  
  REDUNDANCY = MIRROR
  -> Les fichiers utilisent la redondance du disk group
  -> Alternative : UNPROTECTED (pas de miroir, même si disk group = NORMAL)
  
  Pourquoi FINE pour CONTROLFILE et ONLINELOG ?
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  Ces fichiers sont CRITIQUES et ont des patterns d'I/O spécifiques :
  -> Écritures séquentielles très fréquentes (redo logs)
  -> Lectures/écritures aléatoires (control file)
  -> FINE striping = répartition sur TOUS les disques
  -> Maximise la bande passante I/O
  
  SQL> EXIT


ÉTAPE 3 : Sauvegarder les métadonnées ASM
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Les métadonnées ASM décrivent :
  -> Quels disques appartiennent à quels disk groups
  -> Où sont stockés les extents de chaque fichier
  -> Configuration des templates
  -> etc.
  
  [ATTENTION]  Si les métadonnées sont perdues -> impossible d'accéder aux données !
  
  Bonne pratique : Sauvegarder régulièrement les métadonnées
  
  # En tant que 'grid'
  $ asmcmd
  
  # Sauvegarder les métadonnées de tous les disk groups
  ASMCMD> md_backup /u01/stage/grid/asm_metadata_backup.txt
  
  Copying metadata for diskgroup DATA to /u01/stage/grid/asm_metadata_backup.txt
  Copying metadata for diskgroup FRA to /u01/stage/grid/asm_metadata_backup.txt
  
  [OK] Métadonnées sauvegardées
  
  ASMCMD> exit
  
  # Vérifier le fichier de sauvegarde
  $ ls -lh /u01/stage/grid/asm_metadata_backup.txt
  -rw-r--r-- 1 grid oinstall 24K Dec 20 17:30 /u01/stage/grid/asm_metadata_backup.txt
  
  # Afficher le contenu (extrait)
  $ head -50 /u01/stage/grid/asm_metadata_backup.txt
  
  Tu verras :
  - Informations sur les disk groups (taille, redondance, AU size)
  - Liste des disques (paths, taille)
  - Mapping des extents
  - Templates
  
  [ATTENTION]  IMPORTANT : Conserve ce fichier en lieu sûr (hors du serveur) !
  [ATTENTION]  En cas de disaster, tu pourras recréer les disk groups avec ces métadonnées


═══════════════════════════════════════════════════════════════════════════════
6.4 OPÉRATIONS DE MAINTENANCE SUR LES DISK GROUPS
═══════════════════════════════════════════════════════════════════════════════

ÉTAPE 1 : Ajouter un disque à un disk group existant
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Scénario : Le disk group DATA est presque plein, tu veux ajouter un 4ème disque.
  
  Prérequis : Tu as un nouveau disque de 20 GB configuré avec UDEV
  -> Par exemple : /dev/oracleasm/disk6
  
  # En tant que 'grid'
  $ sqlplus / as sysasm
  
  SQL> -- Ajouter le disque au disk group DATA
  SQL> ALTER DISKGROUP DATA 
       ADD DISK '/dev/oracleasm/disk6';
  
  Diskgroup altered.
  
  [TEMPS]  Temps : quelques secondes
  
  SQL> -- Vérifier l'ajout
  SQL> SELECT name, path, total_mb, free_mb, header_status
       FROM v$asm_disk
       WHERE name LIKE 'DATA%'
       ORDER BY name;
  
  Sortie attendue :
  
  NAME       PATH                     TOTAL_MB  FREE_MB  HEADER_STATUS
  ---------- ----------------------- --------- -------- -------------
  DATA_0000  /dev/oracleasm/disk1        20480    20300 MEMBER
  DATA_0001  /dev/oracleasm/disk2        20480    20300 MEMBER
  DATA_0002  /dev/oracleasm/disk3        20480    20300 MEMBER
  DATA_0003  /dev/oracleasm/disk6        20480    20480 MEMBER
  
  [OK] Le nouveau disque (DATA_0003) est ajouté
  
  SQL> -- Vérifier la capacité du disk group
  SQL> SELECT name, total_mb, free_mb, usable_file_mb
       FROM v$asm_diskgroup
       WHERE name = 'DATA';
  
  NAME  TOTAL_MB  FREE_MB  USABLE_FILE_MB
  ----- --------- -------- ---------------
  DATA      81920    81600           30600
  
  Interprétation :
  TOTAL_MB = 81920 (avant : 61440)
  -> +20 GB de capacité brute ajoutée
  -> 81920 MB = 80 GB (4 disques × 20 GB)
  
  USABLE_FILE_MB = 30600 (avant : 20360)
  -> +10 GB d'espace utilisable ajouté
  -> Avec NORMAL redundancy : 20 GB / 2 = 10 GB utilisable
  
  [OK] Capacité du disk group DATA augmentée avec succès


ÉTAPE 2 : Surveiller le rééquilibrage automatique
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Après l'ajout d'un disque, ASM lance un REBALANCE automatique :
  -> Redistribue les données existantes sur TOUS les disques (ancien + nouveau)
  -> Maximise la performance (I/O parallèle sur plus de disques)
  
  # Vérifier l'état du rééquilibrage
  SQL> SELECT group_number, operation, state, power, 
              actual, sofar, est_work, est_rate, est_minutes
       FROM v$asm_operation;
  
  Sortie pendant le rebalance :
  
  GROUP_NUMBER  OPERATION  STATE  POWER  ACTUAL  SOFAR  EST_WORK  EST_RATE  EST_MINUTES
  ------------- ---------- ------ ------ ------- ------ --------- --------- ------------
              1 REBAL      RUN        1      1     150       300        20           7.5
  
  Interprétation :
  
  OPERATION = REBAL
  -> Opération de rééquilibrage en cours
  
  STATE = RUN
  -> En cours d'exécution
  -> États possibles : WAIT (en attente), RUN (en cours), DONE (terminé)
  
  POWER = 1
  -> Puissance du rebalance (1-11)
  -> 1 = lent mais faible impact sur les performances
  -> 11 = rapide mais fort impact sur les performances
  
  SOFAR = 150
  -> 150 MB déjà rééquilibrés
  
  EST_WORK = 300
  -> 300 MB total à rééquilibrer
  
  EST_RATE = 20
  -> Taux : 20 MB/seconde
  
  EST_MINUTES = 7.5
  -> Temps restant estimé : 7.5 minutes
  
  Une fois terminé :
  SQL> SELECT * FROM v$asm_operation;
  
  no rows selected
  
  [OK] Rééquilibrage terminé (aucune opération en cours)
  
  SQL> EXIT


ÉTAPE 3 : Modifier la puissance du rééquilibrage (optionnel)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Par défaut, POWER = 1 (lent mais peu d'impact)
  
  Pour accélérer un rebalance en cours :
  
  SQL> ALTER DISKGROUP DATA REBALANCE POWER 5;
  
  -> Augmente la puissance à 5 (équilibre vitesse/impact)
  -> Le rebalance ira 5× plus vite mais consommera plus de ressources
  
  Pour lancer un rebalance manuel (si on l'avait désactivé) :
  
  SQL> ALTER DISKGROUP DATA REBALANCE;
  
  Pour arrêter un rebalance :
  
  SQL> ALTER DISKGROUP DATA REBALANCE POWER 0;
  
  -> Met le rebalance en pause (reprendra plus tard)


ÉTAPE 4 : Retirer un disque d'un disk group
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Scénario : Tu veux retirer un disque (par exemple pour le remplacer).
  
  [ATTENTION]  ATTENTION : N'utilise cette commande QUE si :
     - Le disque est défaillant
     - Tu veux réduire la capacité du disk group
     - Tu veux remplacer le disque par un autre
  
  # En tant que 'grid'
  $ sqlplus / as sysasm
  
  SQL> -- Retirer le disque DATA_0003 (le disque qu'on vient d'ajouter)
  SQL> ALTER DISKGROUP DATA 
       DROP DISK DATA_0003;
  
  Diskgroup altered.
  
  -> ASM commence immédiatement à ÉVACUER les données du disque
  -> Les données sont redistribuées sur les autres disques
  -> Peut prendre plusieurs minutes selon la quantité de données
  
  SQL> -- Surveiller l'opération
  SQL> SELECT group_number, operation, state, sofar, est_work, est_minutes
       FROM v$asm_operation;
  
  GROUP_NUMBER  OPERATION  STATE  SOFAR  EST_WORK  EST_MINUTES
  ------------- ---------- ------ ------ --------- ------------
              1 REBAL      RUN      50        150           5.0
  
  Une fois terminé, le disque passe en état FORMER :
  
  SQL> SELECT name, path, header_status
       FROM v$asm_disk
       WHERE name = 'DATA_0003';
  
  NAME       PATH                     HEADER_STATUS
  ---------- ----------------------- -------------
  DATA_0003  /dev/oracleasm/disk6    FORMER
  
  HEADER_STATUS = FORMER
  -> Ancien membre du disk group (ne contient plus de données valides)
  -> Le disque peut maintenant être retiré physiquement ou réutilisé


ÉTAPE 5 : Démonter et remonter un disk group
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Parfois nécessaire pour la maintenance.
  
  [ATTENTION]  Démonter un disk group = INDISPONIBILITÉ des fichiers
  [ATTENTION]  Si une base de données utilise ce disk group -> elle CRASHERA
  
  # Démonter FRA (qui ne contient pas encore de base active)
  SQL> ALTER DISKGROUP FRA DISMOUNT;
  
  Diskgroup altered.
  
  SQL> -- Vérifier l'état
  SQL> SELECT name, state FROM v$asm_diskgroup;
  
  NAME  STATE
  ----- --------
  DATA  MOUNTED
  FRA   DISMOUNTED
  
  [OK] FRA est maintenant démonté (pas accessible)
  
  # Remonter FRA
  SQL> ALTER DISKGROUP FRA MOUNT;
  
  Diskgroup altered.
  
  SQL> SELECT name, state FROM v$asm_diskgroup;
  
  NAME  STATE
  ----- --------
  DATA  MOUNTED
  FRA   MOUNTED
  
  [OK] FRA est remonté et accessible
  
  SQL> EXIT


═══════════════════════════════════════════════════════════════════════════════
6.5 SIMULATION DE PANNE ET RÉCUPÉRATION
═══════════════════════════════════════════════════════════════════════════════

[ATTENTION]  ATTENTION : Cette section est à titre ÉDUCATIF
[ATTENTION]  Ne PAS exécuter sur un système de production !
[ATTENTION]  Effectue ces tests UNIQUEMENT sur un environnement de test


SCÉNARIO 1 : Panne d'un disque (simulation)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Nous allons simuler une panne de disque en rendant un disque inaccessible.
  
  # En tant que root
  $ sudo su -
  
  # Sauvegarder les permissions actuelles du disque
  # ls -l /dev/oracleasm/disk3
  lrwxrwxrwx 1 grid asmadmin 6 Dec 20 16:00 /dev/oracleasm/disk3 -> ../sdd
  
  # Rendre le disque inaccessible (simulation de panne)
  # chmod 000 /dev/sdd
  
  # Vérifier
  # ls -l /dev/sdd
  b--------- 1 grid asmadmin 8, 48 Dec 20 18:00 /dev/sdd
  
  -> Permissions 000 = personne ne peut lire/écrire sur ce disque
  -> Simule un disque défaillant
  
  # Attendre quelques secondes que ASM détecte la panne
  # sleep 30
  
  # Se reconnecter en tant que 'grid'
  # exit
  $ sudo su - grid
  
  # Vérifier l'état des disques
  $ sqlplus / as sysasm
  
  SQL> SELECT name, path, header_status, mode_status, state
       FROM v$asm_disk
       WHERE name LIKE 'DATA%'
       ORDER BY name;
  
  Sortie attendue :
  
  NAME       PATH                     HEADER_STATUS  MODE_STATUS  STATE
  ---------- ----------------------- -------------- ------------ -------
  DATA_0000  /dev/oracleasm/disk1    MEMBER         ONLINE       NORMAL
  DATA_0001  /dev/oracleasm/disk2    MEMBER         ONLINE       NORMAL
  DATA_0002  /dev/oracleasm/disk3    MEMBER         OFFLINE      NORMAL
  
  Interprétation :
  
  DATA_0002 (disk3) : MODE_STATUS = OFFLINE
  -> ASM a détecté que le disque est inaccessible
  -> Il a basculé sur les COPIES MIROIR des données
  -> Les applications continuent de fonctionner normalement
  
  [OK] Redondance NORMAL fonctionne : 1 disque en panne, pas d'interruption
  
  SQL> -- Vérifier l'état du disk group
  SQL> SELECT name, state, offline_disks
       FROM v$asm_diskgroup
       WHERE name = 'DATA';
  
  NAME  STATE    OFFLINE_DISKS
  ----- -------- -------------
  DATA  MOUNTED              1
  
  STATE = MOUNTED
  -> Le disk group est toujours monté et fonctionnel
  
  OFFLINE_DISKS = 1
  -> 1 disque hors ligne
  -> [ATTENTION]  Si un 2ème disque tombe en panne -> PERTE DE DONNÉES (avec NORMAL)
  
  SQL> EXIT


RÉCUPÉRATION : Remplacer le disque défaillant
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Deux options :
  
  Option A : Réparer le disque existant (si panne temporaire)
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  # En tant que root
  $ sudo chmod 660 /dev/sdd
  $ sudo chown grid:asmadmin /dev/sdd
  
  # ASM détectera automatiquement que le disque est de retour
  # Il resynchronisera les données (rebalance automatique)
  
  # Vérifier (en tant que grid)
  $ sqlplus / as sysasm
  
  SQL> SELECT name, mode_status, state
       FROM v$asm_disk
       WHERE name = 'DATA_0002';
  
  NAME       MODE_STATUS  STATE
  ---------- ------------ ---------
  DATA_0002  ONLINE       SYNCING
  
  MODE_STATUS = ONLINE
  -> Le disque est de nouveau accessible
  
  STATE = SYNCING
  -> ASM est en train de resynchroniser les données
  -> Passera à NORMAL une fois terminé
  
  Une fois la resynchronisation terminée :
  
  SQL> SELECT name, mode_status, state
       FROM v$asm_disk
       WHERE name = 'DATA_0002';
  
  NAME       MODE_STATUS  STATE
  ---------- ------------ -------
  DATA_0002  ONLINE       NORMAL
  
  [OK] Disque complètement récupéré
  
  SQL> EXIT
  
  
  Option B : Remplacer par un nouveau disque (si disque HS)
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  # En tant que grid
  $ sqlplus / as sysasm
  
  SQL> -- Retirer le disque défaillant
  SQL> ALTER DISKGROUP DATA
       DROP DISK DATA_0002 FORCE;
  
  -> FORCE = ne pas attendre que les données soient évacuées
  -> Utilise les copies miroir pour reconstruire les données
  
  Diskgroup altered.
  
  SQL> -- Ajouter un nouveau disque
  SQL> ALTER DISKGROUP DATA
       ADD DISK '/dev/oracleasm/disk7';
  
  Diskgroup altered.
  
  [OK] Nouveau disque ajouté, rebalance automatique en cours


┌────────────────────────────────────────────────────────────────────────────┐
│                      RÉCAPITULATIF DE LA PARTIE 6                          │
└────────────────────────────────────────────────────────────────────────────┘

[OK] Disk group FRA créé avec succès
   2 disques, NORMAL redundancy, ~10 GB utilisable

[OK] Navigation dans ASM avec ASMCMD maîtrisée
   pwd, cd, ls, mkdir, lsdg, lsdsk

[OK] Métadonnées ASM sauvegardées
   md_backup pour protéger la configuration

[OK] Opérations de maintenance effectuées
   - Ajout de disque à un disk group
   - Surveillance du rééquilibrage
   - Retrait de disque
   - Montage/démontage de disk group

[OK] Résilience testée
   - Simulation de panne de disque
   - Vérification du basculement sur les miroirs
   - Récupération du disque défaillant

[TEMPS]  Temps total de la partie 6 : 45-60 minutes

PROCHAINE ÉTAPE : Installation Oracle Database
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Dans la partie 7, nous allons :
1. Télécharger et installer Oracle Database 19c (binaires)
2. Configurer le listener réseau
3. Créer une base de données ORCL stockée sur ASM
4. Vérifier que la base utilise correctement les disk groups DATA et FRA
5. Effectuer des tests de base

################################################################################
#                                                                              #
#  PARTIE 7 : INSTALLATION ORACLE DATABASE                                    #
#            (par l'utilisateur 'oracle')                                      #
#                                                                              #
################################################################################

Dans cette partie, nous allons :
1. Télécharger Oracle Database 19c
2. Installer les binaires Oracle Database (software only)
3. Configurer le listener réseau
4. Créer une base de données ORCL sur ASM
5. Vérifier l'intégration complète avec ASM
6. Effectuer des tests de base

[TEMPS]  Durée estimée : 90-120 minutes

═══════════════════════════════════════════════════════════════════════════════
7.1 TÉLÉCHARGEMENT D'ORACLE DATABASE 19c
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│                    OÙ TÉLÉCHARGER ORACLE DATABASE 19c ?                    │
└────────────────────────────────────────────────────────────────────────────┘

Site officiel Oracle :
-> https://www.oracle.com/database/technologies/oracle19c-linux-downloads.html

[ATTENTION]  IMPORTANT : Tu as besoin d'un compte Oracle (gratuit)
[ATTENTION]  Accepter la licence Oracle Technology Network (OTN)


ÉTAPE 1 : Télécharger le fichier ZIP
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Fichier à télécharger :
  Nom : LINUX.X64_193000_db_home.zip
  Taille : ~3.1 GB
  Checksum (SHA256) : Vérifie sur le site Oracle
  
  Option A : Télécharger depuis un navigateur web
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  1. Aller sur https://www.oracle.com/database/technologies/oracle19c-linux-downloads.html
  2. Se connecter avec ton compte Oracle
  3. Accepter la licence OTN
  4. Télécharger "Oracle Database 19c (19.3) for Linux x86-64"
  5. Transférer le fichier vers le serveur Ubuntu :
     $ scp LINUX.X64_193000_db_home.zip user@oracledb:/tmp/
  6. Sur le serveur :
     $ sudo mv /tmp/LINUX.X64_193000_db_home.zip /u01/stage/database/
     $ sudo chown oracle:oinstall /u01/stage/database/LINUX.X64_193000_db_home.zip


ÉTAPE 2 : Vérifier le fichier téléchargé
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Se connecter en tant que 'oracle'
  $ sudo su - oracle
  
  # Vérifier la présence du fichier
  $ ls -lh /u01/stage/database/
  
  Sortie attendue :
  -rw-r--r-- 1 oracle oinstall 3.1G Dec 20 18:00 LINUX.X64_193000_db_home.zip
  
  # Vérifier la taille
  $ du -sh /u01/stage/database/LINUX.X64_193000_db_home.zip
  3.1G    /u01/stage/database/LINUX.X64_193000_db_home.zip
  
  # Vérifier l'intégrité du ZIP (optionnel mais recommandé)
  $ unzip -t /u01/stage/database/LINUX.X64_193000_db_home.zip | tail -5
  
  Sortie attendue (dernières lignes) :
  ...
  testing: install/utl/scripts/orainstroot.sh   OK
  testing: install/utl/scripts/ronly.sql   OK
  No errors detected in compressed data of LINUX.X64_193000_db_home.zip.
  
  [OK] Le fichier ZIP est valide


═══════════════════════════════════════════════════════════════════════════════
7.2 INSTALLATION DES BINAIRES ORACLE DATABASE (SOFTWARE ONLY)
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│               STRATÉGIE D'INSTALLATION ORACLE DATABASE                     │
└────────────────────────────────────────────────────────────────────────────┘

Nous allons installer en DEUX ÉTAPES :

ÉTAPE 1 : Installation du LOGICIEL SEUL (software only)
  -> Installe les binaires Oracle Database dans ORACLE_HOME
  -> N'installe PAS de listener
  -> Ne crée PAS de base de données
  -> Avantage : tu peux installer plusieurs bases de données plus tard

ÉTAPE 2 : Création de la BASE DE DONNÉES (dans la section 7.4)
  -> Utilise DBCA (Database Configuration Assistant)
  -> Crée la base ORCL sur les disk groups ASM
  -> Configure les fichiers sur DATA et FRA

Pourquoi cette approche ?
[OK] Flexibilité : un seul logiciel, plusieurs bases possibles
[OK] Maintenance : upgrade du logiciel sans toucher aux bases
[OK] Best practice Oracle


ÉTAPE 1 : Extraire le ZIP directement dans ORACLE_HOME
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'oracle'
  $ cd /u01/app/oracle/product/19.3.0/dbhome_1
  
  # Vérifier que le répertoire est vide
  $ ls -la
  total 8
  drwxr-xr-x 2 oracle oinstall 4096 Dec 20 14:00 .
  drwxr-xr-x 3 oracle oinstall 4096 Dec 20 14:00 ..
  [OK] Vide
  
  # Extraire le ZIP
  $ unzip -q /u01/stage/database/LINUX.X64_193000_db_home.zip
  
  [TEMPS]  Temps : 5-10 minutes
  
  [ATTENTION]  SI tu vois une erreur "No space left on device" :
  -> Vérifie l'espace disque : df -h /u01
  -> Tu as besoin d'au moins 12 GB libres


ÉTAPE 2 : Vérifier l'extraction
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Lister le contenu d'ORACLE_HOME
  $ ls -l /u01/app/oracle/product/19.3.0/dbhome_1/
  
  Sortie attendue (répertoires principaux) :
  drwxr-xr-x  2 oracle oinstall  4096 Dec 20 18:15 apex
  drwxr-xr-x  3 oracle oinstall  4096 Dec 20 18:15 assistants
  drwxr-xr-x  2 oracle oinstall 12288 Dec 20 18:15 bin         <- Binaires
  drwxr-xr-x  5 oracle oinstall  4096 Dec 20 18:15 clone
  drwxr-xr-x  9 oracle oinstall  4096 Dec 20 18:15 crs
  drwxr-xr-x  3 oracle oinstall  4096 Dec 20 18:15 css
  drwxr-xr-x  4 oracle oinstall  4096 Dec 20 18:15 ctx
  drwxr-xr-x  3 oracle oinstall  4096 Dec 20 18:15 cv
  drwxr-xr-x  3 oracle oinstall  4096 Dec 20 18:15 data
  drwxr-xr-x  3 oracle oinstall  4096 Dec 20 18:15 dbs         <- Fichiers config DB
  drwxr-xr-x  5 oracle oinstall  4096 Dec 20 18:15 deinstall
  drwxr-xr-x  2 oracle oinstall  4096 Dec 20 18:15 demo
  drwxr-xr-x  3 oracle oinstall  4096 Dec 20 18:15 dmu
  drwxr-xr-x  6 oracle oinstall  4096 Dec 20 18:15 install
  drwxr-xr-x  8 oracle oinstall  4096 Dec 20 18:15 jdbc
  drwxr-xr-x  8 oracle oinstall  4096 Dec 20 18:15 jdk         <- Java JDK
  drwxr-xr-x  6 oracle oinstall  4096 Dec 20 18:15 jlib
  drwxr-xr-x  2 oracle oinstall  4096 Dec 20 18:15 lib         <- Bibliothèques
  drwxr-xr-x  4 oracle oinstall  4096 Dec 20 18:15 md
  drwxr-xr-x  5 oracle oinstall  4096 Dec 20 18:15 network     <- Config réseau
  drwxr-xr-x  3 oracle oinstall  4096 Dec 20 18:15 nls
  drwxr-xr-x  3 oracle oinstall  4096 Dec 20 18:15 odbc
  drwxr-xr-x  5 oracle oinstall  4096 Dec 20 18:15 OPatch      <- Gestion patches
  drwxr-xr-x 10 oracle oinstall  4096 Dec 20 18:15 ord
  drwxr-xr-x  4 oracle oinstall  4096 Dec 20 18:15 ords
  drwxr-xr-x  2 oracle oinstall  4096 Dec 20 18:15 oui
  drwxr-xr-x  3 oracle oinstall  4096 Dec 20 18:15 owm
  drwxr-xr-x  5 oracle oinstall  4096 Dec 20 18:15 perl
  drwxr-xr-x  2 oracle oinstall  4096 Dec 20 18:15 plsql
  drwxr-xr-x 13 oracle oinstall  4096 Dec 20 18:15 precomp
  drwxr-xr-x  2 oracle oinstall  4096 Dec 20 18:15 QOpatch
  drwxr-xr-x  9 oracle oinstall  4096 Dec 20 18:15 racg
  drwxr-xr-x 12 oracle oinstall  4096 Dec 20 18:15 rdbms       <- Moteur DB
  -rwxr-x---  1 oracle oinstall   134 Dec 20 18:15 root.sh     <- Script root
  -rwxr-x---  1 oracle oinstall   115 Dec 20 18:15 runInstaller
  drwxr-xr-x  4 oracle oinstall  4096 Dec 20 18:15 sdk
  drwxr-xr-x  3 oracle oinstall  4096 Dec 20 18:15 sqlpatch
  drwxr-xr-x 10 oracle oinstall  4096 Dec 20 18:15 sqlplus     <- SQL*Plus
  drwxr-xr-x  3 oracle oinstall  4096 Dec 20 18:15 srvm
  drwxr-xr-x  2 oracle oinstall  4096 Dec 20 18:15 suptools
  drwxr-xr-x  2 oracle oinstall  4096 Dec 20 18:15 ucp
  drwxr-xr-x  4 oracle oinstall  4096 Dec 20 18:15 usm
  drwxr-xr-x  3 oracle oinstall  4096 Dec 20 18:15 wwg
  drwxr-xr-x  2 oracle oinstall  4096 Dec 20 18:15 xdk
  
  # Vérifier la présence des exécutables clés
  $ ls -l /u01/app/oracle/product/19.3.0/dbhome_1/bin/sqlplus
  -rwxr-x--- 1 oracle oinstall 12345 Apr 17  2019 .../bin/sqlplus
  [OK] Binaires présents
  
  # Vérifier l'espace utilisé
  $ du -sh /u01/app/oracle/product/19.3.0/dbhome_1
  8.8G    /u01/app/oracle/product/19.3.0/dbhome_1


ÉTAPE 3 : Créer le fichier de réponse pour l'installation software only
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'oracle'
  $ cd /u01/stage/database
  
  # Créer le fichier db_install.rsp
  $ cat > db_install.rsp << 'EOF'
#############################################################################
# Response File pour l'installation d'Oracle Database 19c
# Mode : SOFTWARE ONLY (pas de création de base de données)
# Date : 2024-12-20
#############################################################################

#-----------------------------------------------------------------------------
# INFORMATIONS GÉNÉRALES
#-----------------------------------------------------------------------------

# Version du format du response file
oracle.install.responseFileVersion=/oracle/install/rspfmt_dbinstall_response_schema_v19.0.0

# Type d'installation
# Options possibles :
#   - INSTALL_DB_SWONLY : Software only (notre choix)
#   - INSTALL_DB_AND_CONFIG : Software + création de DB
#   - UPGRADE_DB : Upgrade d'une DB existante
oracle.install.option=INSTALL_DB_SWONLY

# Nom du système d'exploitation (détection auto)
ORACLE_HOSTNAME=

#-----------------------------------------------------------------------------
# LOCALISATIONS DES RÉPERTOIRES
#-----------------------------------------------------------------------------

# ORACLE_BASE : Répertoire racine pour l'utilisateur oracle
ORACLE_BASE=/u01/app/oracle

# ORACLE_HOME : Répertoire du logiciel Oracle Database
ORACLE_HOME=/u01/app/oracle/product/19.3.0/dbhome_1

# Inventaire Oracle (partagé avec Grid Infrastructure)
INVENTORY_LOCATION=/u01/app/oraInventory

#-----------------------------------------------------------------------------
# ÉDITION ORACLE DATABASE
#-----------------------------------------------------------------------------

# Édition à installer
# Options :
#   - EE : Enterprise Edition (complète, toutes les fonctionnalités)
#   - SE2 : Standard Edition 2 (limitée)
oracle.install.db.InstallEdition=EE

# Composants optionnels pour Enterprise Edition
# true = installer tous les composants
# false = installation minimale
oracle.install.db.OSDBA_GROUP=dba
oracle.install.db.OSOPER_GROUP=oper
oracle.install.db.OSBACKUPDBA_GROUP=backupdba
oracle.install.db.OSDGDBA_GROUP=dgdba
oracle.install.db.OSKMDBA_GROUP=kmdba
oracle.install.db.OSRACDBA_GROUP=dba

#-----------------------------------------------------------------------------
# CONFIGURATION DES GROUPES UNIX
#-----------------------------------------------------------------------------

# Groupe d'administration de la base (SYSDBA)
oracle.install.db.OSDBA_GROUP=dba

# Groupe pour les opérations (SYSOPER)
oracle.install.db.OSOPER_GROUP=oper

# Groupe pour les backups (SYSBACKUP)
oracle.install.db.OSBACKUPDBA_GROUP=backupdba

# Groupe pour Data Guard (SYSDG)
oracle.install.db.OSDGDBA_GROUP=dgdba

# Groupe pour la gestion des clés (SYSKM)
oracle.install.db.OSKMDBA_GROUP=kmdba

# Groupe pour RAC (SYSRAC)
oracle.install.db.OSRACDBA_GROUP=dba

#-----------------------------------------------------------------------------
# CONFIGURATION RÉSEAU
#-----------------------------------------------------------------------------

# Créer un listener pendant l'installation ?
# false = on le créera manuellement plus tard (notre choix)
oracle.install.db.config.starterdb.type=GENERAL_PURPOSE
oracle.install.db.ConfigureAsContainerDB=false

#-----------------------------------------------------------------------------
# CONFIGURATION ROOT SCRIPTS
#-----------------------------------------------------------------------------

# Exécuter automatiquement les scripts root ?
# false = on les exécutera manuellement (plus sûr)
oracle.install.db.rootconfig.executeRootScript=false

# Si true, spécifier les credentials root
#oracle.install.db.rootconfig.configMethod=ROOT
#oracle.install.db.rootconfig.sudoPath=
#oracle.install.db.rootconfig.sudoUserName=

#-----------------------------------------------------------------------------
# CONFIGURATION DÉCLINE SECURITY UPDATES
#-----------------------------------------------------------------------------

# Recevoir les notifications de sécurité d'Oracle ?
# false = non (on peut configurer plus tard)
oracle.installer.autoupdates.option=SKIP_UPDATES

# Email pour les notifications (optionnel)
MYORACLESUPPORT_USERNAME=
MYORACLESUPPORT_PASSWORD=

# Accepter de ne pas recevoir les updates de sécurité
DECLINE_SECURITY_UPDATES=true

#-----------------------------------------------------------------------------
# OPTIONS AVANCÉES
#-----------------------------------------------------------------------------

# Ignorer certains pré-requis ?
# [ATTENTION]  false = recommandé (arrêter si pré-requis non satisfaits)
oracle.installer.ignorePrerequiste=false

#############################################################################
# Fin du fichier de réponse
#############################################################################
EOF

  # [TEMPS]  Temps : 2 minutes


ÉTAPE 4 : Lancer l'installation du logiciel
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'oracle'
  $ cd /u01/app/oracle/product/19.3.0/dbhome_1
  
  # Lancer l'installeur en mode silencieux
  $ ./runInstaller \
      -silent \
      -responseFile /u01/stage/database/db_install.rsp \
      -ignorePrereqFailure
  
  Explication des options :
  
  -silent
  -> Mode silencieux (pas d'interface graphique)
  
  -responseFile /chemin/vers/fichier.rsp
  -> Fichier de réponses
  
  -ignorePrereqFailure (optionnel, À UTILISER AVEC PRÉCAUTION)
  -> Continue même si certains pré-requis échouent
  -> Utile sur Ubuntu (Oracle vérifie pour RHEL/OEL)
  
  [TEMPS]  Temps : 30-45 minutes
  
  Sortie attendue :
  
  Launching Oracle Database Setup Wizard...
  
  [WARNING] [INS-13014] Target environment does not meet some optional requirements.
     CAUSE: Some of the optional prerequisites are not met.
     ACTION: Identify the list of failed prerequisite checks from the log...
  
  [ATTENTION]  Les WARNINGS sont normaux sur Ubuntu
  
  The response file for this session can be found at:
   /u01/app/oracle/product/19.3.0/dbhome_1/install/response/db_2024-12-20_06-30-15PM.rsp
  
  You can find the log of this install session at:
   /u01/app/oraInventory/logs/InstallActions2024-12-20_06-30-15PM.log
  
  [...]
  
  Prepare the home to patch...
  Applying the patch /u01/app/oracle/product/19.3.0/dbhome_1/...
  Successfully applied the patch.
  
  [...]
  
  As a root user, execute the following script(s):
          1. /u01/app/oracle/product/19.3.0/dbhome_1/root.sh
  
  Execute /u01/app/oracle/product/19.3.0/dbhome_1/root.sh on the following nodes: 
  [oracledb]
  
  -> L'installeur s'arrête et ATTEND que tu exécutes le script root
  -> Ouvre un NOUVEAU terminal pour exécuter le script
  
  Run the script on the local node and remote nodes
  After execution of the script on all nodes, enter 'YES' to continue:


ÉTAPE 5 : Exécuter le script root.sh
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Dans un NOUVEAU terminal :
  
  # Se connecter en tant que root
  $ sudo su -
  
  # Exécuter le script
  # cd /u01/app/oracle/product/19.3.0/dbhome_1
  # ./root.sh
  
  Sortie attendue :
  
  Performing root user operation.
  
  The following environment variables are set as:
      ORACLE_OWNER= oracle
      ORACLE_HOME=  /u01/app/oracle/product/19.3.0/dbhome_1
  
  Enter the full pathname of the local bin directory: [/usr/local/bin]: 
  -> Appuie sur ENTER (accepter le défaut)
  
  The contents of "dbhome" have not changed. No need to overwrite.
  The contents of "oraenv" have not changed. No need to overwrite.
  The contents of "coraenv" have not changed. No need to overwrite.
  
  Entries will be added to the /etc/oratab file as needed by
  Database Configuration Assistant when a database is created
  Finished running generic part of root script.
  Now product-specific root actions will be performed.
  
  [OK] Script terminé avec succès
  
  [TEMPS]  Temps : quelques secondes
  
  # Quitter la session root
  # exit


ÉTAPE 6 : Confirmer à l'installeur et finaliser
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Retourne au terminal de l'installeur (terminal 'oracle') :
  
  Run the script on the local node and remote nodes
  After execution of the script on all nodes, enter 'YES' to continue: YES
  
  -> Tape : YES
  -> Appuie sur ENTER
  
  L'installeur termine :
  
  Successfully Setup Software.
  
  [OK] Installation du logiciel Oracle Database terminée !


ÉTAPE 7 : Vérifier l'installation
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'oracle'
  $ echo $ORACLE_HOME
  /u01/app/oracle/product/19.3.0/dbhome_1
  
  # Vérifier que sqlplus est accessible
  $ which sqlplus
  /u01/app/oracle/product/19.3.0/dbhome_1/bin/sqlplus
  
  # Vérifier la version (ne lancera PAS sqlplus, juste affiche la version)
  $ sqlplus -version
  
  SQL*Plus: Release 19.0.0.0.0 - Production
  Version 19.3.0.0.0
  
  [OK] Le logiciel Oracle Database 19c est installé et opérationnel


═══════════════════════════════════════════════════════════════════════════════
7.3 CONFIGURATION DU LISTENER RÉSEAU
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│                    QU'EST-CE QU'UN LISTENER ORACLE ?                       │
└────────────────────────────────────────────────────────────────────────────┘

Le LISTENER = processus réseau qui écoute les connexions entrantes
-> Sans listener, tu ne peux te connecter QUE localement (sqlplus / as sysdba)
-> Avec listener, les applications distantes peuvent se connecter

ANALOGIE :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Le listener = réceptionniste d'un hôtel
-> Il écoute le téléphone (port 1521)
-> Quand un client appelle : "Je veux réserver une chambre dans l'hôtel ORCL"
-> Le listener transfère l'appel au bon service (instance ORCL)
-> Le client peut maintenant communiquer avec l'hôtel


QUI GÈRE LE LISTENER : 'grid' OU 'oracle' ?
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Deux approches possibles :

Approche 1 : Listener géré par 'grid' (RECOMMANDÉ)
  [OK] Le listener est démarré par Oracle Restart (haute disponibilité)
  [OK] Il redémarre automatiquement en cas de crash
  [OK] Un seul listener pour toutes les bases de données du serveur
  [OK] Bonne pratique Oracle

Approche 2 : Listener géré par 'oracle'
  [OK] Plus simple à configurer pour un débutant
  [OK] Chaque base peut avoir son propre listener
  [OK] Pas de haute disponibilité automatique

Dans ce guide : nous utilisons l'Approche 1 (listener géré par 'grid')


ÉTAPE 1 : Vérifier le listener existant (géré par Grid Infrastructure)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Lors de l'installation de Grid Infrastructure, un listener a été créé automatiquement.
  
  # En tant que 'grid'
  $ sudo su - grid
  
  # Vérifier l'état du listener
  $ lsnrctl status
  
  Sortie attendue :
  
  LSNRCTL for Linux: Version 19.0.0.0.0 - Production on 20-DEC-2024 19:00:00
  
  Copyright (c) 1991, 2019, Oracle.  All rights reserved.
  
  Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oracledb)(PORT=1521)))
  STATUS of the LISTENER
  ------------------------
  Alias                     LISTENER
  Version                   TNSLSNR for Linux: Version 19.0.0.0.0 - Production
  Start Date                20-DEC-2024 15:47:10
  Uptime                    0 days 3 hr. 12 min. 50 sec
  Trace Level               off
  Security                  ON: Local OS Authentication
  SNMP                      OFF
  Listener Parameter File   /u01/app/19.3.0/grid/network/admin/listener.ora
  Listener Log File         /u01/app/grid/diag/tnslsnr/oracledb/listener/alert/log.xml
  Listening Endpoints Summary...
    (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=oracledb)(PORT=1521)))
    (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=LISTENER)))
  Services Summary...
  Service "+ASM" has 1 instance(s).
    Instance "+ASM", status READY, has 1 handler(s) for this service...
  The command completed successfully
  
  Interprétation :
  
  Alias = LISTENER
  -> Nom du listener (par défaut : LISTENER)
  
  Version = 19.0.0.0.0
  -> Version Grid Infrastructure
  
  Start Date
  -> Date/heure de démarrage (au boot du serveur)
  
  Listener Parameter File
  -> /u01/app/19.3.0/grid/network/admin/listener.ora
  -> Fichier de configuration du listener
  
  Listening Endpoints Summary
  -> (PROTOCOL=tcp)(HOST=oracledb)(PORT=1521)
  -> Le listener écoute sur le port TCP 1521
  
  Services Summary
  -> Service "+ASM" has 1 instance
  -> Le listener connaît déjà l'instance ASM (+ASM)
  -> Mais il ne connaît PAS encore la base ORCL (on ne l'a pas créée)
  
  [OK] Le listener fonctionne et écoute sur le port 1521


ÉTAPE 2 : Vérifier le fichier listener.ora
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'grid'
  $ cat /u01/app/19.3.0/grid/network/admin/listener.ora
  
  Contenu typique :
  
  # listener.ora Network Configuration File: /u01/app/19.3.0/grid/network/admin/listener.ora
  # Generated by Oracle configuration tools.
  
  LISTENER = 
    (DESCRIPTION_LIST = 
      (DESCRIPTION = 
        (ADDRESS = (PROTOCOL = TCP)(HOST = oracledb)(PORT = 1521))
        (ADDRESS = (PROTOCOL = IPC)(KEY = LISTENER))
      ) 
    ) 
  
  ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER=ON
  
  Explication :
  
  LISTENER
  -> Nom du listener (convention : majuscules)
  
  DESCRIPTION_LIST
  -> Liste des endpoints où le listener écoute
  
  ADDRESS = (PROTOCOL = TCP)(HOST = oracledb)(PORT = 1521)
  -> Écoute sur TCP, host oracledb, port 1521
  
  ADDRESS = (PROTOCOL = IPC)(KEY = LISTENER)
  -> Écoute également sur IPC (Inter-Process Communication)
  -> Pour les connexions locales rapides
  
  ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER=ON
  -> Enregistrement dynamique activé
  -> Les instances peuvent s'enregistrer automatiquement auprès du listener
  -> On n'a PAS besoin de configurer manuellement chaque base
  
  [OK] Configuration par défaut suffisante pour notre usage


ÉTAPE 3 : Vérifier que le listener est géré par Oracle Restart
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'grid'
  $ crsctl stat res ora.LISTENER.lsnr -t
  
  Sortie attendue :
  
  --------------------------------------------------------------------------------
  Name           Target  State        Server                   State details       
  --------------------------------------------------------------------------------
  ora.LISTENER.lsnr
                 ONLINE  ONLINE       oracledb                 STABLE
  --------------------------------------------------------------------------------
  
  Target = ONLINE
  -> Le listener doit être en ligne (configuration cible)
  
  State = ONLINE
  -> Le listener est effectivement en ligne
  
  STABLE
  -> Aucune transition en cours
  
  [OK] Le listener est géré par Oracle Restart
  [OK] Il redémarrera automatiquement au boot et en cas de crash


═══════════════════════════════════════════════════════════════════════════════
7.4 CRÉATION DE LA BASE DE DONNÉES ORCL SUR ASM
═══════════════════════════════════════════════════════════════════════════════

Maintenant que le logiciel est installé et le listener configuré,
nous allons créer une base de données stockée sur ASM.

┌────────────────────────────────────────────────────────────────────────────┐
│                    MÉTHODES DE CRÉATION DE BASE DE DONNÉES                 │
└────────────────────────────────────────────────────────────────────────────┘

Méthode 1 : DBCA en mode graphique (GUI)
  -> Interface graphique interactive
  -> Nécessite X11 (connexion SSH avec -X)
  -> Simple mais nécessite un affichage graphique

Méthode 2 : DBCA en mode silencieux (notre choix)
  -> Utilise un fichier de réponse
  -> Pas d'interface graphique nécessaire
  -> Automatisable et répétable

Méthode 3 : Scripts SQL manuels
  -> CREATE DATABASE en SQL
  -> Très technique, pour experts
  -> Contrôle total mais complexe

Dans ce guide : Méthode 2 (DBCA silencieux)


ÉTAPE 1 : Préparer le fichier de réponse DBCA
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'oracle'
  $ sudo su - oracle
  $ cd /u01/stage/database
  
  # Créer le fichier dbca.rsp
  $ cat > dbca.rsp << 'EOF'
#############################################################################
# Response File pour la création d'une base de données Oracle 19c
# Base : ORCL
# Stockage : ASM (disk groups DATA et FRA)
# Date : 2024-12-20
#############################################################################

#-----------------------------------------------------------------------------
# INFORMATIONS GÉNÉRALES
#-----------------------------------------------------------------------------

# Version du format
responseFileVersion=/oracle/assistants/rspfmt_dbca_response_schema_v19.0.0

# Type d'opération
# Options : createDatabase, createTemplateFromDB, createClone, deleteDatabase
gdbName=ORCL.localdomain

# SID de l'instance
sid=ORCL

# Type de création
# Options :
#   - GENERAL_PURPOSE : Usage général (notre choix)
#   - DATA_WAREHOUSE : Entrepôt de données
#   - CUSTOM : Personnalisé
databaseConfigType=SI

# Créer une Container Database (CDB) ?
# false = base de données classique (non-CDB)
# true = architecture multitenant avec PDBs
createAsContainerDatabase=false

# Si true, nombre de PDBs à créer
#numberOfPDBs=1
#pdbName=PDB1
#pdbAdminPassword=

#-----------------------------------------------------------------------------
# TEMPLATE
#-----------------------------------------------------------------------------

# Template à utiliser
# General_Purpose.dbc = template par défaut avec seed database
templateName=General_Purpose.dbc

#-----------------------------------------------------------------------------
# STOCKAGE : ASM
#-----------------------------------------------------------------------------

# Type de stockage
# Options : FS (file system), ASM, DBFS
storageType=ASM

# Disk group pour les datafiles
datafileDestination=+DATA

# Disk group pour la Fast Recovery Area
recoveryAreaDestination=+FRA

# Taille de la FRA (en GB)
recoveryAreaSize=15

#-----------------------------------------------------------------------------
# CARACTÉRISTIQUES DE LA BASE DE DONNÉES
#-----------------------------------------------------------------------------

# Caracterset de la base
# AL32UTF8 = Unicode, recommandé pour applications modernes
characterSet=AL32UTF8

# National character set
nationalCharacterSet=AL16UTF16

# Langue par défaut
# AMERICAN = anglais américain
databaseType=MULTIPURPOSE
automaticMemoryManagement=FALSE

# Taille totale de la mémoire (SGA + PGA) en MB
# Règle : 40-50% de la RAM totale
# Exemple : 8 GB RAM -> 3-4 GB pour Oracle
# On alloue 2 GB (2048 MB) pour ce guide
totalMemory=2048

#-----------------------------------------------------------------------------
# CONFIGURATION DES MOTS DE PASSE
#-----------------------------------------------------------------------------

# Mots de passe pour les comptes privilégiés
# SYS et SYSTEM auront le même mot de passe
# [ATTENTION]  CHANGE CE MOT DE PASSE en production !
sysPassword=Oracle19c#SYS
systemPassword=Oracle19c#SYS

# Créer automatiquement un compte DBSNMP (pour monitoring) ?
# true = oui
# false = non
emConfiguration=NONE

#-----------------------------------------------------------------------------
# OPTIONS AVANCÉES
#-----------------------------------------------------------------------------

# Samples schemas (schémas exemples) ?
# true = installer HR, OE, SH, etc.
# false = ne pas installer (recommandé pour production)
sampleSchema=false

# Mode d'archivage des redo logs
# true = ARCHIVELOG mode (recommandé, permet la récupération point-in-time)
# false = NOARCHIVELOG mode (pas de récupération point-in-time)
enableArchive=true

# Créer le script de base de données ?
# false = créer la base directement (notre choix)
# true = générer juste le script sans l'exécuter
createDatabaseScriptsOnly=false

# Enregistrer la base dans Oracle Restart ?
# true = oui (recommandé, permet le démarrage automatique)
registerWithDirService=false

# Variables pour Oracle Restart
# On laisse vides, Oracle Restart gérera automatiquement
variables=

# Initparams (paramètres d'initialisation)
# On laisse les valeurs par défaut, on les modifiera après si besoin
initParams=

# Script à exécuter après création (optionnel)
#postDBCreationScript=

#-----------------------------------------------------------------------------
# LISTENERS
#-----------------------------------------------------------------------------

# Liste des listeners à configurer
# LISTENER = le listener créé par Grid Infrastructure
listeners=LISTENER

#-----------------------------------------------------------------------------
# OPTIONS DE CRÉATION
#-----------------------------------------------------------------------------

# Créer le listener ?
# false = utiliser le listener existant (géré par grid)
createListener=false

# Nom du listener (si on en créait un)
#listenerName=LISTENER

# Port du listener (si on en créait un)
#listenerPort=1521

#############################################################################
# Fin du fichier de réponse
#############################################################################
EOF

  # [TEMPS]  Temps : 3 minutes


ÉTAPE 2 : Lancer DBCA pour créer la base de données
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  [ATTENTION]  IMPORTANT : Vérifie que tu as suffisamment d'espace :
     - Disk group DATA : au moins 5 GB libres
     - Disk group FRA : au moins 10 GB libres
  
  # En tant que 'oracle'
  $ dbca -silent -createDatabase -responseFile /u01/stage/database/dbca.rsp
  
  Explication des options :
  
  -silent
  -> Mode silencieux (pas d'interface graphique)
  -> Affiche la progression en mode texte
  
  -createDatabase
  -> Action : créer une nouvelle base de données
  
  -responseFile /chemin/vers/fichier.rsp
  -> Fichier contenant les paramètres de création
  
  [TEMPS]  Temps : 15-30 minutes (selon la puissance du serveur)
  
  Sortie attendue :
  
  [DBT-06208] The 'SYS' password entered does not conform to the Oracle recommended standards.
     CAUSE: 
     a. Oracle recommends that the password entered should be at least 8 characters in length, contain at least 1 uppercase character, 1 lower case character and 1 digit [0-9].
     b.The password entered is a keyword that Oracle does not recommend to be used as password
     ACTION: Specify a strong password. If required refer Oracle documentation for guidelines.
  
  -> WARNING sur le mot de passe (OK, on peut ignorer pour ce guide)
  
  Prepare for db operation
  10% complete
  Copying database files
  40% complete
  Creating and starting Oracle instance
  42% complete
  46% complete
  50% complete
  54% complete
  60% complete
  Completing Database Creation
  66% complete
  69% complete
  70% complete
  Executing Post Configuration Actions
  100% complete
  
  Database creation complete. For details check the logfiles at:
   /u01/app/oracle/cfgtoollogs/dbca/ORCL.
  Database Information:
  Global Database Name:ORCL.localdomain
  System Identifier(SID):ORCL
  Look at the log file "/u01/app/oracle/cfgtoollogs/dbca/ORCL/ORCL.log" for further details.
  
  [OK] Base de données ORCL créée avec succès !


ÉTAPE 3 : Vérifier la création de la base de données
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'oracle'
  $ ps -ef | grep pmon
  
  Sortie attendue :
  oracle   12345     1  0 19:30 ?        00:00:01 ora_pmon_ORCL
  grid     23456     1  0 15:47 ?        00:00:02 asm_pmon_+ASM
  
  Interprétation :
  ora_pmon_ORCL
  -> Process Monitor de l'instance ORCL
  -> Si ce processus existe -> l'instance est démarrée
  
  asm_pmon_+ASM
  -> Process Monitor de l'instance ASM
  
  [OK] L'instance ORCL est démarrée
  
  # Se connecter à la base
  $ sqlplus / as sysdba
  
  SQL*Plus: Release 19.0.0.0.0 - Production on Fri Dec 20 19:45:00 2024
  Version 19.3.0.0.0
  
  Copyright (c) 1982, 2019, Oracle.  All rights reserved.
  
  Connected to:
  Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
  Version 19.3.0.0.0
  
  SQL> SELECT instance_name, status, database_status FROM v$instance;
  
  INSTANCE_NAME    STATUS       DATABASE_STATUS
  ---------------- ------------ ----------------
  ORCL             OPEN         ACTIVE
  
  STATUS = OPEN
  -> L'instance est ouverte (prête à accepter des connexions)
  
  DATABASE_STATUS = ACTIVE
  -> La base est active
  
  [OK] Base de données ORCL opérationnelle
  
  SQL> SELECT name, open_mode FROM v$database;
  
  NAME      OPEN_MODE
  --------- --------------------
  ORCL      READ WRITE
  
  OPEN_MODE = READ WRITE
  -> La base accepte les lectures ET les écritures
  
  SQL> EXIT


═══════════════════════════════════════════════════════════════════════════════
7.5 VÉRIFICATION DE L'INTÉGRATION AVEC ASM
═══════════════════════════════════════════════════════════════════════════════

Vérifions que la base de données utilise correctement les disk groups ASM.

ÉTAPE 1 : Vérifier les fichiers de la base sur ASM
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'oracle'
  $ sqlplus / as sysdba
  
  SQL> -- Lister tous les datafiles
  SQL> SELECT name FROM v$datafile;
  
  NAME
  --------------------------------------------------------------------------------
  +DATA/ORCL/DATAFILE/system.256.1234567890
  +DATA/ORCL/DATAFILE/sysaux.257.1234567891
  +DATA/ORCL/DATAFILE/undotbs1.258.1234567892
  +DATA/ORCL/DATAFILE/users.259.1234567893
  
  [OK] Tous les datafiles sont sur +DATA (disk group DATA)
  
  SQL> -- Lister les control files
  SQL> SELECT name FROM v$controlfile;
  
  NAME
  --------------------------------------------------------------------------------
  +DATA/ORCL/CONTROLFILE/current.260.1234567894
  +FRA/ORCL/CONTROLFILE/current.261.1234567895
  
  [OK] Control files sur DATA et FRA (redondance)
  
  SQL> -- Lister les redo log files
  SQL> SELECT member FROM v$logfile;
  
  MEMBER
  --------------------------------------------------------------------------------
  +DATA/ORCL/ONLINELOG/group_1.262.1234567896
  +FRA/ORCL/ONLINELOG/group_1.263.1234567897
  +DATA/ORCL/ONLINELOG/group_2.264.1234567898
  +FRA/ORCL/ONLINELOG/group_2.265.1234567899
  +DATA/ORCL/ONLINELOG/group_3.266.1234567900
  +FRA/ORCL/ONLINELOG/group_3.267.1234567901
  
  [OK] Redo logs sur DATA et FRA (membres miroirs)
  
  SQL> -- Vérifier les temp files
  SQL> SELECT name FROM v$tempfile;
  
  NAME
  --------------------------------------------------------------------------------
  +DATA/ORCL/TEMPFILE/temp.268.1234567902
  
  [OK] Temp file sur DATA
  
  SQL> EXIT


ÉTAPE 2 : Vérifier avec ASMCMD (en tant que 'grid')
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ sudo su - grid
  $ asmcmd
  
  ASMCMD> cd /DATA/ORCL
  ASMCMD> ls
  CONTROLFILE/
  DATAFILE/
  ONLINELOG/
  PARAMETERFILE/
  TEMPFILE/
  
  ASMCMD> cd DATAFILE
  ASMCMD> ls -l
  Type      Redund  Striped  Time             Sys  Name
  DATAFILE  MIRROR  COARSE   DEC 20 19:30:00  Y    SYSAUX.257.1234567891
  DATAFILE  MIRROR  COARSE   DEC 20 19:30:00  Y    SYSTEM.256.1234567890
  DATAFILE  MIRROR  COARSE   DEC 20 19:30:00  Y    UNDOTBS1.258.1234567892
  DATAFILE  MIRROR  COARSE   DEC 20 19:30:00  Y    USERS.259.1234567893
  
  [OK] Les fichiers sont visibles dans ASM
  
  ASMCMD> cd /FRA/ORCL
  ASMCMD> ls
  ARCHIVELOG/
  AUTOBACKUP/
  CONTROLFILE/
  ONLINELOG/
  
  [OK] Structure FRA créée
  
  ASMCMD> exit


ÉTAPE 3 : Vérifier l'utilisation de l'espace dans les disk groups
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ sudo su - grid
  $ sqlplus / as sysasm
  
  SQL> SELECT name, total_mb, free_mb, usable_file_mb,
              ROUND((total_mb - free_mb) / total_mb * 100, 2) AS pct_used
       FROM v$asm_diskgroup;
  
  NAME  TOTAL_MB  FREE_MB  USABLE_FILE_MB  PCT_USED
  ----- --------- -------- --------------- ---------
  DATA      61440    58200           19100      5.28
  FRA       40960    40600           10150      0.88
  
  Interprétation :
  
  DATA : PCT_USED = 5.28%
  -> ~3 GB utilisés sur ~60 GB (brut)
  -> Cela correspond à une base de données fraîchement créée
  
  FRA : PCT_USED = 0.88%
  -> Très peu utilisé (juste les control files et redo logs miroirs)
  -> Les archived logs s'y accumuleront au fur et à mesure
  
  [OK] Espace suffisant dans les deux disk groups
  
  SQL> EXIT


═══════════════════════════════════════════════════════════════════════════════
7.6 ENREGISTREMENT DANS ORACLE RESTART
═══════════════════════════════════════════════════════════════════════════════

Oracle Restart = système de haute disponibilité pour base standalone
-> Démarre automatiquement la base au boot
-> Redémarre la base en cas de crash

ÉTAPE 1 : Vérifier que la base est enregistrée
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'grid'
  $ sudo su - grid
  $ crsctl stat res -t
  
  Sortie attendue :
  
  --------------------------------------------------------------------------------
  Name           Target  State        Server                   State details       
  --------------------------------------------------------------------------------
  Local Resources
  --------------------------------------------------------------------------------
  ora.DATA.dg
                 ONLINE  ONLINE       oracledb                 STABLE
  ora.FRA.dg
                 ONLINE  ONLINE       oracledb                 STABLE
  ora.LISTENER.lsnr
                 ONLINE  ONLINE       oracledb                 STABLE
  ora.asm
                 ONLINE  ONLINE       oracledb                 Started,STABLE
  ora.ons
                 OFFLINE OFFLINE      oracledb                 STABLE
  --------------------------------------------------------------------------------
  Cluster Resources
  --------------------------------------------------------------------------------
  ora.cssd
        1        ONLINE  ONLINE       oracledb                 STABLE
  ora.diskmon
        1        OFFLINE OFFLINE                               STABLE
  ora.evmd
        1        ONLINE  ONLINE       oracledb                 STABLE
  ora.orcl.db
        1        ONLINE  ONLINE       oracledb                 Open,HOME=/u01/app/oracle/product/19.3.0/dbhome_1,STABLE
  --------------------------------------------------------------------------------
  
  Nouvelle ressource :
  ora.orcl.db
  -> Base de données ORCL enregistrée
  
  Target = ONLINE
  -> Doit être en ligne
  
  State = ONLINE
  -> Est effectivement en ligne
  
  State details = Open
  -> La base est ouverte (READ WRITE)
  
  [OK] La base ORCL est gérée par Oracle Restart
  [OK] Elle démarrera automatiquement au boot


ÉTAPE 2 : Tester l'arrêt et le démarrage avec Oracle Restart
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'grid' (ou 'oracle')
  $ srvctl stop database -d ORCL
  
  -> Arrête proprement la base de données
  [TEMPS]  Temps : 10-30 secondes
  
  # Vérifier l'état
  $ crsctl stat res ora.orcl.db -t
  
  Name           Target  State        Server                   State details       
  --------------------------------------------------------------------------------
  ora.orcl.db
        1        OFFLINE OFFLINE                               STABLE
  
  [OK] Base arrêtée (OFFLINE)
  
  # Redémarrer la base
  $ srvctl start database -d ORCL
  
  [TEMPS]  Temps : 30-60 secondes
  
  # Vérifier
  $ crsctl stat res ora.orcl.db -t
  
  Name           Target  State        Server                   State details       
  --------------------------------------------------------------------------------
  ora.orcl.db
        1        ONLINE  ONLINE       oracledb                 Open,STABLE
  
  [OK] Base redémarrée et ouverte


═══════════════════════════════════════════════════════════════════════════════
7.7 TESTS FINAUX
═══════════════════════════════════════════════════════════════════════════════

ÉTAPE 1 : Créer un tablespace et une table de test
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'oracle'
  $ sudo su - oracle
  $ sqlplus / as sysdba
  
  SQL> -- Créer un tablespace de test
  SQL> CREATE TABLESPACE test_data
       DATAFILE '+DATA' SIZE 100M
       AUTOEXTEND ON NEXT 10M MAXSIZE 500M;
  
  Tablespace created.
  
  SQL> -- Créer un utilisateur de test
  SQL> CREATE USER testuser IDENTIFIED BY Test123#
       DEFAULT TABLESPACE test_data
       QUOTA UNLIMITED ON test_data;
  
  User created.
  
  SQL> -- Accorder les privilèges
  SQL> GRANT CONNECT, RESOURCE TO testuser;
  
  Grant succeeded.
  
  SQL> -- Se connecter en tant que testuser
  SQL> CONNECT testuser/Test123#@localhost:1521/ORCL
  
  Connected.
  
  SQL> -- Créer une table
  SQL> CREATE TABLE employees (
           id NUMBER PRIMARY KEY,
           name VARCHAR2(100),
           hire_date DATE,
           salary NUMBER(10,2)
       );
  
  Table created.
  
  SQL> -- Insérer des données
  SQL> INSERT INTO employees VALUES (1, 'Alice Dupont', SYSDATE, 50000);
  SQL> INSERT INTO employees VALUES (2, 'Bob Martin', SYSDATE-30, 55000);
  SQL> INSERT INTO employees VALUES (3, 'Claire Durand', SYSDATE-60, 60000);
  SQL> COMMIT;
  
  Commit complete.
  
  SQL> -- Interroger les données
  SQL> SELECT * FROM employees ORDER BY id;
  
          ID NAME                 HIRE_DATE    SALARY
  ---------- -------------------- --------- ----------
           1 Alice Dupont         20-DEC-24      50000
           2 Bob Martin           20-NOV-24      55000
           3 Claire Durand        21-OCT-24      60000
  
  [OK] Table créée et données insérées avec succès
  
  SQL> EXIT


ÉTAPE 2 : Vérifier que les données sont bien sur ASM
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ sqlplus / as sysdba
  
  SQL> SELECT file_name, tablespace_name, bytes/1024/1024 AS size_mb
       FROM dba_data_files
       WHERE tablespace_name = 'TEST_DATA';
  
  FILE_NAME                                        TABLESPACE_NAME    SIZE_MB
  ------------------------------------------------ --------------- ----------
  +DATA/ORCL/DATAFILE/test_data.270.1234567910    TEST_DATA              100
  
  [OK] Le datafile du tablespace TEST_DATA est sur +DATA
  
  SQL> EXIT


┌────────────────────────────────────────────────────────────────────────────┐
│                      RÉCAPITULATIF DE LA PARTIE 7                          │
└────────────────────────────────────────────────────────────────────────────┘

[OK] Oracle Database 19c téléchargé et binaires installés
   Software only, ORACLE_HOME = /u01/app/oracle/product/19.3.0/dbhome_1

[OK] Listener configuré et opérationnel
   Géré par Grid Infrastructure, écoute sur le port 1521

[OK] Base de données ORCL créée avec succès
   Utilise DBCA en mode silencieux, stockage sur ASM

[OK] Intégration ASM vérifiée
   - Datafiles sur +DATA
   - Control files sur +DATA et +FRA (redondance)
   - Redo logs sur +DATA et +FRA (miroirs)
   - Fast Recovery Area configurée

[OK] Oracle Restart configuré
   Démarrage automatique de la base au boot

[OK] Tests fonctionnels réussis
   - Création de tablespace sur ASM
   - Création d'utilisateur et de table
   - Insertion et interrogation de données

[TEMPS]  Temps total de la partie 7 : 90-120 minutes

PROCHAINE ÉTAPE : Administration quotidienne
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Dans la partie 8, nous allons :
1. Comprendre la séparation des tâches entre 'grid' et 'oracle'
2. Effectuer les opérations d'administration courantes
3. Surveiller l'état du système (ASM, databases, disk groups)
4. Gérer les sauvegardes avec RMAN
5. Résoudre les problèmes courants


################################################################################
#                                                                              #
#  PARTIE 8 : ADMINISTRATION QUOTIDIENNE                                      #
#                                                                              #
################################################################################

Dans cette partie, nous allons :
1. Comprendre la séparation des responsabilités entre 'grid' et 'oracle'
2. Effectuer les tâches courantes de l'utilisateur 'grid' (ASM)
3. Effectuer les tâches courantes de l'utilisateur 'oracle' (Database)
4. Surveiller l'état du système (monitoring)
5. Gérer les sauvegardes avec RMAN
6. Résoudre les problèmes courants (troubleshooting)

[TEMPS]  Durée estimée : 60-90 minutes

═══════════════════════════════════════════════════════════════════════════════
8.1 SÉPARATION DES RESPONSABILITÉS : grid VS oracle
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│                    QUI FAIT QUOI ? TABLEAU RÉCAPITULATIF                   │
└────────────────────────────────────────────────────────────────────────────┘

┌──────────────────────────────┬─────────────────┬─────────────────┐
│   Tâche                      │  Utilisateur    │  Commande type  │
├──────────────────────────────┼─────────────────┼─────────────────┤
│ INFRASTRUCTURE (STOCKAGE)                                         │
├──────────────────────────────┼─────────────────┼─────────────────┤
│ Démarrer/arrêter ASM         │ grid            │ srvctl start asm│
│ Créer un disk group          │ grid            │ CREATE DISKGROUP│
│ Ajouter un disque            │ grid            │ ALTER DISKGROUP │
│ Retirer un disque            │ grid            │ ALTER DISKGROUP │
│ Monter/démonter disk group   │ grid            │ ALTER DISKGROUP │
│ Naviguer dans ASM            │ grid            │ asmcmd          │
│ Sauvegarder métadonnées ASM  │ grid            │ md_backup       │
│ Surveiller l'état d'ASM      │ grid            │ crsctl stat res │
│ Gérer Oracle Restart         │ grid            │ crsctl/srvctl   │
│ Gérer le listener            │ grid            │ lsnrctl         │
├──────────────────────────────┼─────────────────┼─────────────────┤
│ APPLICATIONS (DATABASES)                                          │
├──────────────────────────────┼─────────────────┼─────────────────┤
│ Démarrer/arrêter une DB      │ oracle          │ srvctl start db │
│ Créer une base de données    │ oracle          │ dbca            │
│ Créer un tablespace          │ oracle          │ CREATE TBSP     │
│ Créer un utilisateur         │ oracle          │ CREATE USER     │
│ Sauvegarder la base (RMAN)   │ oracle          │ rman            │
│ Restaurer la base            │ oracle          │ rman            │
│ Exporter des données         │ oracle          │ expdp           │
│ Importer des données         │ oracle          │ impdp           │
│ Optimiser les requêtes       │ oracle          │ SQL tuning      │
│ Surveiller les sessions      │ oracle          │ v$session       │
│ Analyser les logs DB         │ oracle          │ alert log       │
├──────────────────────────────┼─────────────────┼─────────────────┤
│ COLLABORATION (LES DEUX)                                          │
├──────────────────────────────┼─────────────────┼─────────────────┤
│ Vérifier l'espace disque     │ grid ET oracle  │ lsdg / v$views  │
│ Consulter les fichiers ASM   │ grid (lecture)  │ asmcmd ls       │
│                              │ oracle (usage)  │ v$datafile      │
│ Diagnostiquer un problème    │ grid ET oracle  │ Logs + vues     │
└──────────────────────────────┴─────────────────┴─────────────────┘


PRINCIPE FONDAMENTAL :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

'grid' gère l'INFRASTRUCTURE (disques, ASM, cluster)
-> Comme un gestionnaire d'immeuble : il gère les locaux, l'électricité, l'eau
-> Il ne s'occupe PAS de ce que font les locataires

'oracle' gère les APPLICATIONS (bases de données, données)
-> Comme un locataire : il utilise les locaux fournis
-> Il stocke ses données dans les espaces alloués
-> Il ne peut PAS modifier l'infrastructure directement


═══════════════════════════════════════════════════════════════════════════════
8.2 TÂCHES COURANTES DE L'UTILISATEUR 'grid'
═══════════════════════════════════════════════════════════════════════════════

TÂCHE 1 : Vérifier l'état global du système
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'grid'
  $ sudo su - grid
  
  # Vérifier l'état d'Oracle Restart (Grid Infrastructure)
  $ crsctl check crs
  
  CRS-4638: Oracle High Availability Services is online
  CRS-4537: Cluster Ready Services is online
  CRS-4529: Cluster Synchronization Services is online
  CRS-4533: Event Manager is online
  
  [OK] Tous les composants sont "online"
  
  # Vue d'ensemble de toutes les ressources
  $ crsctl stat res -t
  
  -> Affiche l'état de : ASM, disk groups, listener, databases
  -> À exécuter CHAQUE JOUR pour vérifier que tout fonctionne


TÂCHE 2 : Surveiller l'état de l'instance ASM
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Vérifier si ASM est démarré
  $ ps -ef | grep asm_pmon
  
  grid     12345     1  0 Dec20 ?        00:00:15 asm_pmon_+ASM
  
  [OK] Processus asm_pmon_+ASM présent -> ASM est démarré
  
  # Se connecter à ASM
  $ sqlplus / as sysasm
  
  SQL> SELECT instance_name, status FROM v$instance;
  
  INSTANCE_NAME    STATUS
  ---------------- ------------
  +ASM             STARTED
  
  [OK] STATUS = STARTED (normal pour ASM, pas OPEN comme une DB)
  
  SQL> EXIT
  
  # Vérifier l'état avec srvctl
  $ srvctl status asm
  
  ASM is running on oracledb
  
  [OK] ASM fonctionne correctement


TÂCHE 3 : Surveiller l'espace dans les disk groups
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Méthode 1 : Avec ASMCMD
  $ asmcmd lsdg
  
  State    Type    Rebal  Sector  Block       AU  Total_MB  Free_MB  Req_mir_free_MB  Usable_file_MB  Offline_disks  Name
  MOUNTED  NORMAL  N         512   4096  4194304     61440    58200            20480           18860              0  DATA/
  MOUNTED  NORMAL  N         512   4096  4194304     40960    40600            20480           10060              0  FRA/
  
  Points à surveiller :
  
  Usable_file_MB
  -> Espace réellement disponible pour créer des fichiers
  -> DATA : 18860 MB (~18 GB)
  -> FRA : 10060 MB (~10 GB)
  
  Offline_disks
  -> Nombre de disques hors ligne
  -> Si > 0 : PROBLÈME, un disque est défaillant
  
  Rebal
  -> Rééquilibrage en cours ?
  -> N = non (normal)
  -> Y = oui (opération en cours)
  
  # Méthode 2 : Avec SQL
  $ sqlplus / as sysasm
  
  SQL> SELECT name, 
              total_mb, 
              free_mb,
              usable_file_mb,
              ROUND((total_mb - free_mb) / total_mb * 100, 2) AS pct_used
       FROM v$asm_diskgroup;
  
  NAME  TOTAL_MB  FREE_MB  USABLE_FILE_MB  PCT_USED
  ----- --------- -------- --------------- ---------
  DATA      61440    58200           18860      5.28
  FRA       40960    40600           10060      0.98
  
  [ATTENTION]  ALERTE si PCT_USED > 80% : Ajouter des disques ou nettoyer
  
  SQL> EXIT


TÂCHE 4 : Vérifier l'état des disques
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ sqlplus / as sysasm
  
  SQL> SELECT name, path, header_status, mode_status, state
       FROM v$asm_disk
       ORDER BY name;
  
  NAME       PATH                     HEADER_STATUS  MODE_STATUS  STATE
  ---------- ----------------------- -------------- ------------ -------
  DATA_0000  /dev/oracleasm/disk1    MEMBER         ONLINE       NORMAL
  DATA_0001  /dev/oracleasm/disk2    MEMBER         ONLINE       NORMAL
  DATA_0002  /dev/oracleasm/disk3    MEMBER         ONLINE       NORMAL
  FRA_0000   /dev/oracleasm/disk4    MEMBER         ONLINE       NORMAL
  FRA_0001   /dev/oracleasm/disk5    MEMBER         ONLINE       NORMAL
  
  Points à surveiller :
  
  MODE_STATUS = ONLINE
  -> [OK] Disque accessible
  -> [ATTENTION]  OFFLINE = disque inaccessible, problème matériel
  
  STATE = NORMAL
  -> [OK] Disque en état normal
  -> [ATTENTION]  SYNCING = resynchronisation en cours (après panne)
  -> [ATTENTION]  DROPPING = disque en cours de retrait
  
  HEADER_STATUS = MEMBER
  -> [OK] Disque actif dans le disk group
  -> CANDIDATE = disque disponible mais pas encore utilisé
  -> FORMER = ancien membre (peut être retiré physiquement)
  
  SQL> EXIT


TÂCHE 5 : Gérer le listener
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Vérifier l'état du listener
  $ lsnrctl status
  
  -> Affiche les services enregistrés, le port d'écoute, etc.
  
  # Arrêter le listener (avec Oracle Restart)
  $ srvctl stop listener
  
  # Démarrer le listener
  $ srvctl start listener
  
  # Recharger la configuration (sans interruption de service)
  $ lsnrctl reload
  
  # Voir les connexions actives
  $ lsnrctl services


TÂCHE 6 : Consulter les logs ASM
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Alert log ASM
  $ tail -50 /u01/app/grid/diag/asm/+asm/+ASM/trace/alert_+ASM.log
  
  -> Affiche les dernières lignes du alert log
  -> Chercher les erreurs ORA- ou les messages WARNING
  
  # Suivre le log en temps réel
  $ tail -f /u01/app/grid/diag/asm/+asm/+ASM/trace/alert_+ASM.log
  
  -> Appuie sur Ctrl+C pour arrêter
  
  # Logs Grid Infrastructure (Oracle Restart)
  $ tail -50 /u01/app/grid/diag/crs/$(hostname)/crs/trace/alert.log


TÂCHE 7 : Sauvegarder les métadonnées ASM (hebdomadaire)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ asmcmd
  
  ASMCMD> md_backup /u01/stage/grid/asm_metadata_$(date +%Y%m%d).txt
  
  Copying metadata for diskgroup DATA to /u01/stage/grid/asm_metadata_20241220.txt
  Copying metadata for diskgroup FRA to /u01/stage/grid/asm_metadata_20241220.txt
  
  [OK] Métadonnées sauvegardées avec horodatage
  
  ASMCMD> exit
  
  # Copier la sauvegarde hors du serveur (TRÈS IMPORTANT)
  $ scp /u01/stage/grid/asm_metadata_*.txt backup-server:/backups/asm/


═══════════════════════════════════════════════════════════════════════════════
8.3 TÂCHES COURANTES DE L'UTILISATEUR 'oracle'
═══════════════════════════════════════════════════════════════════════════════

TÂCHE 1 : Vérifier l'état de la base de données
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'oracle'
  $ sudo su - oracle
  
  # Vérifier si la base est démarrée
  $ ps -ef | grep ora_pmon_ORCL
  
  oracle   23456     1  0 Dec20 ?        00:00:20 ora_pmon_ORCL
  
  [OK] Processus ora_pmon_ORCL présent -> base ORCL démarrée
  
  # Vérifier l'état avec srvctl
  $ srvctl status database -d ORCL
  
  Database is running on node oracledb
  
  [OK] Base de données en cours d'exécution
  
  # Se connecter et vérifier l'état interne
  $ sqlplus / as sysdba
  
  SQL> SELECT instance_name, status, database_status FROM v$instance;
  
  INSTANCE_NAME    STATUS       DATABASE_STATUS
  ---------------- ------------ ----------------
  ORCL             OPEN         ACTIVE
  
  STATUS = OPEN
  -> [OK] Base ouverte et prête à accepter des connexions
  
  DATABASE_STATUS = ACTIVE
  -> [OK] Base de données active
  
  SQL> SELECT name, open_mode FROM v$database;
  
  NAME      OPEN_MODE
  --------- --------------------
  ORCL      READ WRITE
  
  OPEN_MODE = READ WRITE
  -> [OK] Accepte les lectures ET les écritures
  
  SQL> EXIT


TÂCHE 2 : Surveiller l'utilisation de l'espace (tablespaces)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ sqlplus / as sysdba
  
  SQL> -- Vue d'ensemble de tous les tablespaces
  SQL> SELECT tablespace_name,
              ROUND(SUM(bytes)/1024/1024, 2) AS size_mb,
              ROUND(SUM(CASE WHEN maxbytes = 0 
                        THEN bytes 
                        ELSE maxbytes END)/1024/1024, 2) AS max_size_mb,
              COUNT(*) AS files
       FROM dba_data_files
       GROUP BY tablespace_name
       ORDER BY tablespace_name;
  
  TABLESPACE_NAME   SIZE_MB  MAX_SIZE_MB  FILES
  --------------- --------- ------------ ------
  SYSAUX             580.00     32767.98      1
  SYSTEM             890.00     32767.98      1
  TEST_DATA          100.00       500.00      1
  UNDOTBS1           105.00     32767.98      1
  USERS                5.00     32767.98      1
  
  # Vérifier l'espace libre dans chaque tablespace
  SQL> SELECT tablespace_name,
              ROUND(SUM(bytes)/1024/1024, 2) AS free_mb
       FROM dba_free_space
       GROUP BY tablespace_name
       ORDER BY tablespace_name;
  
  TABLESPACE_NAME     FREE_MB
  --------------- -----------
  SYSAUX               153.56
  SYSTEM               122.44
  TEST_DATA             99.00
  UNDOTBS1              97.81
  USERS                  3.94
  
  # Calculer le pourcentage d'utilisation
  SQL> SELECT df.tablespace_name,
              ROUND(df.total_mb, 2) AS total_mb,
              ROUND(df.total_mb - NVL(fs.free_mb, 0), 2) AS used_mb,
              ROUND(NVL(fs.free_mb, 0), 2) AS free_mb,
              ROUND((df.total_mb - NVL(fs.free_mb, 0)) / df.total_mb * 100, 2) AS pct_used
       FROM (SELECT tablespace_name, SUM(bytes)/1024/1024 AS total_mb
             FROM dba_data_files
             GROUP BY tablespace_name) df
       LEFT JOIN (SELECT tablespace_name, SUM(bytes)/1024/1024 AS free_mb
                  FROM dba_free_space
                  GROUP BY tablespace_name) fs
       ON df.tablespace_name = fs.tablespace_name
       ORDER BY pct_used DESC;
  
  TABLESPACE_NAME   TOTAL_MB   USED_MB   FREE_MB  PCT_USED
  --------------- ---------- --------- --------- ---------
  SYSTEM              890.00    767.56    122.44     86.24
  SYSAUX              580.00    426.44    153.56     73.52
  UNDOTBS1            105.00      7.19     97.81      6.85
  TEST_DATA           100.00      1.00     99.00      1.00
  USERS                 5.00      1.06      3.94     21.20
  
  [ATTENTION]  ALERTE si PCT_USED > 85% : Étendre le tablespace ou nettoyer
  
  SQL> EXIT


TÂCHE 3 : Surveiller les sessions utilisateurs
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ sqlplus / as sysdba
  
  SQL> -- Nombre de sessions par type
  SQL> SELECT status, COUNT(*) AS nb_sessions
       FROM v$session
       GROUP BY status;
  
  STATUS       NB_SESSIONS
  ------------ ------------
  ACTIVE                  3
  INACTIVE               12
  
  SQL> -- Détail des sessions actives
  SQL> SELECT sid, serial#, username, program, status, 
              logon_time, last_call_et
       FROM v$session
       WHERE username IS NOT NULL
       ORDER BY last_call_et DESC;
  
  SID  SERIAL#  USERNAME   PROGRAM          STATUS   LOGON_TIME       LAST_CALL_ET
  ---- -------- ---------- ---------------- -------- --------------- -------------
   125      789 TESTUSER   sqlplus@client1  ACTIVE   20-DEC-24 10:00           120
   126      790 HR         app.jar          INACTIVE 20-DEC-24 09:30          1800
  
  LAST_CALL_ET
  -> Temps (en secondes) depuis la dernière activité
  -> Si très élevé (ex: > 3600) et INACTIVE -> session zombie à tuer ?
  
  SQL> EXIT


TÂCHE 4 : Consulter le alert log de la base
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Localiser le alert log
  $ find /u01/app/oracle/diag -name "alert_*.log" -type f
  
  /u01/app/oracle/diag/rdbms/orcl/ORCL/trace/alert_ORCL.log
  
  # Afficher les dernières lignes
  $ tail -50 /u01/app/oracle/diag/rdbms/orcl/ORCL/trace/alert_ORCL.log
  
  # Suivre en temps réel
  $ tail -f /u01/app/oracle/diag/rdbms/orcl/ORCL/trace/alert_ORCL.log
  
  # Chercher les erreurs récentes (dernières 24h)
  $ find /u01/app/oracle/diag/rdbms/orcl/ORCL/trace -name "*.trc" -mtime -1
  
  -> Liste les fichiers de trace créés dans les dernières 24 heures


TÂCHE 5 : Gérer les archived logs
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ sqlplus / as sysdba
  
  SQL> -- Vérifier que l'archivage est actif
  SQL> SELECT log_mode FROM v$database;
  
  LOG_MODE
  ------------
  ARCHIVELOG
  
  [OK] ARCHIVELOG = archivage activé (bon pour la récupération)
  
  SQL> -- Lister les archived logs
  SQL> SELECT name, sequence#, first_time, blocks * block_size / 1024 / 1024 AS size_mb
       FROM v$archived_log
       WHERE deleted = 'NO'
       ORDER BY sequence# DESC
       FETCH FIRST 10 ROWS ONLY;
  
  NAME                                           SEQUENCE#  FIRST_TIME         SIZE_MB
  ---------------------------------------------- ---------- ------------------ --------
  +FRA/ORCL/ARCHIVELOG/2024_12_20/thread_1_seq_156  156   20-DEC-24 14:23:12   52.5
  +FRA/ORCL/ARCHIVELOG/2024_12_20/thread_1_seq_155  155   20-DEC-24 13:45:30   52.5
  [...]
  
  -> Les archived logs sont sur +FRA (Fast Recovery Area)
  
  SQL> -- Vérifier l'utilisation de la FRA
  SQL> SELECT * FROM v$recovery_area_usage;
  
  FILE_TYPE            PERCENT_SPACE_USED  PERCENT_SPACE_RECLAIMABLE
  -------------------- ------------------- -------------------------
  CONTROL FILE                        0.00                      0.00
  REDO LOG                            0.15                      0.00
  ARCHIVED LOG                        2.34                      0.00
  BACKUP PIECE                        0.00                      0.00
  IMAGE COPY                          0.00                      0.00
  
  [ATTENTION]  ALERTE si PERCENT_SPACE_USED > 80% : Sauvegarder et nettoyer
  
  SQL> EXIT


═══════════════════════════════════════════════════════════════════════════════
8.4 SURVEILLANCE ET MONITORING (COLLABORATION grid + oracle)
═══════════════════════════════════════════════════════════════════════════════

SCÉNARIO 1 : Vérifier l'intégration ASM <-> Database
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'grid'
  $ sudo su - grid
  $ sqlplus / as sysasm
  
  SQL> -- Voir quels clients (databases) utilisent ASM
  SQL> SELECT instance_name, db_name, status
       FROM v$asm_client;
  
  INSTANCE_NAME    DB_NAME      STATUS
  ---------------- ------------ ----------
  ORCL             ORCL         CONNECTED
  
  [OK] La base ORCL est connectée à ASM
  
  SQL> -- Voir les fichiers de la base ORCL dans ASM
  SQL> SELECT name, type, bytes/1024/1024 AS size_mb
       FROM v$asm_file
       WHERE group_number IN (SELECT group_number 
                              FROM v$asm_diskgroup 
                              WHERE name IN ('DATA', 'FRA'))
       ORDER BY type, name;
  
  -> Affiche tous les fichiers de toutes les bases sur DATA et FRA
  
  SQL> EXIT
  
  # En tant que 'oracle'
  $ sudo su - oracle
  $ sqlplus / as sysdba
  
  SQL> -- Vérifier que tous les fichiers sont sur ASM
  SQL> SELECT DISTINCT SUBSTR(name, 1, 6) AS storage_type
       FROM v$datafile
       UNION
       SELECT DISTINCT SUBSTR(name, 1, 6)
       FROM v$controlfile
       UNION
       SELECT DISTINCT SUBSTR(member, 1, 6)
       FROM v$logfile
       UNION
       SELECT DISTINCT SUBSTR(name, 1, 6)
       FROM v$tempfile;
  
  STORAGE_TYPE
  ------------
  +DATA
  +FRA
  
  [OK] Tous les fichiers sont sur les disk groups ASM (pas de filesystem)
  
  SQL> EXIT


SCÉNARIO 2 : Dashboard complet de l'état du système
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Créons un script de monitoring quotidien.
  
  # En tant que 'oracle'
  $ cat > /home/oracle/daily_check.sh << 'EOF'
#!/bin/bash
################################################################################
# Script de vérification quotidienne
# À exécuter chaque matin pour vérifier l'état du système
################################################################################

echo "=========================================="
echo "DAILY HEALTH CHECK - $(date)"
echo "=========================================="
echo ""

# 1. État d'Oracle Restart (en tant que grid)
echo "1. Oracle Restart Status:"
sudo su - grid -c "crsctl check crs"
echo ""

# 2. État des disk groups ASM
echo "2. ASM Disk Groups Space:"
sudo su - grid -c "asmcmd lsdg" | awk 'NR==1 || /DATA|FRA/'
echo ""

# 3. État de la base de données
echo "3. Database Status:"
ps -ef | grep ora_pmon_ORCL | grep -v grep > /dev/null
if [ $? -eq 0 ]; then
    echo "   Database ORCL: RUNNING"
else
    echo "   Database ORCL: DOWN"
fi
echo ""

# 4. Utilisation des tablespaces
echo "4. Tablespace Usage (top 5):"
sqlplus -s / as sysdba << SQL
SET PAGESIZE 100
SET LINESIZE 150
COLUMN tablespace_name FORMAT A20
COLUMN total_mb FORMAT 999999.99
COLUMN used_mb FORMAT 999999.99
COLUMN free_mb FORMAT 999999.99
COLUMN pct_used FORMAT 999.99

SELECT * FROM (
    SELECT df.tablespace_name,
           ROUND(df.total_mb, 2) AS total_mb,
           ROUND(df.total_mb - NVL(fs.free_mb, 0), 2) AS used_mb,
           ROUND(NVL(fs.free_mb, 0), 2) AS free_mb,
           ROUND((df.total_mb - NVL(fs.free_mb, 0)) / df.total_mb * 100, 2) AS pct_used
    FROM (SELECT tablespace_name, SUM(bytes)/1024/1024 AS total_mb
          FROM dba_data_files
          GROUP BY tablespace_name) df
    LEFT JOIN (SELECT tablespace_name, SUM(bytes)/1024/1024 AS free_mb
               FROM dba_free_space
               GROUP BY tablespace_name) fs
    ON df.tablespace_name = fs.tablespace_name
    ORDER BY pct_used DESC
)
WHERE ROWNUM <= 5;
EXIT;
SQL
echo ""

# 5. Nombre de sessions
echo "5. Active Sessions:"
sqlplus -s / as sysdba << SQL
SET PAGESIZE 0
SELECT 'Total sessions: ' || COUNT(*) FROM v$session;
SELECT 'Active sessions: ' || COUNT(*) FROM v$session WHERE status = 'ACTIVE';
EXIT;
SQL
echo ""

# 6. Erreurs récentes dans l'alert log (dernières 24h)
echo "6. Recent Errors in Alert Log (last 24h):"
ALERT_LOG=$(find /u01/app/oracle/diag -name "alert_ORCL.log" -type f)
if [ -f "$ALERT_LOG" ]; then
    grep -i "ORA-\|ERROR\|WARNING" "$ALERT_LOG" | tail -10
    if [ $? -ne 0 ]; then
        echo "   No errors found (good!)"
    fi
else
    echo "   Alert log not found"
fi
echo ""

echo "=========================================="
echo "END OF HEALTH CHECK"
echo "=========================================="
EOF

  # Rendre le script exécutable
  $ chmod +x /home/oracle/daily_check.sh
  
  # Exécuter le script
  $ /home/oracle/daily_check.sh
  
  -> Ce script donne un aperçu complet de l'état du système
  -> À exécuter CHAQUE JOUR, idéalement automatisé via cron


═══════════════════════════════════════════════════════════════════════════════
8.5 GESTION DES SAUVEGARDES AVEC RMAN
═══════════════════════════════════════════════════════════════════════════════

RMAN = Recovery Manager
-> Outil Oracle pour sauvegarder et restaurer les bases de données
-> Supporte les sauvegardes incrémentielles, la compression, etc.
-> Stocke les backups dans la FRA (+FRA)

TÂCHE 1 : Configurer RMAN
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'oracle'
  $ rman target /
  
  Recovery Manager: Release 19.0.0.0.0 - Production on Fri Dec 20 20:00:00 2024
  Version 19.3.0.0.0
  
  Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.
  
  connected to target database: ORCL (DBID=123456789)
  
  RMAN> 
  
  # Configurer la rétention des backups (7 jours)
  RMAN> CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 7 DAYS;
  
  new RMAN configuration parameters:
  CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 7 DAYS;
  new RMAN configuration parameters are successfully stored
  
  # Activer la compression des backups
  RMAN> CONFIGURE COMPRESSION ALGORITHM 'BASIC';
  
  # Configurer le parallélisme (nombre de canaux)
  RMAN> CONFIGURE DEVICE TYPE DISK PARALLELISM 2;
  
  # Activer l'autobackup du control file
  RMAN> CONFIGURE CONTROLFILE AUTOBACKUP ON;
  
  # Voir la configuration actuelle
  RMAN> SHOW ALL;
  
  RMAN configuration parameters for database with db_unique_name ORCL are:
  CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 7 DAYS;
  CONFIGURE BACKUP OPTIMIZATION OFF;
  CONFIGURE DEFAULT DEVICE TYPE TO DISK;
  CONFIGURE CONTROLFILE AUTOBACKUP ON;
  CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO '%F';
  CONFIGURE DEVICE TYPE DISK PARALLELISM 2 BACKUP TYPE TO BACKUPSET;
  CONFIGURE DATAFILE BACKUP COPIES FOR DEVICE TYPE DISK TO 1;
  CONFIGURE ARCHIVELOG BACKUP COPIES FOR DEVICE TYPE DISK TO 1;
  CONFIGURE MAXSETSIZE TO UNLIMITED;
  CONFIGURE ENCRYPTION FOR DATABASE OFF;
  CONFIGURE ENCRYPTION ALGORITHM 'AES128';
  CONFIGURE COMPRESSION ALGORITHM 'BASIC' AS OF RELEASE 'DEFAULT' OPTIMIZE FOR LOAD TRUE;
  CONFIGURE RMAN OUTPUT TO KEEP FOR 7 DAYS;
  CONFIGURE ARCHIVELOG DELETION POLICY TO NONE;
  CONFIGURE SNAPSHOT CONTROLFILE NAME TO '/u01/app/oracle/product/19.3.0/dbhome_1/dbs/snapcf_ORCL.f';


TÂCHE 2 : Effectuer une sauvegarde complète (FULL BACKUP)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  RMAN> BACKUP DATABASE PLUS ARCHIVELOG;
  
  Starting backup at 20-DEC-24
  current log archived
  using channel ORA_DISK_1
  using channel ORA_DISK_2
  
  channel ORA_DISK_1: starting archived log backup set
  channel ORA_DISK_1: specifying archived log(s) in backup set
  input archived log thread=1 sequence=155 RECID=1 STAMP=1234567890
  input archived log thread=1 sequence=156 RECID=2 STAMP=1234567891
  channel ORA_DISK_1: starting piece 1 at 20-DEC-24
  channel ORA_DISK_2: starting archived log backup set
  [...]
  
  channel ORA_DISK_1: starting full datafile backup set
  channel ORA_DISK_1: specifying datafile(s) in backup set
  input datafile file number=00001 name=+DATA/ORCL/DATAFILE/system.256.1234567890
  input datafile file number=00003 name=+DATA/ORCL/DATAFILE/sysaux.257.1234567891
  channel ORA_DISK_1: starting piece 1 at 20-DEC-24
  [...]
  
  Finished backup at 20-DEC-24
  
  Starting Control File and SPFILE Autobackup at 20-DEC-24
  piece handle=+FRA/ORCL/AUTOBACKUP/2024_12_20/s_123456.289.1234567999 comment=NONE
  Finished Control File and SPFILE Autobackup at 20-DEC-24
  
  [OK] Sauvegarde complète réussie
  
  [TEMPS]  Temps : 5-15 minutes (selon la taille de la base)


TÂCHE 3 : Effectuer une sauvegarde incrémentielle
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Sauvegarde incrémentielle niveau 0 (équivalent à FULL, mais peut être base pour incrémentielles)
  RMAN> BACKUP INCREMENTAL LEVEL 0 DATABASE;
  
  # Sauvegarde incrémentielle niveau 1 (seulement les blocs modifiés depuis niveau 0)
  RMAN> BACKUP INCREMENTAL LEVEL 1 DATABASE;
  
  -> Les backups niveau 1 sont BEAUCOUP plus rapides que les FULL


TÂCHE 4 : Lister les sauvegardes existantes
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  RMAN> LIST BACKUP SUMMARY;
  
  List of Backups
  ===============
  Key     TY LV S Device Type Completion Time #Pieces #Copies Compressed Tag
  ------- -- -- - ----------- --------------- ------- ------- ---------- ---
  1       B  F  A DISK        20-DEC-24       1       1       YES        TAG20241220T200000
  2       B  F  A DISK        20-DEC-24       1       1       YES        TAG20241220T200000
  3       B  F  A DISK        20-DEC-24       1       1       YES        TAG20241220T200000
  
  # Détails d'une sauvegarde spécifique
  RMAN> LIST BACKUP BY FILE;
  
  -> Affiche tous les fichiers sauvegardés


TÂCHE 5 : Valider les sauvegardes
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Valider que tous les fichiers peuvent être restaurés
  RMAN> VALIDATE DATABASE;
  
  Starting validate at 20-DEC-24
  using channel ORA_DISK_1
  using channel ORA_DISK_2
  channel ORA_DISK_1: starting validation of datafile
  channel ORA_DISK_1: specifying datafile(s) for validation
  input datafile file number=00001 name=+DATA/ORCL/DATAFILE/system.256.1234567890
  [...]
  channel ORA_DISK_1: validation complete, elapsed time: 00:00:15
  [...]
  Finished validate at 20-DEC-24
  
  [OK] Tous les fichiers sont validés et peuvent être restaurés


TÂCHE 6 : Nettoyer les anciennes sauvegardes (selon la politique de rétention)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  RMAN> DELETE OBSOLETE;
  
  RMAN retention policy will be applied to the command
  RMAN retention policy is set to recovery window of 7 days
  using channel ORA_DISK_1
  Deleting the following obsolete backups and copies:
  
  Type                 Key    Completion Time    Filename/Handle
  -------------------- ------ ------------------ --------------------
  Backup Set           15     17-DEC-24          +FRA/ORCL/BACKUPSET/...
  Backup Set           16     17-DEC-24          +FRA/ORCL/BACKUPSET/...
  
  Do you really want to delete the above objects (enter YES or NO)? YES
  deleted backup piece
  [...]
  Deleted 2 objects
  
  [OK] Anciennes sauvegardes supprimées


TÂCHE 7 : Créer un script de sauvegarde automatique
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'oracle'
  $ cat > /home/oracle/backup_database.sh << 'EOF'
#!/bin/bash
################################################################################
# Script de sauvegarde automatique avec RMAN
# À exécuter quotidiennement via cron
################################################################################

export ORACLE_SID=ORCL
export ORACLE_HOME=/u01/app/oracle/product/19.3.0/dbhome_1
export PATH=$ORACLE_HOME/bin:$PATH

LOG_FILE=/home/oracle/logs/backup_$(date +%Y%m%d_%H%M%S).log

echo "Starting backup at $(date)" > $LOG_FILE

rman target / << RMANSCRIPT >> $LOG_FILE 2>&1
RUN {
    # Sauvegarde incrémentielle niveau 1 (quotidienne)
    BACKUP INCREMENTAL LEVEL 1 DATABASE;
    
    # Sauvegarder les archived logs
    BACKUP ARCHIVELOG ALL DELETE INPUT;
    
    # Nettoyer les anciennes sauvegardes
    DELETE NOPROMPT OBSOLETE;
    
    # Valider les sauvegardes
    VALIDATE DATABASE;
}
EXIT;
RMANSCRIPT

echo "Backup completed at $(date)" >> $LOG_FILE

# Envoyer un email si erreur (optionnel)
if grep -i "RMAN-\|ORA-" $LOG_FILE > /dev/null; then
    echo "Backup errors found, check log: $LOG_FILE" | mail -s "RMAN Backup Error" admin@example.com
fi
EOF

  $ chmod +x /home/oracle/backup_database.sh
  
  # Créer le répertoire des logs
  $ mkdir -p /home/oracle/logs
  
  # Ajouter au cron pour exécution quotidienne à 2h du matin
  $ crontab -e
  
  # Ajouter cette ligne :
  0 2 * * * /home/oracle/backup_database.sh


═══════════════════════════════════════════════════════════════════════════════
8.6 RÉSOLUTION DE PROBLÈMES COURANTS (TROUBLESHOOTING)
═══════════════════════════════════════════════════════════════════════════════

PROBLÈME 1 : ASM ne démarre pas
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Symptômes :
  $ srvctl start asm
  PRCR-1079 : Failed to start resource ora.asm
  
  $ crsctl stat res ora.asm -t
  ora.asm    OFFLINE  OFFLINE   oracledb  ...

Diagnostic :
  # En tant que 'grid'
  $ tail -100 /u01/app/grid/diag/asm/+asm/+ASM/trace/alert_+ASM.log
  
  Chercher les erreurs ORA-

Solutions possibles :

  a) Disques ASM non accessibles
     -> Vérifier les permissions : ls -l /dev/oracleasm/*
     -> Vérifier les liens UDEV : sudo udevadm trigger
  
  b) Paramètres mémoire insuffisants
     -> Augmenter MEMORY_TARGET dans le spfile ASM
  
  c) Fichiers de mot de passe corrompus
     -> Recréer le password file :
     $ orapwd file=$ORACLE_HOME/dbs/orapw+ASM password=... entries=10


PROBLÈME 2 : Base de données ne démarre pas
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Symptômes :
  $ srvctl start database -d ORCL
  PRCR-1079 : Failed to start resource ora.orcl.db

Diagnostic :
  # En tant que 'oracle'
  $ tail -100 /u01/app/oracle/diag/rdbms/orcl/ORCL/trace/alert_ORCL.log
  
Solutions possibles :

  a) ASM non démarré
     -> Démarrer ASM en premier (en tant que grid)
  
  b) Control files corrompus
     -> Restaurer depuis backup avec RMAN
  
  c) Paramètres init incorrects
     -> Vérifier le spfile : SHOW PARAMETER spfile
     -> Recréer le spfile si nécessaire


PROBLÈME 3 : Disk group plein
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Symptômes :
  ORA-01114: IO error writing block to file
  ORA-17505: ksfdrsz:xyz Failed to resize file to size xyz blocks

Diagnostic :
  $ asmcmd lsdg
  
  DATA : Usable_file_MB = 50 (très faible)

Solutions :
  a) Ajouter un disque au disk group (en tant que grid)
  b) Nettoyer les anciennes sauvegardes (en tant que oracle)
  c) Compresser les tablespaces (en tant que oracle)


┌────────────────────────────────────────────────────────────────────────────┐
│                      RÉCAPITULATIF DE LA PARTIE 8                          │
└────────────────────────────────────────────────────────────────────────────┘

[OK] Séparation des responsabilités claire
   'grid' : infrastructure (ASM, disques, listener)
   'oracle' : applications (bases de données, données)

[OK] Tâches quotidiennes de 'grid' maîtrisées
   - Vérifier ASM, disk groups, disques
   - Gérer le listener
   - Consulter les logs
   - Sauvegarder les métadonnées ASM

[OK] Tâches quotidiennes de 'oracle' maîtrisées
   - Vérifier la base de données
   - Surveiller tablespaces et sessions
   - Consulter l'alert log
   - Gérer les archived logs

[OK] Scripts de monitoring créés
   - daily_check.sh pour vérification quotidienne
   - backup_database.sh pour sauvegardes automatiques

[OK] RMAN configuré et testé
   - Sauvegardes complètes et incrémentielles
   - Validation des backups
   - Nettoyage automatique

[OK] Troubleshooting de base
   - Diagnostic des problèmes courants
   - Solutions pratiques

[TEMPS]  Temps total de la partie 8 : 60-90 minutes

PROCHAINE ÉTAPE : Scénarios pratiques et exemples
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Dans la partie 9, nous allons :
1. Scénario complet : Ajout d'un disque à un disk group
2. Scénario complet : Migration d'une base filesystem vers ASM
3. Scénario complet : Restauration après perte de données
4. Scénario complet : Upgrade de Grid Infrastructure
5. Exercices pratiques pour consolider les connaissances

################################################################################
#                                                                              #
#  PARTIE 9 : SCÉNARIOS PRATIQUES ET EXEMPLES                                 #
#                                                                              #
################################################################################

Dans cette partie, nous allons :
1. Scénario 1 : Ajout d'un disque à un disk group existant
2. Scénario 2 : Migration d'une base filesystem vers ASM
3. Scénario 3 : Restauration complète après perte de données
4. Scénario 4 : Simulation et récupération d'une panne de disque
5. Scénario 5 : Upgrade de Grid Infrastructure 19c vers une version ultérieure
6. Exercices pratiques pour consolider les connaissances

[TEMPS]  Durée estimée : 120-180 minutes

═══════════════════════════════════════════════════════════════════════════════
9.1 SCÉNARIO 1 : AJOUT D'UN DISQUE À UN DISK GROUP EXISTANT
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│                         CONTEXTE DU SCÉNARIO                               │
└────────────────────────────────────────────────────────────────────────────┘

SITUATION :
  Le disk group DATA est presque plein (80% utilisé)
  Tu dois ajouter un nouveau disque de 20 GB pour augmenter la capacité

OBJECTIFS :
  1. Préparer le nouveau disque physique
  2. L'ajouter au disk group DATA
  3. Vérifier le rééquilibrage automatique
  4. Confirmer l'augmentation de capacité


ÉTAPE 1 : État initial du disk group DATA
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'grid'
  $ sudo su - grid
  $ sqlplus / as sysasm
  
  SQL> SELECT name, total_mb, free_mb, usable_file_mb,
              ROUND((total_mb - free_mb) / total_mb * 100, 2) AS pct_used
       FROM v$asm_diskgroup
       WHERE name = 'DATA';
  
  NAME  TOTAL_MB  FREE_MB  USABLE_FILE_MB  PCT_USED
  ----- --------- -------- --------------- ---------
  DATA      61440    12288            6144     80.00
  
  [ATTENTION]  80% utilisé -> il est temps d'ajouter de la capacité
  
  SQL> SELECT name, total_mb, free_mb
       FROM v$asm_disk
       WHERE group_number = (SELECT group_number 
                             FROM v$asm_diskgroup 
                             WHERE name = 'DATA')
       ORDER BY name;
  
  NAME       TOTAL_MB  FREE_MB
  ---------- --------- --------
  DATA_0000     20480     4096
  DATA_0001     20480     4096
  DATA_0002     20480     4096
  
  -> 3 disques de 20 GB chacun
  
  SQL> EXIT


ÉTAPE 2 : Préparer le nouveau disque (en tant que root)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que root
  $ sudo su -
  
  # Créer un nouveau fichier disque (si VM ou test)
  # dd if=/dev/zero of=/u01/asmdisks/disk6.img bs=1M count=20480
  # losetup /dev/loop6 /u01/asmdisks/disk6.img
  
  # OU si tu as un vrai disque physique :
  # Identifie le device : lsblk
  # Exemple : /dev/sdf (nouveau disque de 20 GB)
  
  # Nettoyer les métadonnées existantes
  # dd if=/dev/zero of=/dev/sdf bs=1M count=100
  
  # Ajouter la règle UDEV pour le nouveau disque
  # vi /etc/udev/rules.d/99-oracle-asmdevices.rules
  
  # Ajouter cette ligne (ajuster selon ton environnement) :
  KERNEL=="sdf", OWNER="grid", GROUP="asmadmin", MODE="0660", SYMLINK+="oracleasm/disk6"
  
  # Recharger les règles UDEV
  # udevadm control --reload-rules
  # udevadm trigger
  
  # Vérifier le nouveau lien symbolique
  # ls -l /dev/oracleasm/disk6
  lrwxrwxrwx 1 root root 4 Dec 20 21:00 /dev/oracleasm/disk6 -> ../sdf
  
  # Vérifier les permissions
  # ls -l /dev/sdf
  brw-rw---- 1 grid asmadmin 8, 80 Dec 20 21:00 /dev/sdf
  
  [OK] Nouveau disque prêt avec les bonnes permissions
  
  # exit


ÉTAPE 3 : Vérifier que ASM voit le nouveau disque comme CANDIDATE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'grid'
  $ sudo su - grid
  $ sqlplus / as sysasm
  
  SQL> SELECT path, header_status, total_mb
       FROM v$asm_disk
       WHERE header_status = 'CANDIDATE'
       ORDER BY path;
  
  PATH                       HEADER_STATUS  TOTAL_MB
  -------------------------- -------------- ---------
  /dev/oracleasm/disk6       CANDIDATE          20480
  
  [OK] Le disque est visible comme CANDIDATE (prêt à être ajouté)
  
  SQL> EXIT


ÉTAPE 4 : Ajouter le disque au disk group DATA
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ sqlplus / as sysasm
  
  SQL> -- Ajouter le disque
  SQL> ALTER DISKGROUP DATA ADD DISK '/dev/oracleasm/disk6' SIZE 20G;
  
  Diskgroup altered.
  
  -> La commande retourne immédiatement
  -> Le RÉÉQUILIBRAGE démarre automatiquement en arrière-plan
  
  [TEMPS]  Temps de rééquilibrage : 5-30 minutes (selon la quantité de données)


ÉTAPE 5 : Surveiller le rééquilibrage en temps réel
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  SQL> -- Vérifier qu'un rééquilibrage est en cours
  SQL> SELECT group_number, operation, state, power, sofar, est_work, est_minutes
       FROM v$asm_operation;
  
  GROUP_NUMBER  OPERATION  STATE   POWER  SOFAR  EST_WORK  EST_MINUTES
  ------------- ---------- ------- ------ ------ --------- ------------
             1  REBAL      RUN          4  15360     49152           12
  
  Explication des colonnes :
  
  OPERATION = REBAL
  -> Opération de rééquilibrage
  
  STATE = RUN
  -> En cours d'exécution
  
  POWER = 4
  -> Niveau de parallélisme (1-11)
  -> Plus élevé = plus rapide mais plus de ressources
  
  SOFAR
  -> Nombre de MB déjà traités (15360 MB = 15 GB)
  
  EST_WORK
  -> Travail total estimé en MB (49152 MB = 48 GB)
  
  EST_MINUTES
  -> Temps restant estimé (12 minutes)
  
  # Pour suivre la progression en temps réel
  SQL> SET PAGESIZE 100
  SQL> SELECT operation, state, 
              ROUND(sofar/est_work*100, 2) AS pct_complete,
              est_minutes
       FROM v$asm_operation
       WHERE operation = 'REBAL';
  
  -> Exécute cette requête toutes les 30 secondes pour voir la progression
  
  # Quand le rééquilibrage est terminé
  SQL> SELECT * FROM v$asm_operation;
  
  no rows selected
  
  [OK] Aucune opération en cours -> rééquilibrage terminé


ÉTAPE 6 : Vérifier l'ajout du disque et l'augmentation de capacité
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  SQL> SELECT name, total_mb, free_mb, usable_file_mb,
              ROUND((total_mb - free_mb) / total_mb * 100, 2) AS pct_used
       FROM v$asm_diskgroup
       WHERE name = 'DATA';
  
  NAME  TOTAL_MB  FREE_MB  USABLE_FILE_MB  PCT_USED
  ----- --------- -------- --------------- ---------
  DATA      81920    32768           16384     60.00
  
  Avant : TOTAL_MB = 61440 (60 GB brut), PCT_USED = 80%
  Après : TOTAL_MB = 81920 (80 GB brut), PCT_USED = 60%
  
  [OK] Capacité augmentée de 20 GB
  [OK] Pourcentage d'utilisation réduit de 80% à 60%
  
  SQL> SELECT name, path, total_mb, free_mb
       FROM v$asm_disk
       WHERE group_number = (SELECT group_number 
                             FROM v$asm_diskgroup 
                             WHERE name = 'DATA')
       ORDER BY name;
  
  NAME       PATH                      TOTAL_MB  FREE_MB
  ---------- ------------------------- --------- --------
  DATA_0000  /dev/oracleasm/disk1          20480     8192
  DATA_0001  /dev/oracleasm/disk2          20480     8192
  DATA_0002  /dev/oracleasm/disk3          20480     8192
  DATA_0003  /dev/oracleasm/disk6          20480     8192
  
  [OK] Nouveau disque DATA_0003 ajouté avec succès
  [OK] Les données ont été rééquilibrées sur les 4 disques
  
  SQL> EXIT


ÉTAPE 7 : Vérifier avec ASMCMD
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ asmcmd lsdg
  
  State    Type    Rebal  Sector  Block       AU  Total_MB  Free_MB  Req_mir_free_MB  Usable_file_MB  Offline_disks  Name
  MOUNTED  NORMAL  N         512   4096  4194304     81920    32768            40960           16384              0  DATA/
  MOUNTED  NORMAL  N         512   4096  4194304     40960    40600            20480           10060              0  FRA/
  
  Rebal = N
  -> [OK] Aucun rééquilibrage en cours (opération terminée)
  
  $ asmcmd lsdsk -G DATA
  
  Path                      OS_MB  TOTAL_MB  FREE_MB
  ------------------------ ------- --------- --------
  /dev/oracleasm/disk1       20480     20480     8192
  /dev/oracleasm/disk2       20480     20480     8192
  /dev/oracleasm/disk3       20480     20480     8192
  /dev/oracleasm/disk6       20480     20480     8192
  
  [OK] Les 4 disques sont équilibrés (même quantité de données libres)


┌────────────────────────────────────────────────────────────────────────────┐
│                    RÉCAPITULATIF SCÉNARIO 1                                │
└────────────────────────────────────────────────────────────────────────────┘

[OK] Nouveau disque ajouté au disk group DATA
[OK] Rééquilibrage automatique effectué avec succès
[OK] Capacité augmentée : 60 GB -> 80 GB (brut)
[OK] Utilisation réduite : 80% -> 60%
[OK] Données redistribuées équitablement sur 4 disques

[TEMPS]  Temps total : 30-60 minutes (selon la taille des données)


═══════════════════════════════════════════════════════════════════════════════
9.2 SCÉNARIO 2 : MIGRATION D'UNE BASE FILESYSTEM VERS ASM
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│                         CONTEXTE DU SCÉNARIO                               │
└────────────────────────────────────────────────────────────────────────────┘

SITUATION :
  Tu as une base de données TESTDB stockée sur le filesystem (/u01/oradata)
  Tu veux migrer tous les fichiers vers ASM pour bénéficier de la redondance

OBJECTIFS :
  1. Sauvegarder la base existante
  2. Migrer les fichiers vers ASM avec RMAN
  3. Vérifier que tout fonctionne sur ASM
  4. Nettoyer les anciens fichiers


ÉTAPE 1 : État initial de la base TESTDB (sur filesystem)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'oracle'
  $ sudo su - oracle
  $ export ORACLE_SID=TESTDB
  $ sqlplus / as sysdba
  
  SQL> SELECT name FROM v$datafile;
  
  NAME
  --------------------------------------------------------------------------------
  /u01/oradata/TESTDB/system01.dbf
  /u01/oradata/TESTDB/sysaux01.dbf
  /u01/oradata/TESTDB/undotbs01.dbf
  /u01/oradata/TESTDB/users01.dbf
  
  -> Tous les fichiers sont sur le filesystem
  
  SQL> SELECT member FROM v$logfile;
  
  MEMBER
  --------------------------------------------------------------------------------
  /u01/oradata/TESTDB/redo01.log
  /u01/oradata/TESTDB/redo02.log
  /u01/oradata/TESTDB/redo03.log
  
  SQL> SELECT name FROM v$controlfile;
  
  NAME
  --------------------------------------------------------------------------------
  /u01/oradata/TESTDB/control01.ctl
  /u01/oradata/TESTDB/control02.ctl
  
  SQL> EXIT


ÉTAPE 2 : Sauvegarder la base avant migration (ESSENTIEL)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ rman target /
  
  RMAN> BACKUP DATABASE PLUS ARCHIVELOG;
  
  [TEMPS]  Temps : 10-30 minutes
  
  RMAN> LIST BACKUP SUMMARY;
  
  [OK] Sauvegarde complète effectuée avant migration
  
  RMAN> EXIT


ÉTAPE 3 : Arrêter proprement la base de données
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ sqlplus / as sysdba
  
  SQL> SHUTDOWN IMMEDIATE;
  
  Database closed.
  Database dismounted.
  ORACLE instance shut down.
  
  [OK] Base arrêtée proprement


ÉTAPE 4 : Démarrer en mode NOMOUNT pour préparer la migration
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  SQL> STARTUP NOMOUNT;
  
  ORACLE instance started.
  
  Total System Global Area 2147483648 bytes
  Fixed Size                  8896856 bytes
  Variable Size            1543503872 bytes
  Database Buffers          536870912 bytes
  Redo Buffers               58212352 bytes
  
  [OK] Instance démarrée en NOMOUNT (pas de montage de la base)
  
  SQL> EXIT


ÉTAPE 5 : Migrer les fichiers avec RMAN
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ rman target /
  
  RMAN> -- Restaurer le control file vers ASM
  RMAN> RESTORE CONTROLFILE FROM '/u01/oradata/TESTDB/control01.ctl';
  
  Starting restore at 20-DEC-24
  allocated channel: ORA_DISK_1
  channel ORA_DISK_1: SID=123 device type=DISK
  
  channel ORA_DISK_1: copied control file copy
  output file name=+DATA/TESTDB/CONTROLFILE/current.256.1234567890
  Finished restore at 20-DEC-24
  
  [OK] Control file restauré sur +DATA
  
  RMAN> -- Monter la base avec le nouveau control file
  RMAN> ALTER DATABASE MOUNT;
  
  Statement processed
  
  RMAN> -- Copier tous les datafiles vers ASM
  RMAN> BACKUP AS COPY DATABASE FORMAT '+DATA';
  
  Starting backup at 20-DEC-24
  using channel ORA_DISK_1
  channel ORA_DISK_1: starting datafile copy
  input datafile file number=00001 name=/u01/oradata/TESTDB/system01.dbf
  output file name=+DATA/TESTDB/DATAFILE/system.257.1234567891 tag=TAG20241220T210000
  channel ORA_DISK_1: datafile copy complete, elapsed time: 00:02:15
  
  channel ORA_DISK_1: starting datafile copy
  input datafile file number=00003 name=/u01/oradata/TESTDB/sysaux01.dbf
  output file name=+DATA/TESTDB/DATAFILE/sysaux.258.1234567892 tag=TAG20241220T210000
  [...]
  
  Finished backup at 20-DEC-24
  
  [TEMPS]  Temps : 10-30 minutes (selon la taille de la base)
  
  [OK] Tous les datafiles copiés vers +DATA
  
  RMAN> -- Basculer la base pour utiliser les nouveaux fichiers sur ASM
  RMAN> SWITCH DATABASE TO COPY;
  
  datafile 1 switched to datafile copy "+DATA/TESTDB/DATAFILE/system.257.1234567891"
  datafile 3 switched to datafile copy "+DATA/TESTDB/DATAFILE/sysaux.258.1234567892"
  datafile 4 switched to datafile copy "+DATA/TESTDB/DATAFILE/undotbs1.259.1234567893"
  datafile 7 switched to datafile copy "+DATA/TESTDB/DATAFILE/users.260.1234567894"
  
  [OK] Base maintenant configurée pour utiliser les fichiers ASM


ÉTAPE 6 : Recréer les redo logs sur ASM
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  RMAN> EXIT
  
  $ sqlplus / as sysdba
  
  SQL> -- Lister les redo log groups et leur emplacement
  SQL> SELECT group#, member FROM v$logfile ORDER BY group#;
  
  GROUP#  MEMBER
  ------- --------------------------------------------------------------------------------
        1 /u01/oradata/TESTDB/redo01.log
        2 /u01/oradata/TESTDB/redo02.log
        3 /u01/oradata/TESTDB/redo03.log
  
  -> Les redo logs sont encore sur le filesystem
  
  SQL> -- Ajouter de nouveaux redo logs sur ASM
  SQL> ALTER DATABASE ADD LOGFILE GROUP 4 '+DATA' SIZE 100M;
  SQL> ALTER DATABASE ADD LOGFILE GROUP 5 '+DATA' SIZE 100M;
  SQL> ALTER DATABASE ADD LOGFILE GROUP 6 '+DATA' SIZE 100M;
  
  Logfile created.
  
  SQL> -- Basculer vers les nouveaux groupes
  SQL> ALTER SYSTEM SWITCH LOGFILE;
  SQL> ALTER SYSTEM CHECKPOINT;
  
  SQL> -- Attendre que les anciens groupes ne soient plus actifs
  SQL> SELECT group#, status, archived FROM v$log;
  
  GROUP#  STATUS      ARCHIVED
  ------- ----------- --------
        1 INACTIVE    YES
        2 INACTIVE    YES
        3 INACTIVE    YES
        4 ACTIVE      NO
        5 INACTIVE    YES
        6 CURRENT     NO
  
  -> Groupes 1, 2, 3 = INACTIVE et ARCHIVED -> peuvent être supprimés
  
  SQL> -- Supprimer les anciens redo logs (filesystem)
  SQL> ALTER DATABASE DROP LOGFILE GROUP 1;
  SQL> ALTER DATABASE DROP LOGFILE GROUP 2;
  SQL> ALTER DATABASE DROP LOGFILE GROUP 3;
  
  Database altered.
  
  SQL> -- Vérifier que seuls les nouveaux groupes (ASM) existent
  SQL> SELECT group#, member FROM v$logfile ORDER BY group#;
  
  GROUP#  MEMBER
  ------- --------------------------------------------------------------------------------
        4 +DATA/TESTDB/ONLINELOG/group_4.261.1234567895
        5 +DATA/TESTDB/ONLINELOG/group_5.262.1234567896
        6 +DATA/TESTDB/ONLINELOG/group_6.263.1234567897
  
  [OK] Redo logs migrés vers ASM


ÉTAPE 7 : Recréer les control files sur ASM (optionnel, pour redondance)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  SQL> -- Vérifier les control files actuels
  SQL> SELECT name FROM v$controlfile;
  
  NAME
  --------------------------------------------------------------------------------
  +DATA/TESTDB/CONTROLFILE/current.256.1234567890
  
  -> Un seul control file sur +DATA
  -> Best practice : avoir aussi une copie sur +FRA
  
  SQL> -- Arrêter la base
  SQL> SHUTDOWN IMMEDIATE;
  
  SQL> -- Modifier le paramètre pour ajouter un control file sur FRA
  SQL> STARTUP NOMOUNT;
  
  SQL> -- Afficher le paramètre actuel
  SQL> SHOW PARAMETER control_files;
  
  NAME           TYPE   VALUE
  -------------- ------ --------------------------------------------------------------------------------
  control_files  string +DATA/TESTDB/CONTROLFILE/current.256.1234567890
  
  SQL> -- Créer le script pour recréer le control file
  SQL> ALTER DATABASE BACKUP CONTROLFILE TO TRACE AS '/tmp/recreate_controlfile.sql';
  
  SQL> EXIT
  
  # Éditer le fichier pour ajouter FRA
  $ vi /tmp/recreate_controlfile.sql
  
  # Chercher la ligne CONTROL_FILES et modifier :
  # Avant :
  # CONTROL_FILES='+DATA/TESTDB/CONTROLFILE/current.256.1234567890'
  
  # Après :
  # CONTROL_FILES=('+DATA/TESTDB/CONTROLFILE/current.ctl', '+FRA/TESTDB/CONTROLFILE/current.ctl')
  
  # Recréer le control file
  $ sqlplus / as sysdba
  SQL> STARTUP NOMOUNT;
  SQL> @/tmp/recreate_controlfile.sql
  
  Control file created.
  
  SQL> ALTER DATABASE OPEN;
  
  Database altered.
  
  SQL> SELECT name FROM v$controlfile;
  
  NAME
  --------------------------------------------------------------------------------
  +DATA/TESTDB/CONTROLFILE/current.264.1234567900
  +FRA/TESTDB/CONTROLFILE/current.265.1234567901
  
  [OK] Control files maintenant sur DATA et FRA (redondance)


ÉTAPE 8 : Ouvrir la base et vérifier que tout fonctionne
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  SQL> SELECT status FROM v$instance;
  
  STATUS
  ------------
  OPEN
  
  [OK] Base ouverte
  
  SQL> -- Vérifier tous les fichiers
  SQL> SELECT name FROM v$datafile;
  
  NAME
  --------------------------------------------------------------------------------
  +DATA/TESTDB/DATAFILE/system.257.1234567891
  +DATA/TESTDB/DATAFILE/sysaux.258.1234567892
  +DATA/TESTDB/DATAFILE/undotbs1.259.1234567893
  +DATA/TESTDB/DATAFILE/users.260.1234567894
  
  [OK] Tous les datafiles sur ASM
  
  SQL> SELECT member FROM v$logfile;
  
  MEMBER
  --------------------------------------------------------------------------------
  +DATA/TESTDB/ONLINELOG/group_4.261.1234567895
  +DATA/TESTDB/ONLINELOG/group_5.262.1234567896
  +DATA/TESTDB/ONLINELOG/group_6.263.1234567897
  
  [OK] Tous les redo logs sur ASM
  
  SQL> SELECT name FROM v$controlfile;
  
  NAME
  --------------------------------------------------------------------------------
  +DATA/TESTDB/CONTROLFILE/current.264.1234567900
  +FRA/TESTDB/CONTROLFILE/current.265.1234567901
  
  [OK] Control files sur DATA et FRA
  
  SQL> -- Test de lecture/écriture
  SQL> CREATE TABLE test_migration (id NUMBER, data VARCHAR2(100));
  SQL> INSERT INTO test_migration VALUES (1, 'Migration réussie !');
  SQL> COMMIT;
  SQL> SELECT * FROM test_migration;
  
          ID DATA
  ---------- --------------------
           1 Migration réussie !
  
  [OK] Lecture/écriture fonctionnelles
  
  SQL> EXIT


ÉTAPE 9 : Nettoyer les anciens fichiers sur le filesystem
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  [ATTENTION]  ATTENTION : Ne supprime les anciens fichiers QUE si tu es SÛR que la base fonctionne sur ASM
  
  # Lister les anciens fichiers
  $ ls -lh /u01/oradata/TESTDB/
  
  -rw-r----- 1 oracle oinstall 890M Dec 20 19:00 system01.dbf
  -rw-r----- 1 oracle oinstall 580M Dec 20 19:00 sysaux01.dbf
  -rw-r----- 1 oracle oinstall 105M Dec 20 19:00 undotbs01.dbf
  -rw-r----- 1 oracle oinstall   5M Dec 20 19:00 users01.dbf
  -rw-r----- 1 oracle oinstall 100M Dec 20 19:00 redo01.log
  -rw-r----- 1 oracle oinstall 100M Dec 20 19:00 redo02.log
  -rw-r----- 1 oracle oinstall 100M Dec 20 19:00 redo03.log
  -rw-r----- 1 oracle oinstall  20M Dec 20 19:00 control01.ctl
  -rw-r----- 1 oracle oinstall  20M Dec 20 19:00 control02.ctl
  
  # Sauvegarder avant de supprimer (optionnel)
  $ tar -czf /backup/testdb_old_files_$(date +%Y%m%d).tar.gz /u01/oradata/TESTDB/
  
  # Supprimer les anciens fichiers
  $ rm -rf /u01/oradata/TESTDB/*.dbf
  $ rm -rf /u01/oradata/TESTDB/*.log
  $ rm -rf /u01/oradata/TESTDB/*.ctl
  
  [OK] Anciens fichiers supprimés


┌────────────────────────────────────────────────────────────────────────────┐
│                    RÉCAPITULATIF SCÉNARIO 2                                │
└────────────────────────────────────────────────────────────────────────────┘

[OK] Base de données TESTDB migrée du filesystem vers ASM
[OK] Tous les fichiers (datafiles, redo logs, control files) sur ASM
[OK] Redondance configurée (control files sur DATA et FRA)
[OK] Base opérationnelle après migration
[OK] Anciens fichiers nettoyés

[TEMPS]  Temps total : 60-120 minutes (selon la taille de la base)


═══════════════════════════════════════════════════════════════════════════════
9.3 SCÉNARIO 3 : RESTAURATION COMPLÈTE APRÈS PERTE DE DONNÉES
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│                         CONTEXTE DU SCÉNARIO                               │
└────────────────────────────────────────────────────────────────────────────┘

SITUATION :
  Catastrophe ! Un utilisateur a supprimé accidentellement une table importante
  Table : EMPLOYEES (contient les données des employés)
  Heure de la suppression : 20-DEC-2024 14:30:00
  Dernière sauvegarde RMAN : 20-DEC-2024 02:00:00 (sauvegarde nocturne)

OBJECTIFS :
  1. Confirmer la perte de données
  2. Identifier le moment exact de la suppression
  3. Restaurer la base à un point dans le temps (point-in-time recovery)
  4. Récupérer la table EMPLOYEES
  5. Remettre la base en production


ÉTAPE 1 : Constater et documenter le problème
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'oracle'
  $ sqlplus / as sysdba
  
  SQL> -- Se connecter au schéma concerné
  SQL> CONNECT hr/password@ORCL
  
  SQL> -- Vérifier que la table n'existe plus
  SQL> SELECT COUNT(*) FROM employees;
  
  SELECT COUNT(*) FROM employees
                       *
  ERROR at line 1:
  ORA-00942: table or view does not exist
  
  [ATTENTION]  Confirmation : la table EMPLOYEES a été supprimée
  
  SQL> CONNECT / AS SYSDBA
  
  SQL> -- Chercher l'heure exacte de la suppression dans l'audit
  SQL> SELECT timestamp, username, sql_text
       FROM dba_audit_trail
       WHERE obj_name = 'EMPLOYEES'
       AND sql_text LIKE '%DROP%'
       ORDER BY timestamp DESC;
  
  TIMESTAMP           USERNAME  SQL_TEXT
  ------------------- --------- ---------------------------------
  20-DEC-24 14:30:15  HR        DROP TABLE employees PURGE
  
  [OK] Confirmation : DROP TABLE à 14:30:15
  [OK] Objectif : Restaurer la base à 14:29:00 (1 minute avant)


ÉTAPE 2 : Vérifier que nous avons les sauvegardes et archived logs nécessaires
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ rman target /
  
  RMAN> -- Lister les sauvegardes disponibles
  RMAN> LIST BACKUP SUMMARY;
  
  List of Backups
  ===============
  Key     TY LV S Device Type Completion Time #Pieces #Copies Compressed Tag
  ------- -- -- - ----------- --------------- ------- ------- ---------- ---
  123     B  0  A DISK        20-DEC-24 02:00 3       1       YES        FULL_BACKUP
  
  [OK] Sauvegarde complète à 02:00 (avant la suppression)
  
  RMAN> -- Vérifier les archived logs depuis la sauvegarde
  RMAN> LIST ARCHIVELOG ALL;
  
  List of Archived Log Copies for database with db_unique_name ORCL
  =====================================================================
  
  Key     Thrd Seq     S Low Time           Name
  ------- ---- ------- - ------------------- -------------------------
  245     1    156     A 20-DEC-24 02:00:00 +FRA/ORCL/ARCHIVELOG/...
  246     1    157     A 20-DEC-24 03:00:00 +FRA/ORCL/ARCHIVELOG/...
  247     1    158     A 20-DEC-24 04:00:00 +FRA/ORCL/ARCHIVELOG/...
  [...]
  268     1    179     A 20-DEC-24 14:28:30 +FRA/ORCL/ARCHIVELOG/...
  269     1    180     A 20-DEC-24 14:35:00 +FRA/ORCL/ARCHIVELOG/...
  
  [OK] Archived logs disponibles jusqu'à 14:35 (après la suppression)
  [OK] Nous pouvons restaurer jusqu'à 14:29
  
  RMAN> EXIT


ÉTAPE 3 : Avertir les utilisateurs et arrêter la base
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  [ATTENTION]  IMPORTANT : La restauration nécessite l'arrêt de la base
  [ATTENTION]  Prévenir TOUS les utilisateurs avant
  
  $ sqlplus / as sysdba
  
  SQL> -- Forcer la déconnexion de tous les utilisateurs
  SQL> ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
  
  -- OU pour déconnecter tout le monde automatiquement :
  SQL> BEGIN
           FOR r IN (SELECT sid, serial# FROM v$session WHERE username IS NOT NULL) LOOP
               EXECUTE IMMEDIATE 'ALTER SYSTEM KILL SESSION ''' || r.sid || ',' || r.serial# || ''' IMMEDIATE';
           END LOOP;
       END;
       /
  
  SQL> -- Arrêter la base
  SQL> SHUTDOWN IMMEDIATE;
  
  Database closed.
  Database dismounted.
  ORACLE instance shut down.
  
  SQL> EXIT


ÉTAPE 4 : Restaurer la base à partir de la sauvegarde
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ rman target /
  
  RMAN> -- Démarrer en NOMOUNT
  RMAN> STARTUP NOMOUNT;
  
  Oracle instance started
  
  Total System Global Area    2147483648 bytes
  [...]
  
  RMAN> -- Restaurer le control file depuis la sauvegarde
  RMAN> RESTORE CONTROLFILE FROM AUTOBACKUP;
  
  Starting restore at 20-DEC-24
  allocated channel: ORA_DISK_1
  channel ORA_DISK_1: looking for AUTOBACKUP on day: 20241220
  channel ORA_DISK_1: AUTOBACKUP found: +FRA/ORCL/AUTOBACKUP/2024_12_20/s_123456.289.1234567999
  channel ORA_DISK_1: restoring control file from AUTOBACKUP
  [...]
  output file name=+DATA/ORCL/CONTROLFILE/current.256.1234567890
  output file name=+FRA/ORCL/CONTROLFILE/current.261.1234567895
  Finished restore at 20-DEC-24
  
  [OK] Control file restauré
  
  RMAN> -- Monter la base
  RMAN> ALTER DATABASE MOUNT;
  
  Statement processed
  
  RMAN> -- Restaurer tous les datafiles
  RMAN> RESTORE DATABASE;
  
  Starting restore at 20-DEC-24
  using channel ORA_DISK_1
  
  channel ORA_DISK_1: starting datafile backup set restore
  channel ORA_DISK_1: specifying datafile(s) to restore from backup set
  channel ORA_DISK_1: restoring datafile 00001 to +DATA/ORCL/DATAFILE/system.256.1234567890
  channel ORA_DISK_1: restoring datafile 00003 to +DATA/ORCL/DATAFILE/sysaux.257.1234567891
  [...]
  channel ORA_DISK_1: restore complete, elapsed time: 00:10:25
  Finished restore at 20-DEC-24
  
  [TEMPS]  Temps : 10-30 minutes (selon la taille de la base)
  
  [OK] Tous les datafiles restaurés à l'état de 02:00 (sauvegarde nocturne)


ÉTAPE 5 : Récupération point-in-time (jusqu'à 14:29:00)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  RMAN> -- Appliquer les archived logs jusqu'à 14:29:00
  RMAN> RECOVER DATABASE UNTIL TIME "TO_DATE('20-DEC-2024 14:29:00', 'DD-MON-YYYY HH24:MI:SS')";
  
  Starting recover at 20-DEC-24
  using channel ORA_DISK_1
  
  starting media recovery
  
  archived log for thread 1 with sequence 156 is already on disk as file +FRA/ORCL/ARCHIVELOG/...
  archived log for thread 1 with sequence 157 is already on disk as file +FRA/ORCL/ARCHIVELOG/...
  [...]
  archived log for thread 1 with sequence 179 is already on disk as file +FRA/ORCL/ARCHIVELOG/...
  archived log file name=+FRA/ORCL/ARCHIVELOG/2024_12_20/thread_1_seq_156.260.1234567890 thread=1 sequence=156
  archived log file name=+FRA/ORCL/ARCHIVELOG/2024_12_20/thread_1_seq_157.261.1234567891 thread=1 sequence=157
  [...]
  media recovery complete, elapsed time: 00:05:30
  Finished recover at 20-DEC-24
  
  [TEMPS]  Temps : 5-15 minutes
  
  [OK] Base restaurée à 14:29:00 (1 minute avant la suppression)
  
  RMAN> -- Ouvrir la base avec RESETLOGS
  RMAN> ALTER DATABASE OPEN RESETLOGS;
  
  Statement processed
  
  [ATTENTION]  RESETLOGS = Nouveau départ pour les redo logs
  [ATTENTION]  Les sauvegardes AVANT ce point ne peuvent plus être utilisées
  [ATTENTION]  Il FAUT faire une nouvelle sauvegarde COMPLÈTE maintenant
  
  RMAN> EXIT


ÉTAPE 6 : Vérifier que la table EMPLOYEES est restaurée
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  $ sqlplus / as sysdba
  
  SQL> SELECT open_mode, log_mode FROM v$database;
  
  OPEN_MODE            LOG_MODE
  -------------------- ------------
  READ WRITE           ARCHIVELOG
  
  [OK] Base ouverte en lecture/écriture
  
  SQL> CONNECT hr/password@ORCL
  
  SQL> -- Vérifier la table
  SQL> SELECT COUNT(*) FROM employees;
  
    COUNT(*)
  ----------
         107
  
  [OK] Table EMPLOYEES restaurée avec 107 lignes
  
  SQL> SELECT employee_id, first_name, last_name, hire_date
       FROM employees
       FETCH FIRST 5 ROWS ONLY;
  
  EMPLOYEE_ID FIRST_NAME  LAST_NAME   HIRE_DATE
  ----------- ----------- ----------- ---------
          100 Steven      King        17-JUN-03
          101 Neena       Kochhar     21-SEP-05
          102 Lex         De Haan     13-JAN-01
          103 Alexander   Hunold      03-JAN-06
          104 Bruce       Ernst       21-MAY-07
  
  [OK] Données cohérentes et correctes
  
  SQL> EXIT


ÉTAPE 7 : Effectuer une sauvegarde complète POST-RESTAURATION (CRITIQUE)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  [ATTENTION]  APRÈS UN RESETLOGS, une nouvelle sauvegarde est OBLIGATOIRE
  
  $ rman target /
  
  RMAN> BACKUP DATABASE PLUS ARCHIVELOG;
  
  Starting backup at 20-DEC-24
  current log archived
  using channel ORA_DISK_1
  [...]
  Finished backup at 20-DEC-24
  
  Starting Control File and SPFILE Autobackup at 20-DEC-24
  piece handle=+FRA/ORCL/AUTOBACKUP/2024_12_20/s_123999.289.1234569999 comment=NONE
  Finished Control File and SPFILE Autobackup at 20-DEC-24
  
  [OK] Nouvelle sauvegarde complète effectuée
  
  RMAN> EXIT


ÉTAPE 8 : Documenter l'incident et informer les utilisateurs
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Créer un rapport d'incident
  $ cat > /home/oracle/logs/incident_$(date +%Y%m%d).txt << EOF
  INCIDENT REPORT - DATA LOSS AND RECOVERY
  =========================================
  
  Date/Time of Incident: 20-DEC-2024 14:30:15
  Reported by: [Nom de l'utilisateur]
  Affected Object: HR.EMPLOYEES table
  
  Problem Description:
  - Table EMPLOYEES accidentally dropped by user HR
  - 107 employee records lost
  
  Recovery Actions Taken:
  1. Database shutdown at 14:45:00
  2. Restored from backup taken at 02:00:00
  3. Point-in-time recovery to 14:29:00 (1 min before drop)
  4. Database opened with RESETLOGS at 15:30:00
  5. Full backup taken at 15:45:00
  
  Data Loss:
  - Transactions between 14:29:00 and 14:30:15: LOST (1 minute 15 seconds)
  - All other data: RECOVERED
  
  Downtime:
  - Start: 14:45:00
  - End: 15:30:00
  - Duration: 45 minutes
  
  Preventive Measures:
  - Implement additional auditing on DROP TABLE commands
  - Train users on proper data management procedures
  - Review backup frequency (currently daily at 02:00)
  
  Prepared by: DBA Team
  Date: 20-DEC-2024 16:00:00
  EOF
  
  [OK] Incident documenté


┌────────────────────────────────────────────────────────────────────────────┐
│                    RÉCAPITULATIF SCÉNARIO 3                                │
└────────────────────────────────────────────────────────────────────────────┘

[OK] Problème identifié : DROP TABLE à 14:30:15
[OK] Base restaurée à partir de la sauvegarde de 02:00
[OK] Point-in-time recovery effectué jusqu'à 14:29:00
[OK] Table EMPLOYEES récupérée avec succès (107 lignes)
[OK] Perte de données : 1 minute 15 secondes de transactions
[OK] Nouvelle sauvegarde complète effectuée après RESETLOGS
[OK] Downtime total : 45 minutes

[TEMPS]  Temps total : 45-90 minutes (selon la taille de la base)

LEÇONS APPRISES :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. Les sauvegardes régulières sont ESSENTIELLES
2. Le mode ARCHIVELOG permet la récupération point-in-time
3. Documenter toujours les incidents pour l'amélioration continue
4. Former les utilisateurs pour éviter les accidents


═══════════════════════════════════════════════════════════════════════════════
9.4 SCÉNARIO 4 : SIMULATION ET RÉCUPÉRATION D'UNE PANNE DE DISQUE
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│                         CONTEXTE DU SCÉNARIO                               │
└────────────────────────────────────────────────────────────────────────────┘

SITUATION :
  Nous allons simuler une panne de disque dans le disk group DATA (NORMAL redundancy)
  Puis observer comment ASM gère automatiquement la panne
  Enfin, remplacer le disque défaillant et récupérer

OBJECTIFS :
  1. Simuler une panne de disque
  2. Observer le comportement d'ASM
  3. Vérifier que la base continue de fonctionner
  4. Remplacer le disque défaillant
  5. Récupérer la redondance complète


ÉTAPE 1 : État initial du disk group DATA
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'grid'
  $ sudo su - grid
  $ sqlplus / as sysasm
  
  SQL> SELECT name, state, type, total_mb, free_mb, offline_disks
       FROM v$asm_diskgroup
       WHERE name = 'DATA';
  
  NAME  STATE   TYPE    TOTAL_MB  FREE_MB  OFFLINE_DISKS
  ----- ------- ------- --------- -------- --------------
  DATA  MOUNTED NORMAL      81920    32768              0
  
  [OK] État normal : 0 disques hors ligne
  
  SQL> SELECT name, path, mode_status, state, total_mb
       FROM v$asm_disk
       WHERE group_number = (SELECT group_number FROM v$asm_diskgroup WHERE name = 'DATA')
       ORDER BY name;
  
  NAME       PATH                      MODE_STATUS  STATE   TOTAL_MB
  ---------- ------------------------- ------------ ------- ---------
  DATA_0000  /dev/oracleasm/disk1      ONLINE       NORMAL      20480
  DATA_0001  /dev/oracleasm/disk2      ONLINE       NORMAL      20480
  DATA_0002  /dev/oracleasm/disk3      ONLINE       NORMAL      20480
  DATA_0003  /dev/oracleasm/disk6      ONLINE       NORMAL      20480
  
  [OK] Tous les disques ONLINE et NORMAL
  
  SQL> EXIT


ÉTAPE 2 : Simuler une panne de disque (DATA_0002)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  [ATTENTION]  Ceci simule une VRAIE panne matérielle
  [ATTENTION]  À ne PAS faire en production sans préparation
  
  # En tant que root
  $ sudo su -
  
  # Identifier le disque à "casser"
  # ls -l /dev/oracleasm/disk3
  lrwxrwxrwx 1 root root 4 Dec 20 16:00 /dev/oracleasm/disk3 -> ../sdd
  
  # Simuler la panne en retirant les permissions de lecture
  # chmod 000 /dev/sdd
  
  # Vérifier
  # ls -l /dev/sdd
  b--------- 1 grid asmadmin 8, 48 Dec 20 16:00 /dev/sdd
  
  [OK] Disque rendu inaccessible (simule une panne matérielle)
  
  # exit


ÉTAPE 3 : Observer la réaction d'ASM (immédiate)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'grid'
  $ tail -f /u01/app/grid/diag/asm/+asm/+ASM/trace/alert_+ASM.log
  
  Sortie attendue (dans les secondes qui suivent) :
  
  2024-12-20 16:05:23.456
  WARNING: I/O error during read from disk DATA_0002
  2024-12-20 16:05:23.789
  NOTE: Attempting to read from mirror copy for disk DATA_0002
  2024-12-20 16:05:24.012
  NOTE: Successfully recovered data from mirror on disk DATA_0001
  2024-12-20 16:05:24.234
  WARNING: Disk DATA_0002 in group DATA is offline
  2024-12-20 16:05:24.567
  NOTE: Offline disk timer started for disk DATA_0002
  2024-12-20 16:05:24.890
  NOTE: ASM automatically using mirror copies, no data loss
  
  -> ASM a détecté la panne automatiquement
  -> Il bascule vers les copies miroirs (NORMAL redundancy)
  -> Aucune perte de données
  -> Un timer démarre : par défaut 3.6 heures avant de considérer le disque définitivement perdu
  
  Appuie sur Ctrl+C pour arrêter le suivi
  
  $ sqlplus / as sysasm
  
  SQL> SELECT name, path, mode_status, state
       FROM v$asm_disk
       WHERE name = 'DATA_0002';
  
  NAME       PATH                      MODE_STATUS  STATE
  ---------- ------------------------- ------------ -------
  DATA_0002  /dev/oracleasm/disk3      OFFLINE      NORMAL
  
  [ATTENTION]  MODE_STATUS = OFFLINE (disque inaccessible)
  [OK]  STATE = NORMAL (pas encore marqué comme définitivement perdu)
  
  SQL> SELECT name, state, offline_disks
       FROM v$asm_diskgroup
       WHERE name = 'DATA';
  
  NAME  STATE          OFFLINE_DISKS
  ----- -------------- --------------
  DATA  MOUNTED               1
  
  [ATTENTION]  1 disque hors ligne, mais disk group toujours MOUNTED
  
  SQL> EXIT


ÉTAPE 4 : Vérifier que la base de données continue de fonctionner
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # En tant que 'oracle'
  $ sudo su - oracle
  $ sqlplus / as sysdba
  
  SQL> SELECT status FROM v$instance;
  
  STATUS
  ------------
  OPEN
  
  [OK] Instance toujours ouverte
  
  SQL> -- Test de lecture
  SQL> SELECT COUNT(*) FROM hr.employees;
  
    COUNT(*)
  ----------
         107
  
  [OK] Lecture fonctionnelle
  
  SQL> -- Test d'écriture
  SQL> CREATE TABLE test_failover (id NUMBER, data VARCHAR2(100));
  SQL> INSERT INTO test_failover VALUES (1, 'Base fonctionnelle malgré panne disque');
  SQL> COMMIT;
  
  [OK] Écriture fonctionnelle
  
  SQL> -- Vérifier où est stockée cette nouvelle table
  SQL> SELECT file_name FROM dba_data_files WHERE tablespace_name = 'USERS';
  
  FILE_NAME
  --------------------------------------------------------------------------------
  +DATA/ORCL/DATAFILE/users.259.1234567893
  
  [OK] Les nouveaux fichiers sont créés sur DATA malgré le disque défaillant
  [OK] ASM utilise automatiquement les disques restants
  
  SQL> EXIT
  
  -> LA BASE CONTINUE DE FONCTIONNER NORMALEMENT
  -> C'est la MAGIE de la redondance ASM NORMAL !


ÉTAPE 5 : Option A - Réparer le disque existant (si panne temporaire)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Si la panne est temporaire (problème de câble, contrôleur, etc.) :
  
  # En tant que root
  $ sudo su -
  
  # Restaurer les permissions (simule la réparation)
  # chmod 660 /dev/sdd
  # chown grid:asmadmin /dev/sdd
  
  # Vérifier
  # ls -l /dev/sdd
  brw-rw---- 1 grid asmadmin 8, 48 Dec 20 16:15 /dev/sdd
  
  [OK] Disque à nouveau accessible
  
  # exit
  
  # En tant que 'grid'
  $ sqlplus / as sysasm
  
  SQL> -- Forcer ASM à réévaluer le disque
  SQL> ALTER DISKGROUP DATA ONLINE DISK DATA_0002;
  
  Diskgroup altered.
  
  -> ASM va resynchroniser les données manquées pendant l'indisponibilité
  
  SQL> -- Surveiller la resynchronisation
  SQL> SELECT operation, state, power, sofar, est_work, est_minutes
       FROM v$asm_operation;
  
  OPERATION  STATE   POWER  SOFAR  EST_WORK  EST_MINUTES
  ---------- ------- ------ ------ --------- ------------
  REBAL      RUN          4   2048     12288            8
  
  [TEMPS]  Temps : 5-15 minutes (selon les données à resynchroniser)
  
  # Quand terminé
  SQL> SELECT name, mode_status, state FROM v$asm_disk WHERE name = 'DATA_0002';
  
  NAME       MODE_STATUS  STATE
  ---------- ------------ -------
  DATA_0002  ONLINE       NORMAL
  
  [OK] Disque de retour en ligne et synchronisé
  
  SQL> EXIT


ÉTAPE 6 : Option B - Remplacer par un nouveau disque (si panne permanente)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Si le disque est vraiment mort (panne matérielle permanente) :
  
  # En tant que 'grid'
  $ sqlplus / as sysasm
  
  SQL> -- Retirer définitivement le disque défaillant
  SQL> ALTER DISKGROUP DATA DROP DISK DATA_0002 FORCE;
  
  Diskgroup altered.
  
  -> ASM retire le disque du disk group
  -> Les données sont maintenant SANS redondance sur ce disque
  -> Il FAUT ajouter un nouveau disque rapidement
  
  SQL> EXIT
  
  # Préparer un nouveau disque (en tant que root)
  $ sudo su -
  
  # Installer physiquement le nouveau disque (ou créer pour test)
  # dd if=/dev/zero of=/u01/asmdisks/disk7.img bs=1M count=20480
  # losetup /dev/loop7 /u01/asmdisks/disk7.img
  
  # OU pour un vrai disque :
  # Nouveau disque = /dev/sde (par exemple)
  
  # Ajouter la règle UDEV
  # vi /etc/udev/rules.d/99-oracle-asmdevices.rules
  # Ajouter :
  KERNEL=="sde", OWNER="grid", GROUP="asmadmin", MODE="0660", SYMLINK+="oracleasm/disk7"
  
  # Recharger
  # udevadm control --reload-rules
  # udevadm trigger
  
  # Vérifier
  # ls -l /dev/oracleasm/disk7
  lrwxrwxrwx 1 root root 4 Dec 20 16:30 /dev/oracleasm/disk7 -> ../sde
  
  # exit
  
  # En tant que 'grid'
  $ sqlplus / as sysasm
  
  SQL> -- Ajouter le nouveau disque
  SQL> ALTER DISKGROUP DATA ADD DISK '/dev/oracleasm/disk7' SIZE 20G;
  
  Diskgroup altered.
  
  -> Rééquilibrage automatique démarre
  
  SQL> -- Surveiller
  SQL> SELECT operation, state, est_minutes FROM v$asm_operation;
  
  OPERATION  STATE   EST_MINUTES
  ---------- ------- ------------
  REBAL      RUN               15
  
  [TEMPS]  Temps : 10-30 minutes
  
  # Quand terminé
  SQL> SELECT name, total_mb, offline_disks
       FROM v$asm_diskgroup
       WHERE name = 'DATA';
  
  NAME  TOTAL_MB  OFFLINE_DISKS
  ----- --------- --------------
  DATA      81920              0
  
  [OK] Retour à 0 disques hors ligne
  [OK] Redondance complète restaurée
  
  SQL> EXIT


┌────────────────────────────────────────────────────────────────────────────┐
│                    RÉCAPITULATIF SCÉNARIO 4                                │
└────────────────────────────────────────────────────────────────────────────┘

[OK] Panne de disque simulée avec succès
[OK] ASM a détecté la panne automatiquement
[OK] Basculement automatique vers les copies miroirs
[OK] Base de données a continué de fonctionner (ZÉRO downtime)
[OK] Aucune perte de données
[OK] Disque remplacé et redondance restaurée

[TEMPS]  Temps de récupération : 15-30 minutes (sans interruption de service)

POINTS CLÉS :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. La redondance NORMAL protège contre UNE panne de disque
2. ASM gère automatiquement le failover (aucune intervention DBA nécessaire)
3. Les applications continuent de fonctionner pendant la panne
4. Le remplacement de disque se fait EN LIGNE (no downtime)
5. Important : Remplacer le disque rapidement pour restaurer la redondance


═══════════════════════════════════════════════════════════════════════════════
9.5 EXERCICES PRATIQUES
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│                    EXERCICES POUR CONSOLIDER TES CONNAISSANCES             │
└────────────────────────────────────────────────────────────────────────────┘

EXERCICE 1 : Créer un nouveau disk group pour les TEMP files
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Objectif : Créer un disk group TEMP dédié aux fichiers temporaires

Tâches :
1. Préparer 2 nouveaux disques de 10 GB chacun
2. Créer le disk group TEMP avec redondance EXTERNAL
3. Créer un tablespace temporaire sur ce disk group
4. Définir ce tablespace comme temporaire par défaut
5. Vérifier avec ASMCMD et SQL

Résultat attendu :
- Disk group TEMP : 20 GB utilisables (EXTERNAL = pas de mirroring)
- Tablespace TEMP_NEW sur +TEMP
- Toutes les sessions utilisent TEMP_NEW par défaut


EXERCICE 2 : Mettre en place une sauvegarde RMAN automatisée
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Objectif : Automatiser les sauvegardes quotidiennes

Tâches :
1. Créer un script de sauvegarde incrémentielle niveau 1
2. Le script doit sauvegarder les archived logs et les supprimer après
3. Configurer cron pour exécution à 3h du matin tous les jours
4. Le script doit envoyer un email en cas d'erreur
5. Conserver les logs de sauvegarde pendant 30 jours

Résultat attendu :
- Script /home/oracle/scripts/backup_daily.sh
- Crontab configuré
- Test d'exécution manuelle réussi


EXERCICE 3 : Surveillance proactive des disk groups
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Objectif : Créer un script de monitoring qui alerte en cas de problème

Tâches :
1. Créer un script qui vérifie :
   - Espace libre dans DATA et FRA (alerte si < 20%)
   - Disques hors ligne (alerte si > 0)
   - État d'ASM et des bases de données
   - Taille de la FRA et % d'archived logs
2. Envoyer un email si un problème est détecté
3. Programmer l'exécution toutes les heures avec cron
4. Logger les résultats dans /home/grid/logs/monitoring.log

Résultat attendu :
- Script /home/grid/scripts/monitor_asm.sh
- Exécution automatique toutes les heures
- Historique des vérifications dans le log


EXERCICE 4 : Migration d'un tablespace vers un autre disk group
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Objectif : Déplacer un tablespace de DATA vers FRA

Tâches :
1. Créer un tablespace TEST_TBS sur +DATA avec 100 MB
2. Créer une table dedans et y insérer 10000 lignes
3. Déplacer le datafile vers +FRA en utilisant RMAN
4. Vérifier que la table est toujours accessible
5. Confirmer que le fichier est bien sur +FRA

Résultat attendu :
- Tablespace migré de +DATA vers +FRA
- Données intactes et accessibles
- Pas de downtime pendant la migration


EXERCICE 5 : Test de disaster recovery complet
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Objectif : Simuler la perte complète d'un serveur et récupérer

Scénario :
Le serveur principal est perdu (incendie, inondation, etc.)
Tu dois reconstruire sur un nouveau serveur en utilisant les sauvegardes

Tâches :
1. Sauvegarder les métadonnées ASM (md_backup)
2. Copier les backups RMAN vers un emplacement externe
3. Simuler la perte : supprimer tous les disk groups (DROP DISKGROUP)
4. Recréer les disk groups à partir des métadonnées sauvegardées
5. Restaurer la base de données avec RMAN
6. Vérifier que tout fonctionne

Résultat attendu :
- Base de données complètement récupérée
- Tous les disk groups recréés
- Données intactes


┌────────────────────────────────────────────────────────────────────────────┐
│               SOLUTIONS AUX EXERCICES (Section suivante)                   │
└────────────────────────────────────────────────────────────────────────────┘

Les solutions détaillées pour chaque exercice sont disponibles dans un document
séparé : "SOLUTIONS_EXERCICES_ASM.txt"

Il est FORTEMENT recommandé d'essayer de résoudre les exercices par toi-même
AVANT de consulter les solutions. C'est en pratiquant que tu apprends vraiment !


┌────────────────────────────────────────────────────────────────────────────┐
│                      RÉCAPITULATIF DE LA PARTIE 9                          │
└────────────────────────────────────────────────────────────────────────────┘

[OK] Scénario 1 : Ajout de disque maîtrisé
   - Augmentation de capacité d'un disk group
   - Rééquilibrage automatique

[OK] Scénario 2 : Migration filesystem -> ASM réussie
   - Tous les fichiers déplacés vers ASM
   - Base opérationnelle après migration

[OK] Scénario 3 : Restauration point-in-time maîtrisée
   - Récupération après perte de données
   - PITR avec RMAN

[OK] Scénario 4 : Gestion de panne de disque
   - Failover automatique démontré
   - Remplacement de disque en ligne

[OK] Exercices pratiques fournis
   - 5 exercices pour consolider les connaissances
   - Couvrent tous les aspects d'ASM

[TEMPS]  Temps total de la partie 9 : 120-180 minutes

PROCHAINE ÉTAPE : Conclusion et ressources
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Dans la partie 10, nous allons :
1. Récapitulatif complet du guide
2. Meilleures pratiques et recommandations
3. Ressources additionnelles
4. Glossaire des termes
5. Commandes de référence rapide

################################################################################
#                                                                              #
#  PARTIE 10 : CONCLUSION ET RESSOURCES                                       #
#                                                                              #
################################################################################

Dans cette partie finale :
1. Récapitulatif complet du guide
2. Meilleures pratiques et recommandations
3. Checklist de production
4. Commandes de référence rapide
5. Glossaire des termes
6. Ressources additionnelles et liens utiles
7. Conclusion

[TEMPS]  Durée estimée : 30 minutes (lecture)

═══════════════════════════════════════════════════════════════════════════════
10.1 RÉCAPITULATIF COMPLET DU GUIDE
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│                    CE QUE TU AS APPRIS DANS CE GUIDE                       │
└────────────────────────────────────────────────────────────────────────────┘

PARTIE 1 : Introduction et Architecture
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[OK] Compréhension d'ASM et de ses avantages
[OK] Architecture à deux niveaux : Grid Infrastructure + Database
[OK] Séparation des utilisateurs 'grid' et 'oracle'
[OK] Concepts : disk groups, redundancy, allocation units, extents

PARTIE 2 : Préparation du Système
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[OK] Configuration d'Ubuntu pour Oracle
[OK] Création des utilisateurs et groupes Unix
[OK] Installation des packages requis
[OK] Configuration du kernel et des limites système

PARTIE 3 : Préparation des Disques
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[OK] Identification et préparation des disques
[OK] Configuration UDEV pour les liens persistants
[OK] Gestion des permissions et propriétés
[OK] Vérification de la visibilité des disques

PARTIE 4 : Arborescence des Répertoires
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[OK] Création de l'arborescence Oracle Flexible Architecture (OFA)
[OK] Séparation ORACLE_BASE et ORACLE_HOME
[OK] Répertoires distincts pour 'grid' et 'oracle'
[OK] Organisation des fichiers de staging et logs

PARTIE 5 : Installation Grid Infrastructure
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[OK] Téléchargement et extraction de Grid Infrastructure 19c
[OK] Installation en mode silencieux avec response file
[OK] Configuration d'Oracle Restart (haute disponibilité)
[OK] Création du premier disk group DATA
[OK] Démarrage de l'instance ASM (+ASM)

PARTIE 6 : Gestion des Disk Groups
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[OK] Création du disk group FRA (Fast Recovery Area)
[OK] Navigation avec ASMCMD
[OK] Compréhension des métadonnées ASM
[OK] Opérations de maintenance (add/drop disk, mount/dismount)
[OK] Simulation de panne et récupération

PARTIE 7 : Installation Oracle Database
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[OK] Installation des binaires Oracle Database 19c
[OK] Configuration du listener réseau (géré par Grid)
[OK] Création de la base ORCL avec DBCA en mode silencieux
[OK] Vérification de l'intégration complète avec ASM
[OK] Enregistrement dans Oracle Restart
[OK] Tests fonctionnels

PARTIE 8 : Administration Quotidienne
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[OK] Séparation des tâches 'grid' vs 'oracle'
[OK] Surveillance d'ASM et des disk groups
[OK] Surveillance de la base de données
[OK] Gestion des sauvegardes avec RMAN
[OK] Scripts de monitoring automatisés
[OK] Troubleshooting de base

PARTIE 9 : Scénarios Pratiques
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[OK] Ajout d'un disque à un disk group
[OK] Migration d'une base filesystem vers ASM
[OK] Restauration après perte de données (PITR)
[OK] Gestion d'une panne de disque
[OK] Exercices pratiques pour consolider

PARTIE 10 : Conclusion
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[OK] Récapitulatif et ressources (cette partie)


═══════════════════════════════════════════════════════════════════════════════
10.2 MEILLEURES PRATIQUES ET RECOMMANDATIONS
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│                    BEST PRACTICES POUR LA PRODUCTION                       │
└────────────────────────────────────────────────────────────────────────────┘

INFRASTRUCTURE ET DISQUES
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

1. REDONDANCE
   [OK] Utiliser NORMAL redundancy pour les données critiques (DATA)
   [OK] EXTERNAL redundancy acceptable si le stockage sous-jacent a déjà du RAID
   [OK] Toujours avoir au moins 3 disques pour NORMAL redundancy
   [OK] HIGH redundancy (triple mirroring) pour les données ultra-critiques

2. DIMENSIONNEMENT DES DISK GROUPS
   [OK] DATA : Au moins 50% de marge (ne jamais dépasser 80% d'utilisation)
   [OK] FRA : Dimensionner pour 2-3 jours de backups + archived logs
   [OK] Planifier la croissance : prévoir l'ajout de disques à l'avance

3. CHOIX DES DISQUES
   [OK] Utiliser des disques de même taille dans un disk group
   [OK] Privilégier les SSD pour les performances
   [OK] Éviter de mélanger SSD et HDD dans le même disk group
   [OK] Répartir les disques sur différents contrôleurs (éviter SPOF)

4. ALLOCATION UNITS (AU)
   [OK] 4 MB par défaut (bon compromis)
   [OK] 1 MB pour bases OLTP avec beaucoup de petites transactions
   [OK] 8-64 MB pour bases OLAP/Data Warehouse


ADMINISTRATION ET MAINTENANCE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

5. SAUVEGARDES
   [OK] Sauvegarde COMPLÈTE au moins une fois par semaine
   [OK] Sauvegardes INCRÉMENTIELLES quotidiennes
   [OK] Mode ARCHIVELOG obligatoire en production
   [OK] Tester régulièrement les restaurations (1x par mois minimum)
   [OK] Conserver les backups HORS du serveur de production
   [OK] Sauvegarder les métadonnées ASM (md_backup) hebdomadairement

6. SURVEILLANCE
   [OK] Monitoring automatisé toutes les heures
   [OK] Alertes si espace disque < 20%
   [OK] Alertes immédiate si disque offline
   [OK] Surveillance des logs (alert log ASM et DB)
   [OK] Dashboard pour visualiser l'état du système

7. HAUTE DISPONIBILITÉ
   [OK] Utiliser Oracle Restart sur serveurs standalone
   [OK] Configurer les ressources pour démarrage automatique
   [OK] Tester régulièrement le redémarrage après crash simulé

8. DOCUMENTATION
   [OK] Documenter TOUTE modification de configuration
   [OK] Tenir à jour un diagramme de l'architecture
   [OK] Créer des runbooks pour les opérations courantes
   [OK] Log de tous les incidents et résolutions


SÉCURITÉ
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

9. MOTS DE PASSE
   [OK] Utiliser des mots de passe FORTS (min. 12 caractères)
   [OK] Changer TOUS les mots de passe par défaut
   [OK] Rotation des mots de passe tous les 90 jours
   [OK] Ne JAMAIS stocker les mots de passe en clair

10. ACCÈS ET PERMISSIONS
    [OK] Principe du moindre privilège
    [OK] Séparer strictement les rôles 'grid' et 'oracle'
    [OK] Auditer les connexions des comptes privilégiés
    [OK] Désactiver les comptes inutilisés

11. RÉSEAU
    [OK] Firewall : Autoriser uniquement le port 1521 (listener)
    [OK] Utiliser SSL/TLS pour les connexions distantes
    [OK] Segmenter le réseau (VLAN séparé pour la base de données)


PERFORMANCE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

12. MÉMOIRE
    [OK] Allouer 40-50% de la RAM totale à Oracle (SGA + PGA)
    [OK] Utiliser Automatic Memory Management (AMM) pour débuter
    [OK] Passer à Automatic Shared Memory Management (ASMM) pour optimiser
    [OK] Surveiller les statistiques de mémoire régulièrement

13. RÉÉQUILIBRAGE ASM
    [OK] Effectuer les opérations d'add/drop disk en heures creuses
    [OK] Ajuster POWER selon la charge du système (1-11)
    [OK] POWER élevé = plus rapide mais plus de ressources

14. STATISTIQUES
    [OK] Collecter les statistiques régulièrement (DBMS_STATS)
    [OK] Analyser les requêtes lentes (AWR reports)
    [OK] Optimiser les index et les requêtes


═══════════════════════════════════════════════════════════════════════════════
10.3 CHECKLIST DE MISE EN PRODUCTION
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│          CHECKLIST AVANT DE METTRE UNE BASE ASM EN PRODUCTION             │
└────────────────────────────────────────────────────────────────────────────┘

INFRASTRUCTURE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[ ] Serveur dimensionné selon les besoins (CPU, RAM, Disque)
[ ] Disques ASM configurés avec redondance appropriée
[ ] Réseau stable et haute disponibilité
[ ] Système d'exploitation à jour (patches de sécurité)
[ ] Firewall configuré (port 1521 ouvert si nécessaire)

INSTALLATION
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[ ] Grid Infrastructure 19c installé et fonctionnel
[ ] Oracle Database 19c installé et fonctionnel
[ ] Tous les patches de sécurité critiques appliqués
[ ] Oracle Restart configuré et testé
[ ] Listener démarré et enregistré

DISK GROUPS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[ ] Disk group DATA créé avec redondance NORMAL
[ ] Disk group FRA créé et dimensionné correctement
[ ] Tous les disques ONLINE et en état NORMAL
[ ] Espace libre > 50% dans chaque disk group
[ ] Métadonnées ASM sauvegardées (md_backup)

BASE DE DONNÉES
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[ ] Base de données ORCL créée et ouverte
[ ] Mode ARCHIVELOG activé
[ ] Fast Recovery Area configurée
[ ] Tous les fichiers sur ASM (datafiles, redo logs, control files)
[ ] Tablespaces dimensionnés avec marge de croissance
[ ] Paramètres de mémoire configurés (SGA, PGA)

SAUVEGARDES
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[ ] RMAN configuré (retention policy, compression, etc.)
[ ] Sauvegarde complète initiale effectuée
[ ] Sauvegardes automatiques programmées (cron)
[ ] Destination des backups accessible et sécurisée
[ ] Test de restauration effectué et validé
[ ] Procédure de restauration documentée

SÉCURITÉ
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[ ] Tous les mots de passe par défaut changés
[ ] Mots de passe forts pour SYS, SYSTEM, DBSNMP
[ ] Comptes inutilisés verrouillés
[ ] Audit configuré pour les opérations sensibles
[ ] Permissions des fichiers correctement configurées
[ ] Accès SSH sécurisé (clés, pas de root direct)

MONITORING
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[ ] Scripts de monitoring déployés
[ ] Alertes configurées (email/SMS)
[ ] Dashboard pour visualisation de l'état
[ ] Logs centralisés et analysés régulièrement
[ ] Procédures d'escalade définies

DOCUMENTATION
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[ ] Architecture documentée (diagramme)
[ ] Inventaire des serveurs et disques
[ ] Configuration détaillée (paramètres, disk groups, etc.)
[ ] Runbooks pour les opérations courantes
[ ] Plan de disaster recovery
[ ] Contacts d'urgence à jour

TESTS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[ ] Test de charge (simuler la charge de production)
[ ] Test de failover (panne de disque simulée)
[ ] Test de redémarrage après crash
[ ] Test de restauration complète
[ ] Test de point-in-time recovery
[ ] Test de basculement réseau
[ ] Validation des performances

FORMATION
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[ ] Équipe DBA formée sur ASM et Oracle 19c
[ ] Équipe ops formée sur les procédures de base
[ ] Documentation accessible à tous
[ ] Simulation d'incidents avec l'équipe


═══════════════════════════════════════════════════════════════════════════════
10.4 COMMANDES DE RÉFÉRENCE RAPIDE
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│                    COMMANDES ESSENTIELLES - QUICK REFERENCE                │
└────────────────────────────────────────────────────────────────────────────┘

COMMANDES 'grid' (Infrastructure ASM)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

# État d'Oracle Restart
crsctl check crs                    # Vérifier tous les composants
crsctl stat res -t                  # Vue d'ensemble de toutes les ressources

# Gestion ASM
srvctl start asm                    # Démarrer ASM
srvctl stop asm                     # Arrêter ASM
srvctl status asm                   # État d'ASM

# Gestion du listener
lsnrctl start                       # Démarrer le listener
lsnrctl stop                        # Arrêter le listener
lsnrctl status                      # État du listener
lsnrctl reload                      # Recharger la configuration
srvctl start listener               # Via Oracle Restart
srvctl stop listener                # Via Oracle Restart

# Se connecter à ASM
sqlplus / as sysasm

# ASMCMD (navigation dans ASM)
asmcmd                              # Lancer ASMCMD
  pwd                               # Répertoire courant
  cd /DATA                          # Changer de répertoire
  ls                                # Lister fichiers/répertoires
  ls -l                             # Liste détaillée
  lsdg                              # Lister les disk groups
  lsdsk                             # Lister les disques
  du                                # Utilisation de l'espace
  md_backup /path/backup.txt        # Sauvegarder métadonnées


COMMANDES SQL POUR ASM (en tant que SYSASM)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

-- État des disk groups
SELECT name, state, type, total_mb, free_mb, offline_disks 
FROM v$asm_diskgroup;

-- État des disques
SELECT name, path, mode_status, state, total_mb, free_mb 
FROM v$asm_disk 
ORDER BY name;

-- Opérations en cours (rebalance, etc.)
SELECT * FROM v$asm_operation;

-- Clients connectés à ASM
SELECT instance_name, db_name, status FROM v$asm_client;

-- Fichiers dans ASM
SELECT name, type, bytes/1024/1024 AS size_mb 
FROM v$asm_file 
WHERE group_number = 1;

-- Créer un disk group
CREATE DISKGROUP data NORMAL REDUNDANCY
  DISK '/dev/oracleasm/disk1',
       '/dev/oracleasm/disk2',
       '/dev/oracleasm/disk3';

-- Ajouter un disque
ALTER DISKGROUP data ADD DISK '/dev/oracleasm/disk4';

-- Retirer un disque
ALTER DISKGROUP data DROP DISK data_0003;

-- Monter/Démonter
ALTER DISKGROUP data MOUNT;
ALTER DISKGROUP data DISMOUNT;


COMMANDES 'oracle' (Base de données)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

# Gestion de la base
srvctl start database -d ORCL       # Démarrer la base
srvctl stop database -d ORCL        # Arrêter la base
srvctl status database -d ORCL      # État de la base

# Se connecter à la base
sqlplus / as sysdba

# Variables d'environnement
export ORACLE_SID=ORCL
export ORACLE_HOME=/u01/app/oracle/product/19.3.0/dbhome_1
export PATH=$ORACLE_HOME/bin:$PATH


COMMANDES SQL POUR LA BASE DE DONNÉES (en tant que SYSDBA)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

-- État de l'instance
SELECT instance_name, status, database_status FROM v$instance;

-- Mode d'ouverture
SELECT name, open_mode, log_mode FROM v$database;

-- Emplacement des fichiers
SELECT name FROM v$datafile;
SELECT member FROM v$logfile;
SELECT name FROM v$controlfile;

-- Utilisation des tablespaces
SELECT tablespace_name, 
       ROUND(SUM(bytes)/1024/1024, 2) AS size_mb,
       COUNT(*) AS files
FROM dba_data_files
GROUP BY tablespace_name;

-- Sessions actives
SELECT sid, serial#, username, status, program 
FROM v$session 
WHERE username IS NOT NULL;

-- Arrêter/Démarrer
SHUTDOWN IMMEDIATE;
STARTUP;

-- Passer en mode ARCHIVELOG
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE OPEN;


COMMANDES RMAN (Sauvegardes)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

# Lancer RMAN
rman target /

# Sauvegardes
BACKUP DATABASE;                           # Sauvegarde complète
BACKUP DATABASE PLUS ARCHIVELOG;           # Avec archived logs
BACKUP INCREMENTAL LEVEL 0 DATABASE;       # Incrémentielle niveau 0
BACKUP INCREMENTAL LEVEL 1 DATABASE;       # Incrémentielle niveau 1
BACKUP ARCHIVELOG ALL DELETE INPUT;        # Archived logs puis suppression

# Lister les sauvegardes
LIST BACKUP SUMMARY;
LIST BACKUP BY FILE;
LIST ARCHIVELOG ALL;

# Restauration
RESTORE DATABASE;
RECOVER DATABASE;
ALTER DATABASE OPEN RESETLOGS;

# Point-in-time recovery
RESTORE DATABASE;
RECOVER DATABASE UNTIL TIME "TO_DATE('2024-12-20 14:29:00', 'YYYY-MM-DD HH24:MI:SS')";
ALTER DATABASE OPEN RESETLOGS;

# Maintenance
DELETE OBSOLETE;                           # Supprimer anciennes sauvegardes
VALIDATE DATABASE;                         # Valider l'intégrité
CROSSCHECK BACKUP;                         # Vérifier les backups


FICHIERS IMPORTANTS (Logs et Configuration)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

# Alert logs
tail -f /u01/app/grid/diag/asm/+asm/+ASM/trace/alert_+ASM.log
tail -f /u01/app/oracle/diag/rdbms/orcl/ORCL/trace/alert_ORCL.log

# Listener log
tail -f /u01/app/grid/diag/tnslsnr/$(hostname)/listener/alert/log.xml

# Fichiers de configuration
/u01/app/19.3.0/grid/network/admin/listener.ora
/u01/app/oracle/product/19.3.0/dbhome_1/network/admin/tnsnames.ora
/etc/oratab


═══════════════════════════════════════════════════════════════════════════════
10.5 GLOSSAIRE DES TERMES
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│                    GLOSSAIRE - TERMES ESSENTIELS                           │
└────────────────────────────────────────────────────────────────────────────┘

A
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ALLOCATION UNIT (AU)
  Plus petite unité d'allocation dans ASM. Typiquement 1, 4, 8, ou 64 MB.
  Les fichiers sont découpés en extents multiples d'AU.

ARCHIVELOG
  Mode de fonctionnement où les redo logs remplis sont archivés.
  Permet la récupération point-in-time. Opposé : NOARCHIVELOG.

ASM (Automatic Storage Management)
  Gestionnaire de stockage intégré à Oracle qui virtualise les disques
  et fournit mirroring, striping et gestion automatique de l'espace.

ASMCMD
  Utilitaire en ligne de commande pour naviguer dans l'arborescence ASM.
  Similaire aux commandes Unix (ls, cd, pwd, etc.).

ASMSNMP
  Compte utilisé par Oracle Enterprise Manager pour surveiller ASM.


C
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
CONTROL FILE
  Fichier binaire qui contient les métadonnées de la base de données.
  Critique : sans lui, la base ne peut pas démarrer.

CRS (Cluster Ready Services)
  Composant d'Oracle Restart qui gère le démarrage/arrêt automatique
  des ressources (ASM, databases, listeners).


D
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
DATAFILE
  Fichier physique qui contient les données d'un tablespace.

DBCA (Database Configuration Assistant)
  Outil Oracle pour créer, modifier ou supprimer des bases de données.
  Peut fonctionner en mode graphique ou silencieux.

DISK GROUP
  Pool logique de disques gérés par ASM. Similaire à un volume LVM.
  Exemples : DATA, FRA, TEMP.


E
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
EXTENT
  Unité d'allocation contiguë. Dans ASM, un extent = 1 AU pour les
  premiers 20 000 extents, puis augmente (4 AU, 16 AU, etc.).

EXTERNAL REDUNDANCY
  Pas de mirroring par ASM. L'utilisateur doit fournir la redondance
  via le stockage sous-jacent (RAID hardware).


F
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
FAST RECOVERY AREA (FRA)
  Zone dédiée pour les backups, archived logs et flashback logs.
  Simplifie la gestion des fichiers de récupération.


G
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
GRID INFRASTRUCTURE
  Couche logicielle qui fournit ASM, Oracle Restart, et (en RAC) le
  clustering. Installée avant la base de données.


H
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
HIGH REDUNDANCY
  Triple mirroring. Nécessite 3 failure groups minimum.
  Tolère la perte de 2 disques. Capacité utilisable = 33%.


L
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
LISTENER
  Processus réseau qui écoute les demandes de connexion et les
  transfère à l'instance appropriée. Port par défaut : 1521.


N
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
NORMAL REDUNDANCY
  Double mirroring (2-way mirroring). Nécessite 2 failure groups minimum.
  Tolère la perte d'1 disque. Capacité utilisable = 50%.


O
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ORACLE_BASE
  Répertoire racine pour les fichiers Oracle (données, logs, config).
  Exemple : /u01/app/oracle

ORACLE_HOME
  Répertoire contenant les binaires Oracle (exécutables, librairies).
  Exemple : /u01/app/oracle/product/19.3.0/dbhome_1

ORACLE RESTART
  Fonction de haute disponibilité pour serveurs standalone.
  Redémarre automatiquement ASM, databases et listeners en cas de crash.


P
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PITR (Point-In-Time Recovery)
  Récupération de la base à un instant précis dans le passé.
  Nécessite mode ARCHIVELOG et sauvegardes RMAN.


R
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
REBALANCE
  Opération automatique d'ASM pour redistribuer équitablement les
  données après ajout ou retrait de disques.

REDO LOG
  Fichier circulaire qui enregistre toutes les modifications de la base.
  Critique pour la récupération en cas de crash.

RMAN (Recovery Manager)
  Outil Oracle pour sauvegarder, restaurer et récupérer les bases de
  données. Supporte compression, encryption, incrémental, etc.


S
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
SPFILE (Server Parameter File)
  Fichier binaire contenant les paramètres d'initialisation de l'instance.
  Peut être stocké sur ASM. Opposé : PFILE (texte).

STRIPING
  Technique de répartition des données sur plusieurs disques.
  COARSE = larges bandes (1 AU), FINE = petites bandes (128 KB).

SYSASM
  Privilège pour administrer ASM. Séparé de SYSDBA (administration DB).


T
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
TABLESPACE
  Division logique de la base de données. Contient des objets (tables,
  index). Stocké dans un ou plusieurs datafiles.

TEMPFILE
  Fichier temporaire utilisé pour les opérations de tri et autres
  opérations temporaires. Appartient au tablespace TEMP.


U
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
UDEV
  Gestionnaire de périphériques Linux. Utilisé pour créer des liens
  symboliques persistants vers les disques ASM.


═══════════════════════════════════════════════════════════════════════════════
10.6 RESSOURCES ADDITIONNELLES ET LIENS UTILES
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│                    RESSOURCES POUR ALLER PLUS LOIN                         │
└────────────────────────────────────────────────────────────────────────────┘

DOCUMENTATION OFFICIELLE ORACLE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Oracle Database 19c Documentation
https://docs.oracle.com/en/database/oracle/oracle-database/19/

ASM Administrator's Guide
https://docs.oracle.com/en/database/oracle/oracle-database/19/ostmg/

Grid Infrastructure Installation Guide for Linux
https://docs.oracle.com/en/database/oracle/oracle-database/19/cwlin/

Database Backup and Recovery User's Guide (RMAN)
https://docs.oracle.com/en/database/oracle/oracle-database/19/bradv/

Real Application Clusters Administration and Deployment Guide
https://docs.oracle.com/en/database/oracle/oracle-database/19/racad/


FORUMS ET COMMUNAUTÉS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Oracle Community Forums
https://community.oracle.com/

Oracle-Base (Tutoriels et articles)
https://oracle-base.com/

AskTOM (Questions/Réponses d'experts Oracle)
https://asktom.oracle.com/

Stack Overflow - Oracle Tag
https://stackoverflow.com/questions/tagged/oracle


BLOGS ET SITES SPÉCIALISÉS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

OraFAQ - Oracle FAQ
http://www.orafaq.com/

Oracle Learning Library
https://apexapps.oracle.com/pls/apex/f?p=44785:1

Brent Ozar (Performance Tuning)
https://www.brentozar.com/

Quest's Toad World
https://www.toadworld.com/


OUTILS UTILES
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

SQL Developer
  IDE gratuit d'Oracle pour développer et administrer les bases
  https://www.oracle.com/database/sqldeveloper/

Oracle Enterprise Manager (OEM)
  Console web complète pour gérer Oracle (payant)
  https://www.oracle.com/enterprise-manager/

DBeaver
  IDE universel open-source (supporte Oracle)
  https://dbeaver.io/

SQL*Plus
  Client en ligne de commande (inclus avec Oracle)


CERTIFICATIONS ORACLE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Pour valider tes compétences officiellement :

Oracle Certified Associate (OCA)
  Niveau débutant, couvre les bases de SQL et d'administration

Oracle Certified Professional (OCP)
  Niveau intermédiaire, administration avancée
  OCP 19c Database Administration

Oracle Certified Master (OCM)
  Niveau expert, examen pratique de 2 jours

Plus d'infos :
https://education.oracle.com/oracle-certification-path


LIVRES RECOMMANDÉS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

"Oracle Database 12c DBA Handbook" by Bob Bryla, Kevin Loney
  Bible de l'administration Oracle (applicable à 19c)

"Expert Oracle Database Architecture" by Thomas Kyte
  Architecture interne approfondie

"Oracle RMAN Pocket Reference" by Darl Kuhn
  Guide de poche pour RMAN


═══════════════════════════════════════════════════════════════════════════════
10.7 CONCLUSION
═══════════════════════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────────────────────┐
│                           FÉLICITATIONS !                                  │
└────────────────────────────────────────────────────────────────────────────┘

Tu es arrivé au terme de ce guide exhaustif sur Oracle ASM 19c !

Au cours de ces 10 parties, tu as parcouru un chemin complet :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

[OK] Tu as COMPRIS l'architecture ASM et ses avantages
[OK] Tu as PRÉPARÉ un serveur Ubuntu pour héberger Oracle
[OK] Tu as INSTALLÉ Grid Infrastructure et Oracle Database 19c
[OK] Tu as CRÉÉ et GÉRÉ des disk groups avec redondance
[OK] Tu as CONFIGURÉ des sauvegardes automatiques avec RMAN
[OK] Tu as PRATIQUÉ des scénarios réels de production
[OK] Tu MAÎTRISES les opérations quotidiennes d'administration


TU ES MAINTENANT CAPABLE DE :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

-> Installer une infrastructure Oracle complète de A à Z
-> Gérer le stockage ASM de manière autonome
-> Effectuer des sauvegardes et restaurations
-> Diagnostiquer et résoudre les problèmes courants
-> Mettre en place une base de données en production
-> Assurer la haute disponibilité avec Oracle Restart
-> Récupérer après des pannes matérielles ou des pertes de données


LE CHEMIN NE S'ARRÊTE PAS LÀ
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Ce guide t'a donné des FONDATIONS SOLIDES, mais le monde Oracle est vaste :

PROCHAINES ÉTAPES SUGGÉRÉES :

1. PRATIQUER, PRATIQUER, PRATIQUER
   -> Monte un lab personnel (VM VirtualBox/VMware)
   -> Casse des choses, restaure-les, apprends de tes erreurs
   -> Reproduis les scénarios de ce guide plusieurs fois

2. APPROFONDIR tes connaissances
   -> Performance tuning (AWR, ASH, SQL Tuning)
   -> Data Guard (haute disponibilité avec standby database)
   -> RAC (Real Application Clusters) pour clustering multi-nœuds
   -> Multitenant architecture (Container Database + PDBs)

3. OBTENIR une CERTIFICATION
   -> OCA Database SQL -> OCP Database Administration
   -> Valide officiellement tes compétences

4. PARTICIPER à la COMMUNAUTÉ
   -> Pose des questions sur les forums
   -> Partage tes solutions et expériences
   -> Contribue à des projets open-source

5. RESTER À JOUR
   -> Oracle sort régulièrement des patches et updates
   -> Suis les blogs et newsletters Oracle
   -> Teste les nouvelles fonctionnalités (Oracle 21c, 23c...)


UN DERNIER CONSEIL
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

L'administration Oracle est un ART qui s'affine avec l'EXPÉRIENCE.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Ne te décourage pas si quelque chose ne fonctionne pas du premier coup.
Les meilleurs DBAs sont ceux qui ont :
  • Cassé des bases (dans un environnement de test !)
  • Passé des nuits blanches à déboguer
  • Appris de chaque erreur
  • Développé leur intuition au fil des années

Chaque problème résolu est une VICTOIRE.
Chaque base restaurée avec succès est une FIERTÉ.
Chaque uptime record est un ACCOMPLISSEMENT.


TU AS MAINTENANT LES OUTILS ET LES CONNAISSANCES.
À toi de jouer !


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                        BONNE CHANCE DANS TON AVENTURE ORACLE !
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Si tu as des questions ou des retours sur ce guide, n'hésite pas à :
  • Consulter la documentation officielle Oracle
  • Poser des questions sur les forums communautaires
  • Continuer à pratiquer et expérimenter

Merci d'avoir suivi ce guide jusqu'au bout.
Tu es maintenant armé pour gérer Oracle ASM en production !

                                                            -- L'équipe DBA


################################################################################
#                                                                              #
#                             FIN DU GUIDE                                     #
#                   Oracle ASM 19c sur Ubuntu - Guide Complet                  #
#                                                                              #
#                           Décembre 2024                                      #
#                                                                              #
################################################################################