Activer le failover au niveau client JDBC ou OCI avec Oracle DataGuard

Oracle DataGuard est une solution de réplication à chaud d’une base de données Oracle fournie gratuitement avec l’édition Enterprise. Cette solution permet de disposer d’une base de données de secours répliquée de façon synchrone ou asynchrone avec une ba
Jérôme POUSSINEAUMis à jour le 10 Sept 2012

Oracle DataGuard est une solution de réplication à chaud d’une base de données Oracle fournie gratuitement avec l’édition Enterprise. Cette solution permet de disposer d’une base de données de secours répliquée de façon synchrone ou asynchrone avec une bascule manuelle ou automatique.

Après un switchover ou failover de la base Primary vers la base Standby réalisé avec Oracle DataGuard il est nécessaire de faire une migration au niveau du ou des clients Oracle pour faire pointer les applicatifs vers la nouvelle base de données Primary. Une solution de contournement est d’;utiliser la notion de SERVICE_NAME Oracle.

En utilisant un client Oracle OCI, il faut modifier le tnsnames.ora de la sorte:


####### TNSNAMES CLIENTS OCI #######
      
ORCLPRIM=(DESCRIPTION=(ADDRESS_LIST=
      
(LOAD_BALANCE=OFF)
      
(FAILOVER=ON)
      
  (ADDRESS=(PROTOCOL=TCP)(HOST=MASTER)(PORT=1521))
      
  (ADDRESS=(PROTOCOL=TCP)(HOST=SLAVE)(PORT=1521)) )
      
  (CONNECT_DATA=
      
   (SERVICE\_NAME=ORCLPRIM)(INSTANCE\_NAME=ORCL)(GLOBAL_NAME=ORCL))) 

Depuis une connexion JDBC, il est possible d’;utiliser l’;URL JDBC suivante:
      
jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=
      
(LOAD_BALANCE=OFF)
      
(FAILOVER=ON)
      
(ADDRESS=(PROTOCOL=TCP)(PORT=1521)(HOST=MASTER))
      
(ADDRESS=(PROTOCOL=TCP)(PORT=1521)(HOST=SLAVE)))
      
(CONNECT\_DATA=(SERVICE\_NAME=ORCLPRIM)(INSTANCE\_NAME=ORCL)(GLOBAL\_NAME=ORCL))) 

Selon la version d’Oracle, il faudra alors mettre en place des Trigger pour permettre l’;assignation du bon nom de service. Toutes les manipulations suivantes seront faites sur le serveur Primary et donc répliquée automatiquement sur le Standby.

La première étape est de déclarer les noms de service pour les deux états (Primary et Standby):

SQL>execute dbms\_service.create\_service(service\_name=>’ORCLPRIM’,network\_name=>’ORCLPRIM’);
      
SQL>execute dbms\_service.create\_service(service\_name=>’ORCLSTBY’,network\_name=>’ORCLSTBY’); 

Il est ensuite nécessaire de créer un Trigger de type startup permettant de positionner le bon service au démarrage de la base de données.

SQL> CREATE or REPLACE TRIGGER gestion\_service\_name AFTER startup ON DATABASE
      
DECLARE
      
DB\_ROLE V$DATABASE.DATABASE\_ROLE%TYPE;
      
BEGIN
      
SELECT DATABASE\_ROLE INTO DB\_ROLE FROM V$DATABASE;
      
IF DB_ROLE = ’PRIMARY’; THEN
      
DBMS\_SERVICE.START\_SERVICE (’ORCLPRIM’;);
      
ELSIF DB_ROLE = ’PHYSICAL STANDBY’; THEN
      
DBMS\_SERVICE.START\_SERVICE (’ORCLSTBY’;);
      
END IF;
      
END;
      
/ 

Pour vérifier le bon fonctionnement du Triger, il est nécessaire de redémarrer les deux bases puis d’;utiliser la commande SQLLangage permettant de communiquer avec une base de données. suivante:

SQL>show parameter service; 

Attention, dans certains cas au niveau du listener Oracle le nom du service peut être modifié. Par exemple sur mon exemple le service est «ORCLPRIM.0.10.3.5» au lieu de «ORCLPRIM». C’est bien le service name complet qu’il faut utiliser au niveau de l’URLUniform Ressource Locator JDBC ou bien du tnsnames.ora du client OCI.

Pour obtenir le nom du service au niveau du listener Oracle il est possible d’;utiliser la commande suivante:

LSNRCTL>services