[Oracle] Créer un clone de base instantané en lecture/écriture avec ACFS Snapshot

Introduit avec la version 11g, Oracle ACFS est un système de fichiers développé par Oracle et s’appuyant sur ASM. Il introduit d’intéressantes fonctionnalités comme, entre autres, la réplication asynchrone de système de fichiers ou la création de Snapshots en Lecture/écriture. C’est cette dernière fonctionnalité évoquée qui est ici abordée.

Si vous souhaitez créer un clone temporaire de vos bases de production à des fins de tests ou de reporting, les Snapshots ACFS peuvent répondre à votre besoin.

Quels sont les avantages de cette solution

  • Le clone est accessible en lecture et en écriture. Cela permet de tester certaines opérations comme par exemple tester la création d’un index sans risquer d’affecter la structure de votre base de production.
  • La base clone occupe un minimum d’espace : En effet, seuls les blocs modifiés sur la base « hôte » et/ou sur le clone occupent de l’espace sur disque.

Quelles sont les limites de cette solution

  • Le clone n’a pas pour vocation de survivre plus de quelques jours : plus la durée de vie du Snapshot est importante, plus la volumétrie devient importante (cela dépend bien sûr du nombre et de la volumétrie des transactions).
  • La charge IO de la base Snapshot se fait sur la base de production. De lourdes transactions peuvent affecter les performances de votre base hôte.

Mise en place

Le principe est simple mais nécessite tout de même quelques actions.
Nous allons créer une base qui « partagera » ses datafiles avec la base hôte au travers d’un Snapshot ACFS.
Seuls « l’écart » (les blocs modifiés sur la base hôte et/ou le Snapshot) occuperont de l’espace sur le système de fichiers ACFS.

1ère étape : Réserver un espace spécifique différent de l’emplacement de ceux de la base hôte

La réservation d’espace est pour :

  • les onlinelogs
  • Les tempfiles
  • Le controlfile
  • Les archivelogs
  • Les fichiers d’audit (le adump)

2ème étape : Générer depuis la base hôte le contrôle file et le fichier d’initialisation qui seront adaptés pour la base Snapshot et dupliquer le fichier de mot de passe

  • Génération du spfile :
    • SQL> create pfile=’/tmp/initSNAP.ora’ from spfile ;
  • Génération du controlfile :
    • SQL> alter database backup controlfile to trace as ‘/tmp/ctl_SNAP.sql’;
  • Adaptation du controlfile depuis le fichier /tmp/ctl_SNAP.sql généré :
    • Adaptez le chemin des datafiles en ajoutant à l’arborescence « […]/.ACFS/snaps/<snap_acfs>/[…]»
    • Adaptez le chemin des onlinelogs vers l’arborescence créée à l’étape 1
    • Modifier la première ligne du create controlfile de la sorte :
      CREATE CONTROLFILE SET DATABASE « <base_snap> » RESETLOGS …
  • Adaptation du pfile depuis le fichier /tmp/initSNAP.ora généré :
    • Supprimer la ligne relative au(x) controlfile(s)
    • Adapter le chemin du adump
    • Adapter toutes les références au nom de la base hôte avec le nom de la base Snapshot
  • Copier depuis le répertoire dbs le fichier de mot de passe de la base hôte pour la base Snapshot :
    • cp <ORACLE_HOME>/dbs/orapw<base_hote> <ORACLE_HOME>/dbs/orapw<base_snap>

3ème étape : Créer le Snapshot ACFS

  • La base hôte doit être « figée » en écriture le temps de la création du Snaphot ACFS; pour cela, elle est passée en begin backup :
    • SQL> alter database begin backup ;
  • A cette étape, on crée le Snapshot depuis la commande suivante :
    • $ /sbin/acfsutil snap create -w <snap_acfs> <arborescence_a_snaper>
    • La commande est quasiment instantanée
  • La base est repassée en mode nominal :
    • SQL> alter database end backup ;
  • On force ensuite un checkpoint et un switchlog pour créer un point de consistance de la base qui sera utilisé pour le recover du Snapshot

4ème étape : Création de la base base Snapshot

  • Après avoir positionné la variable ORACLE_SID :
    • $export ORACLE_SID=<base_snap>
  • On se connecte à SqlPlus et génère le spfile :
    • SQL> create spfile from pfile=’/tmp/initSNAP.ora’;
  • On démarre la base en nomount :
    • SQL> startup nomount
  • On créé le controlfile de la base Snapshot depuis le script /tmp/ctl_SNAP.sql qui a été adapté :
    • SQL > CREATE CONTROLFILE SET DATABASE …

5ème étape : Avant d’ouvrir la base Snapshot, il faut lui trouver un point de consistance

  • Pour cela, on utilise rman pour référencer les derniers archivelogs générés que l’on aura préalablement copié :
    • RMAN> catalog start with ‘<arborescence_archivelogs_base_snap>’;
  • Puis pour effectuer un recover jusqu’au checkpoint :
    • RMAN> recover automatic database until time ‘<date_et_heure_du_checkpoint>’ using backup controlfile;
  • On ouvre ensuite la base en mode resetlogs :
    • SQL> alter database open resetlogs ;
  • On re-créz les tempfiles dans l’arborescence dédiée à la base Snapshot :
    • SQL> Alter tablespace <TBS_TEMP> add tempfile ‘<arborescence/tempfile.tmp>’ ;

6ème et dernière étape : On rend la base joignable par le listener

  • Dans cet exemple on crée un service avec srvctl
    • $ srvctl add database -db <base_snap> -oraclehome <ORACLE_HOME>
    • $ srvctl add service -db <base_snap> -service <base_snap>

 

Enfin, si vous voulez contrôler l’espace occupé par le Snapshot ACFS, la commande suivante répondra à votre besoin :
$ /sbin/acfsutil snap info <arborescence_snapée>

 

Même si la mise en place peut paraitre un peu fastidieuse, elle s’appuie principalement sur des actions d’administration courantes.

Elle s’applique particulièrement aux « grosses » bases que l’on ne veut pas entièrement répliquer pour des raisons de temps et de place.

Cette démarche à été testée sur une base en single tenant (avec un container et une pluggable database) et s’applique donc à une base multitenants. (Attention tout de même, le Snapshot concernera toutes les bases pluggable).

Si vous ne désirez cloner qu’une pluggable database au sein d’un container, il faudra préférer une autre méthode plus simple (non basée sur un Snapshot ACFS) avec un « CREATE PLUGGABLE DATABASE … SNAPSHOT … » à condition, bien sur, que vous ayez une licence vous permettant de faire du multitenants.