Créer une base RAC à la main en ligne de commande

Je me suis récemment trouvé dans une situation où mon cluster et son ASM étaient sains, mais pas moyen de créer des bases 10g avec dbca, celui-ci rejetant diverses erreurs de listener, et même si l’ajout d’entrées plastron dans tnsnames.ora permettait à la base d’être créée, pas moyen de modifier après des paramètres tels que le local_listener, la commande

alter system set local_listener=srvdb1.easyteam.fr scope=both sid=prda1

s’exécutait sans problème mais un :

show parameter local_listener

renvoyait toujours l’ancienne valeur ! J’ai donc fait 3615 – ArKZoYd à la rescousse qui me dit « C’est simple, tu va créer une base mono-instance en ligne de commande et la convertir en RAC« ,
Mais bien sûr….Donc au menu nous créons :

  • Un fichier de de mot passe
  • Un tnsnames.ora
  • Un pfile simplifié
  • L’arborescence ASM
  • La base
  • Son catalogue

Puis nous :

  • Convertissons l’instance en cluster
  • Ajoutons le service

Elementary, my Dear Watson! Donc dans le détail, nous avons notre cluster 2 noeuds composé de srvdb1 et srvdb2 devant  héberger 2 bases PRDA et PRDB en cluster. Les instructions qui suivent sont pour la première base PRDA, il suffira de les répéter pour faire la deuxième PRDB. Même si ces opérations ont été effectuées en 10g, les principes sont transposable à du 11g.

Le fichier de mot de passe

On se place dans le dossier $ORACLE_HOME/dbs là où l’on trouve les fichiers init et de mot de passe, tels que ceux d’ASM qui sont déjà là:

orapwd file=orapwPRDA password=oracle1 entries=10

L’utilitaire orapwd va créer un fichier contenant jusqu’à 10 mots de passe de la base BEEDBA, en particulier le mot de passe de SYS qui est oracle1.

Un tnsnames.ora

Dans le dossier $ORACLE_HOME/network/admin, on crée un fichier tnsnames.ora contenant:

LISTENER_PRDA1=
(DESCRIPTION=
(ADDRESS = (PROTOCOL = TCP)(HOST = srvdb1.easyteam.fr)(PORT = 1521))
)
LISTENER_PRDA2=
(DESCRIPTION=
(ADDRESS = (PROTOCOL = TCP)(HOST = srvdb2.easyteam.fr)(PORT = 1521))
)
LISTENERS_PRDA
(DESCRIPTION=
(ADDRESS = (PROTOCOL = TCP)(HOST = srvdb1.easyteam.fr)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = srvdb1.easyteam.fr)(PORT = 1521))
)

Un pfile simplifié

Dans le dossier $ORACLE_HOME/dbs créer le fichier initPRDA1.ora permettant de lancer la première instance:

compatible=10.2.0.4.0
control_files=(+DATA01/PRDA/CONTROLFILES/control01.dbf,+DATA01/PRDA/CONTROLFILES/control02.dbf,+DATA02/PRDA/CONTROLFILES/control03.dbf)
db_name=PRDA
db_block_size=8192
db_create_file_dest=+DATA01
db_recovery_file_dest=+DATA02
db_recovery_file_dest_size=10G
open_cursors=1000
pga_aggregate_target=300M
processes=500
sga_target=500M
remote_login_passwordfile=EXCLUSIVE
undo_management=AUTO
undo_tablespace=UNDOTBS1

L’arborescence ASM

Vous aurez remarqué juste au dessus que l’on précise les Diskgroups ASM devant héberger les données, la flash recovery area et les control files ; il faudra créer cette arborescence à la main car les processus Oracle n’en sont pas capable au lancement de l’instance. Donc on passe en environnement ASM:

. oraenv
+ASM1

On lance asmcmd

asmcmd

On crée les dossiers dans les 2 diskgroups:

cd DATA01
mkdir PRDA
cd PRDA
mkdir CONTROLFILES
cd .. cd ..
cd DATA02
mkdir PRDA
cd PRDA
mkdir CONTROLFILES

La base

On est prêt à créer la base ; on positionne les variables d’environnement en particulier le ORACLE_SID à celui de la future instance :

export ORACLE_SID=PRDA1
sqlplus / as sysdba
startup nomount pfile='$ORACLE_HOME/dbs/initPRDA1.ora'
  • On est connecté à une ‘idle instance’ car rien n’est lancé, donc on crée la base dans la session sqlplus
create database PRDA
character set AL32UTF8
extent management local
sysaux datafile size 600M
default tablespace users datafile size 20M
default temporary tablespace temp tempfile size 100M
undo tablespace UNDOTBS1 datafile size 200M

Son catalogue

Toujours dans la session sqlplus, nous allons ajouter à la base nouvellement créer les composants minimum:

  • Le dictionnaire
@?/rdbms/admin/catalog
  • Les procédures
@?/rdbms/admin/catproc
  • La recompilation et les composants cluster
@?/rdbms/admin/utlrp
@?/rdbms/admin/catclust
  • Le fichier d’init spfile
create spfile='+DATA01/PRDA/spfilePRDA.ora' from pfile;
  • Sortir de la session sqlplus et modifier le pfile créé ci-dessus et remplacer son contenu par :
 spfile=+DATA01/PRDA/spfilePRDA.ora
  • A ce stade nous pouvons démarrer la base et vérifier que tout a été créé au bon endroit :
sqlplus / as sysdba
startup
show parameter spfile
select file_name from dba_data_files;
select member from v$logfile;

Convertion de l’instance en cluster

  • Créer un fichier /etc/oratab ajouter la ligne
PRDA:/u01/app/oracle/product/10.2.0/db:N
  • Modifier paramètres dans spfile
alter system set cluster_database=true scope=spfile;
alter system set cluster_database_instances=2 scope=spfile;
alter system set local_listener=LISTENER_PRDA1 scope=spfile sid='PRDA1';
alter system set local_listener=LISTENER_PRDA2 scope=spfile sid='PRDA2';
alter system set undo_tablespace=UNDOTBS1 scope=spfile sid='PRDA1';
alter system set undo_tablespace=UNDOTBS2 scope=spfile sid='PRDA2';
create undo tablespace UNDOTBS2 datafile size 200M;
alter system set thread=1 scope=spfile sid='PRDA1';
alter system set thread=2 scope=spfile sid='PRDA2';
alter database add logfile thread 2 group 3;
alter database add logfile thread 2 group 4;
alter database enable public thread 2;
alter system set instance_number=1 scope=spfile sid='PRDA1';
alter system set instance_number=2 scope=spfile sid='PRDA2';
  • Et on redémarre la base (shutdown abort + startup)
startup force
  • On recopie le fichier de mot de passe et le pfile vers l’autre nœud du cluster :
scp orapwPRDA srvdb2:/u01/app/oracle/product/10.2.0/db/dbs/
scp initPRDA1.ora srvdb2:/u01/app/oracle/product/10.2.0/db/dbs/
  • Sur srvdb2, on change le nom du fichier pfile pour correspondre au SID de l’instance sur le deuxième nœud :
mv initPRDA1.ora initPRDA2.ora
  • On crée un lien symbolique pour le fichier de mot de passe :
ln -s orapwPRDA orapwPRDA2
  • Démarrage de la deuxième instance:
export ORACLE_SID=PRDA2
sqlplus / as sysdba
startup pfile='$ORACLE_HOME/dbs/initPRDA2.ora'

Enregistrement cluster

Dans un RAC, tout doit être contrôlé avec srvctl plutôt que des session sqlplus:

srvctl add database –d PRDA –o /u01/app/oracle/product/10.2.0/db –p +DATA01/PRDA/spfilePRDA.ora
srvctl add instance -d PRDA -i PRDA1 -n srvdb1
srvctl add instance -d PRDA -i PRDA2 -n srvdb2

Malgré l’enregistrement, comme l’instance a été démarrée avec sqlplus, elle doit être arrêtée de même, puis redémarrée avec srvctl:

sqlplus / as sysdba
shutdown abort
srvctl start database -d PRDA

On termine avec l’ajout d’un service, ce qui pourrait également être fait avec dbca, notez que l’on favorise le nœud 2 ici:

srvctl add service -d PRDA -s PRDASRV -r "PRDA2" -a "PRDA1"
srvctl start service -d PRDA -s PRDASRV

Et bien sur en ajoutant l’entrée TNS correspondante dans le $ORACLE_HOME/network/admin/tnsnames.ora:

PRDASRV =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = srvdb1-vip.easyteam.fr)(PORT = 1521))
    (ADDRESS = (PROTOCOL = TCP)(HOST = srvdb2-vip.easyteam.fr)(PORT = 1521))
    (LOAD_BALANCE = yes)
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = PRDASRV)
      (FAILOVER_MODE =
        (TYPE = SELECT)
        (METHOD = BASIC)
        (RETRIES = 180)
        (DELAY = 5)
      )
    )
  )

La base est maintenant prête à recevoir ses schémas applicatifs. Pour créer la deuxième base PRDB, nous avons repris les même étapes, en nous offrant même le luxe d’un listener séparé sur le port 1522!