Réplication Oracle et basculement de connexion rapide UCP



Parfois, la configuration de l'application Java contient l'adresse IP "principale" du serveur de base de données, qui peut changer, par exemple, dans les cas suivants:



  • Changement contrôlé des rôles de base de données. «Primaire» devient «Veille» et vice versa, «Veille» devient «Primaire». Cette procédure est généralement appelée «basculement».
  • Changement d'urgence du rôle "Standby" en "Primary". Ceci est communément appelé «basculement».


Dans les deux cas, l'application doit non seulement «connaître» l'adresse IP du nouveau serveur «primaire», mais aussi pouvoir y accéder en cas de besoin. Ce qui suit est un guide rapide sur la façon de le faire à l'aide d'Oracle Universal Connection Pool (UCP), ainsi qu'une démonstration de "Switchover".



Pour l'expérience, nous utiliserons:



  • MacBook avec 16 Go de RAM (plus de 8 Go requis pour l'expérience)
  • Boîte virtuelle version 6.1.12
  • 2x machines virtuelles (ci-après VM) avec  CentOS 7 Minimal , chacune ayant

    • 2 processeurs virtuels
    • 2048 Go de RAM (jusqu'à 8 Go temporairement, un à la fois)
    • Disque dur de 40 Go
    • audio désactivé pour éviter une charge du processeur à 100%
  • Base de données Oracle 19c


Suivons ces étapes:



  1. Configurer des machines virtuelles
  2. Installation d'Oracle
  3. Réplication Oracle
  4. Installation et configuration d'Oracle Grid
  5. "Switchover" Java








Nous créons des machines virtuelles (ci-après dénommées VM) avec le type Linux Red Hat, start. Lorsque Virtual Box démarre, il vous invite à sélectionner l'iso à partir duquel démarrer la VM (dans l'expérience, CentOS-7-x86_64-Minimal-1908.iso est utilisé). Laissez tout par défaut, redémarrez, mettez à jour, installez "Virtual Box Guest Additions", désactivez firewalld pour qu'il ne vous gêne pas. «Tout le monde sait comment le polish est effacé», donc nous notons seulement qu'après la mise à jour des VM, nous faisons passer leurs interfaces réseau de l'adaptateur NAT à «l'adaptateur d'hôte virtuel» vboxnet0. Pour cet adaptateur, qui peut être créé dans les outils Virtual Box, définissez manuellement l'adresse 192.168.56.1/24 et désactivez DHCP. Fondamentalement, il s'agit de l'adresse IP de la passerelle par défaut pour les VM et de l'adresse de l'application Java. Juste pour plus de clarté. Et si vous avez toujours besoin d'Internet sur CentOS,alors vous pouvez activer NAT sur macOS:



  1. Passez à la racine en utilisant la commande 'sudo su -'.
  2. Autorisez la redirection du trafic à l'aide de la commande 'sysctl -w net.inet.ip.forwarding = 1'.
  3. Ajoutez le contenu du fichier /etc/pf.conf au fichier /var/root/pfnat.conf, dans lequel, au lieu de la ligne 3, insérez la règle NAT:

    nat sur enX de vboxnet0: réseau vers n'importe quel -> (enX)


    où enX est le nom de l'interface réseau avec la route par défaut.
  4. Exécutez la commande 'pfctl -f pfnat.conf -e' pour mettre à jour les règles de filtrage de paquets.


Les étapes 2 à 4 peuvent être exécutées en une seule commande.
sysctl -w net.inet.ip.forwarding=1 \
 && grep -v -E -e '^#.*' -e '^$' /etc/pf.conf | head -n2 > pfnat.conf \
 && INET_PORT=$(netstat -nrf inet | grep default | tr -s ' ' | cut -d ' ' -f 4) \
 && echo "nat on ${INET_PORT} from vboxnet0:network to any -> (${INET_PORT})" >> pfnat.conf \
 && grep -v -E -e '^#.*' -e '^$' /etc/pf.conf | tail -n+3 >> pfnat.conf \
 && pfctl -f pfnat.conf -e




Ajoutez des entrées uniformes à / etc / hosts de toutes les VM afin qu'elles puissent se «pinguer» les unes les autres par noms de domaine.



127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.56.78 oracle1.localdomain oracle1
192.168.56.79 oracle2.localdomain oracle2




Installation d'Oracle





Nous effectuons une installation "Logiciel uniquement" sur oracle1 et oracle2 à l'  aide de packages rpm , le répertoire avec lequel peut être partagé depuis MacOS via Virtual Box (Machine-> Paramètres-> Dossier partagé).



yum -y localinstall oracle-database-preinstall-19c-1.0-1.el7.x86_64.rpm


yum -y localinstall oracle-database-ee-19c-1.0-1.x86_64.rpm


Ensuite, nous créons une instance de SGBD sur la VM "oracle1". Pour ce faire, exécutez le script correspondant sous l'utilisateur oralce.



/etc/init.d/oracledb_ORCLCDB-19c configure


Cette procédure prend un certain temps. Après avoir créé une instance sur les deux hôtes, ajoutez ces lignes au fichier /home/oracle/.bash_profile:



export ORACLE_HOME="/opt/oracle/product/19c/dbhome_1"
export ORACLE_BASE="/opt/oracle"
export ORACLE_SID="ORCLCDB"
export PATH=$PATH:$ORACLE_HOME/bin


Eh bien, nous configurons ssh pour plus de commodité, afin que vous puissiez vous connecter immédiatement en tant qu'utilisateur oracle. Nous nous connectons à l'hôte via ssh et nous nous connectons à la base de données sous l'utilisateur oracle.



user@macbook:~$ ssh oracle@oracle1
Last login: Wed Aug 12 16:17:05 2020
[oracle@oracle1 ~]$ sqlplus / as sysdba

SQL*Plus: Release 19.0.0.0.0 - Production on Wed Aug 12 16:19:44 2020
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>


En fait, Oracle. Pour l'expérience, nous devons également configurer la réplication.



Réplication Oracle.







Pour configurer la réplication, nous utiliserons une instruction légèrement mise à jour :



  1. Nous transférons la base de données sur le serveur oracle1 en "Mode Archive". Pour ce faire, exécutez les commandes dans sqlplus:



    SHUTDOWN IMMEDIATE;


    STARTUP MOUNT;


    ALTER DATABASE ARCHIVELOG;


    ALTER DATABASE OPEN;
  2. Sans quitter sqlplus, activez «Forcer la journalisation» sur le serveur oracle1.



    ALTER DATABASE FORCE LOGGING;


    ALTER SYSTEM SWITCH LOGFILE;
  3. Créez des fichiers "redo log" sur le serveur oracle1.

    ALTER DATABASE
          ADD STANDBY LOGFILE
          THREAD 1 GROUP 10 ('/opt/oracle/oradata/ORCLCDB/standby_redo01.log')
          SIZE 209715200;


    ALTER DATABASE
          ADD STANDBY LOGFILE
          THREAD 1 GROUP 11 ('/opt/oracle/oradata/ORCLCDB/standby_redo02.log')
          SIZE 209715200;


    ALTER DATABASE
          ADD STANDBY LOGFILE
          THREAD 1 GROUP 12 ('/opt/oracle/oradata/ORCLCDB/standby_redo03.log')
          SIZE 209715200;


    ALTER DATABASE
          ADD STANDBY LOGFILE
          THREAD 1 GROUP 13 ('/opt/oracle/oradata/ORCLCDB/standby_redo04.log')
          SIZE 209715200;
  4. Activez "FLASHBACK" sur le serveur oracle1, cela ne fonctionnera pas sans lui.

    SQL> hôte

    [oracle @ oracle1 ~] $ mkdir / opt / oracle / recovery_area

    [oracle @ oracle1 ~] $ exit

    SQL> modifier l'ensemble du système db_recovery_file_dest_size = 2g scope = both;

    SQL> modifier l'ensemble du système db_recovery_file_dest = '/ opt / oracle / recovery_area' scope = both;

    SQL> ALTER DATABASE FLASHBACK ON;
  5. Nous activons quelque chose d'automatique sur le serveur oracle1.

    SQL> ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=AUTO;
  6. tnsnames.ora listener.ora oracle1 oracle2 :

    oracle1, $ORACLE_HOME/network/admin/tnsnames.ora
    
    LISTENER_ORCLCDB =
      (ADDRESS = (PROTOCOL = TCP)(HOST = oracle1.localdomain)(PORT = 1521))
    
    ORCLCDB =
      (DESCRIPTION =
        (ADDRESS_LIST =
          (ADDRESS = (PROTOCOL = TCP)(HOST = oracle1.localdomain)(PORT = 1521))
        )
        (CONNECT_DATA =
          (SID = ORCLCDB)
        )
      )
    
    ORCLCDB_STBY =
      (DESCRIPTION =
        (ADDRESS_LIST =
          (ADDRESS = (PROTOCOL = TCP)(HOST = oracle2.localdomain)(PORT = 1521))
        )
        (CONNECT_DATA =
          (SID = ORCLCDB)
        )
      )
    




    oracle1, $ORACLE_HOME/network/admin/listener.ora
    
    LISTENER =
      (DESCRIPTION_LIST =
        (DESCRIPTION =
          (ADDRESS = (PROTOCOL = TCP)(HOST = oracle1.localdomain)(PORT = 1521))
          (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
        )
      )
    
    SID_LIST_LISTENER =
      (SID_LIST =
        (SID_DESC =
          (GLOBAL_DBNAME = ORCLCDB_DGMGRL)
          (ORACLE_HOME = /opt/oracle/product/19c/dbhome_1)
          (SID_NAME = ORCLCDB)
        )
      )
    
    ADR_BASE_LISTENER = /opt/oracle
    




    oracle2, $ORACLE_HOME/network/admin/tnsnames.ora
    
    LISTENER_ORCLCDB =
      (ADDRESS = (PROTOCOL = TCP)(HOST = oracle2.localdomain)(PORT = 1521))
    
    ORCLCDB =
      (DESCRIPTION =
        (ADDRESS_LIST =
          (ADDRESS = (PROTOCOL = TCP)(HOST = oracle1.localdomain)(PORT = 1521))
        )
        (CONNECT_DATA =
          (SID = ORCLCDB)
        )
      )
    
    ORCLCDB_STBY =
      (DESCRIPTION =
        (ADDRESS_LIST =
          (ADDRESS = (PROTOCOL = TCP)(HOST = oracle2.localdomain)(PORT = 1521))
        )
        (CONNECT_DATA =
          (SID = ORCLCDB)
        )
      )
    




    oracle2, $ORACLE_HOME/network/admin/listener.ora
    
    LISTENER =
      (DESCRIPTION_LIST =
        (DESCRIPTION =
          (ADDRESS = (PROTOCOL = TCP)(HOST = oracle2.localdomain)(PORT = 1521))
          (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
        )
      )
    
    SID_LIST_LISTENER =
      (SID_LIST =
        (SID_DESC =
          (GLOBAL_DBNAME = ORCLCDB_STBY_DGMGRL)
          (ORACLE_HOME = /opt/oracle/product/19c/dbhome_1)
          (SID_NAME = ORCLCDB)
        )
      )
    
    ADR_BASE_LISTENER = /opt/oracle
    


  7. oracle1 listener-.

    [oracle@oracle1 ~]$ lsnrctl reload


    [oracle@oracle1 ~]$ lsnrctl status



    LSNRCTL for Linux: Version 19.0.0.0.0 — Production on 15-AUG-2020 08:17:24



    Copyright © 1991, 2019, Oracle. All rights reserved.



    Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oracle1.localdomain)(PORT=1521)))

    STATUS of the LISTENER

    — Alias LISTENER

    Version TNSLSNR for Linux: Version 19.0.0.0.0 — Production

    Start Date 15-AUG-2020 08:09:57

    Uptime 0 days 0 hr. 7 min. 26 sec

    Trace Level off

    Security ON: Local OS Authentication

    SNMP OFF

    Listener Parameter File /opt/oracle/product/19c/dbhome_1/network/admin/listener.ora

    Listener Log File /opt/oracle/diag/tnslsnr/oracle1/listener/alert/log.xml

    Listening Endpoints Summary…

    (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=oracle1.localdomain)(PORT=1521)))

    (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))

    (DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=oracle1.localdomain)(PORT=5500))(Security=(my_wallet_directory=/opt/oracle/admin/ORCLCDB/xdb_wallet))(Presentation=HTTP)(Session=RAW))

    Services Summary…

    Service «ORCLCDB» has 1 instance(s).

    Instance «ORCLCDB», status READY, has 1 handler(s) for this service…

    Service «ORCLCDBXDB» has 1 instance(s).

    Instance «ORCLCDB», status READY, has 1 handler(s) for this service…

    Service «ac8d8d741e3e2a52e0534e38a8c0602d» has 1 instance(s).

    Instance «ORCLCDB», status READY, has 1 handler(s) for this service…

    Service «orclpdb1» has 1 instance(s).

    Instance «ORCLCDB», status READY, has 1 handler(s) for this service…

    The command completed successfully


    ( Data Guard: ORCLCDB_DGMGRL)
    [oracle@oracle1 ~]$ lsnrctl status



    LSNRCTL for Linux: Version 19.0.0.0.0 — Production on 15-AUG-2020 08:17:32



    Copyright © 1991, 2019, Oracle. All rights reserved.



    Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oracle1.localdomain)(PORT=1521)))

    STATUS of the LISTENER

    — Alias LISTENER

    Version TNSLSNR for Linux: Version 19.0.0.0.0 — Production

    Start Date 15-AUG-2020 08:09:57

    Uptime 0 days 0 hr. 7 min. 34 sec

    Trace Level off

    Security ON: Local OS Authentication

    SNMP OFF

    Listener Parameter File /opt/oracle/product/19c/dbhome_1/network/admin/listener.ora

    Listener Log File /opt/oracle/diag/tnslsnr/oracle1/listener/alert/log.xml

    Listening Endpoints Summary…

    (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=oracle1.localdomain)(PORT=1521)))

    (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))

    (DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=oracle1.localdomain)(PORT=5500))(Security=(my_wallet_directory=/opt/oracle/admin/ORCLCDB/xdb_wallet))(Presentation=HTTP)(Session=RAW))

    Services Summary…

    Service «ORCLCDB» has 1 instance(s).

    Instance «ORCLCDB», status READY, has 1 handler(s) for this service…

    Service «ORCLCDBXDB» has 1 instance(s).

    Instance «ORCLCDB», status READY, has 1 handler(s) for this service…

    Service «ORCLCDB_DGMGRL» has 1 instance(s).

    Instance «ORCLCDB», status UNKNOWN, has 1 handler(s) for this service…

    Service «ac8d8d741e3e2a52e0534e38a8c0602d» has 1 instance(s).

    Instance «ORCLCDB», status READY, has 1 handler(s) for this service…

    Service «orclpdb1» has 1 instance(s).

    Instance «ORCLCDB», status READY, has 1 handler(s) for this service…

    The command completed successfully
  8. SYS oracle1.

    SQL> alter user sys identified by "pa_SSw0rd";
  9. oracle2 listener .

    [oracle@oracle2 ~]$ lsnrctl start

    [oracle@oracle2 ~]$ orapwd file=$ORACLE_BASE/product/19c/dbhome_1/dbs/orapwORCLCDB entries=10 password=pa_SSw0rd

    [oracle@oracle2 ~]$ echo "*.db_name='ORCLCDB'" > /tmp/initORCLCDB_STBY.ora

    [oracle@oracle2 ~]$ mkdir -p $ORACLE_BASE/oradata/ORCLCDB/pdbseed

    [oracle@oracle2 ~]$ mkdir -p $ORACLE_BASE/oradata/ORCLCDB/ORCLPDB1

    [oracle@oracle2 ~]$ mkdir -p $ORACLE_BASE/admin/ORCLCDB/adump

    [oracle@oracle2 ~]$ mkdir /opt/oracle/recovery_area

    [oracle@oracle2 ~]$ sqlplus / as sysdba

    SQL> STARTUP NOMOUNT PFILE='/tmp/initORCLCDB_STBY.ora'

    [oracle@oracle2 ~]$ rman TARGET sys/pa_SSw0rd@ORCLCDB AUXILIARY sys/pa_SSw0rd@ORCLCDB_STBY

    RMAN> DUPLICATE TARGET DATABASE FOR STANDBY FROM ACTIVE DATABASE DORECOVER SPFILE SET db_unique_name = 'ORCLCDB_STBY' COMMENT 'Est en veille' NOFILENAMECHECK;
  10. Lancez Data Guard sur les deux serveurs (oracle1 et oracle2).

    SQL> ALTER SYSTEM SET dg_broker_start = true;
  11. Sur le serveur oracle1, connectez-vous à la console de gestion Data Guard et créez une configuration.

    [oracle @ oracle1 ~] $ dgmgrl sys / pa_SSw0rd @ ORCLCDB

    DGMGRL> CRÉER LA CONFIGURATION my_dg_config COMME BASE DE DONNÉES PRIMAIRE EST ORCLCDB L'IDENTIFICATEUR DE CONNEXION EST ORCLCDB;

    DGMGRL> ADD DATABASE ORCLCDB_STBY AS CONNECT IDENTIFIER IS ORCLCDB_STBY MAINTAINED AS PHYSIQUE;

    DGMGRL> activer la configuration;




Ainsi, suite à la création d'un réplica et à l'activation de Data Guard, nous avons l'état suivant:



DGMGRL> show configuration

Configuration - my_dg_config

  Protection Mode: MaxPerformance
  Members:
  orclcdb      - Primary database
    orclcdb_stby - Physical standby database 
      Warning: ORA-16854: apply lag could not be determined

Fast-Start Failover:  Disabled

Configuration Status:
WARNING   (status updated 40 seconds ago)


C'est un mauvais état. Attendons un peu ...



DGMGRL> show configuration

Configuration - my_dg_config

  Protection Mode: MaxPerformance
  Members:
  orclcdb      - Primary database
    orclcdb_stby - Physical standby database 

Fast-Start Failover:  Disabled

Configuration Status:
SUCCESS   (status updated 55 seconds ago)


Maintenant, l'état est bon! Cependant, la réplique est très passive, elle n'accepte pas les requêtes de lecture (OPEN MODE: MOUNTED).



SQL> show pdbs

    CON_ID CON_NAME			  OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
 
	 2 PDB$SEED			  MOUNTED
	 3 ORCLPDB1			  MOUNTED


Rendons le réplica actif pour qu'il accepte les demandes de lecture. Ensuite, nous pourrons, à l'avenir, décharger le serveur avec la base "primaire". C'est ce qu'on appelle «Active Data Guard», ou veille active . Sur le serveur oracle2, exécutez la séquence de commandes suivante dans sqlplus:

alter database 
      recover managed standby database cancel;


alter database open;


alter database 
      recover managed standby database 
      using current logfile 
      disconnect from session;


alter pluggable database all open;


Vous pouvez maintenant lire à partir de la réplique (OPEN MODE: READ ONLY):

SQL> show pdbs;

    CON_ID CON_NAME			  OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
 
	 2 PDB$SEED			  READ ONLY  NO
	 3 ORCLPDB1			  READ ONLY  NO


Et dans la console DataGuard sur le serveur oracle1, tout semble bon:

DGMGRL> show configuration;

Configuration - my_dg_config

  Protection Mode: MaxPerformance
  Members:
  orclcdb      - Primary database
    orclcdb_stby - Physical standby database 

Fast-Start Failover:  Disabled

Configuration Status:
SUCCESS   (status updated 19 seconds ago)


Malgré le fait que nous ayons désormais Data Guard Active, le cluster est encore largement passif. Il ne nous dira toujours pas un mot à nous et à notre incroyable application Java selon laquelle Primary n'est plus Primary. Pour ce faire, un autre service, ONS (Oracle Notification Services), doit être en cours d'exécution sur les serveurs du cluster. Et il semble que l'installation d'Oracle Database ne soit pas suffisante pour exécuter ce service, nous devrons installer Oracle Grid.







Installation et configuration d'Oracle Grid.







Tout est assez simple ici: comme lors de l'installation d'Oracle Database, nous suivrons simplement les instructions officielles .



  1.   oracle1  oracle2 root    Oracle Grid, gcc-c++, oracle   asm.   Virtual Box, Oracle, Oracle Grid    .

    mkdir -p /opt/oracle/product/19c/grid \
            && cp -r /mnt/oracle_grid_19300/LINUX/* /opt/oracle/product/19c/grid/ \
            && chown -R oracle:oinstall /opt/oracle/product/19c/grid


    yum install -y gcc-c++


    groupadd asm && usermod -aG asm oracle


  2. ,   oracle, Oracle Grid.

    cd /opt/oracle/product/19c/grid/ && ./runcluvfy.sh stage -pre hacfg


    Verifying Physical Memory ...FAILED

    Required physical memory = 8GB

    Verifying Swap Size ...FAILED

    Required = 2.6924GB (2823138.0KB); Found = 2GB (2097148.0KB)]



      - ,     swap, Oracle Grid ,   .
  3. oracle2, oracle1.

    SQL> shutdown immediate


    # poweroff
  4. oracle1  8192 ,  VM   swap root.

    dd if=/dev/zero of=/swap_file bs=1G count=7 \
                && chmod 600 /swap_file && mkswap /swap_file \
                && echo '/swap_file  swap  swap  defaults  0 0' >> /etc/fstab \
                && swapoff -a && swapon -a
  5. , , .

    [oracle@oracle1 grid]$ cd /opt/oracle/product/19c/grid/ && ./runcluvfy.sh stage -pre hacfg

    Pre-check for Oracle Restart configuration was successful.


    ! Oracle Grid.
  6. oracle   oracle1  /opt/oracle/product/19c/grid/ grid_configwizard.rsp.

    cd /opt/oracle/product/19c/grid/ && touch grid_configwizard.rsp


    grid_configwizard.rsp , oracle restart, ASM   .

    oracle.install.responseFileVersion=/oracle/install/rspfmt_crsinstall_response_schema_v19.0.0

    INVENTORY_LOCATION=/opt/oracle/oraInventory

    oracle.install.option=CRS_SWONLY

    ORACLE_BASE=/opt/oracle

    oracle.install.asm.OSDBA=oinstall

    oracle.install.asm.OSASM=asm

    oracle.install.asm.SYSASMPassword=oracle

    oracle.install.asm.diskGroup.name=data

    oracle.install.asm.diskGroup.redundancy=NORMAL

    oracle.install.asm.diskGroup.AUSize=4

    oracle.install.asm.diskGroup.disksWithFailureGroupNames=/dev/sdb

  7.   oracle grid   .

    ./gridSetup.sh -silent \
                   -responseFile /opt/oracle/product/19c/grid/grid_configwizard.rsp
  8.   , oracle grid root,   .

    /opt/oracle/product/19c/grid/root.sh
  9. , oracle restart root roothas.sh.

    cd /opt/oracle/product/19c/grid/crs/install/ && ./roothas.sh


  10.   oracle   runInstaller.

    cd /opt/oracle/product/19c/grid/oui/bin/ \
                                && ./runInstaller -updateNodeList \
                                    ORACLE_HOME=/opt/oracle/product/19c/grid \
                                    -defaultHomeName CLUSTER_NODES= CRS=TRUE
  11. oracle1 /etc/fstab , /swap_file, 2048 RAM.
  12. " Oracle Grid" VM oracle2.
  13. ,   ,   Oracle Restart.    oracle1 oracle     Oracle Restart.

    srvctl add database -db ORCLCDB \
                -oraclehome /opt/oracle/product/19c/dbhome_1 \
                -role PRIMARY


    /opt/oracle/product/19c/grid/bin/crsctl modify \
                res ora.cssd -attr "AUTO_START=always" -unsupported


    /opt/oracle/product/19c/grid/bin/crsctl stop has


    /opt/oracle/product/19c/grid/bin/crsctl start has
  14.   oracle2 oracle     Oracle Restart.

    /opt/oracle/product/19c/grid/bin/crsctl modify \
                res ora.cssd -attr "AUTO_START=always" -unsupported


    /opt/oracle/product/19c/grid/bin/crsctl stop has


    /opt/oracle/product/19c/grid/bin/crsctl start has


    srvctl add database -db ORCLCDB_STBY \
               -oraclehome /opt/oracle/product/19c/dbhome_1 \
               -role PHYSICAL_STANDBY \
               -spfile /opt/oracle/product/19c/dbhome_1/dbs/spfileORCLCDB.ora \
               -dbname ORCLCDB -instance ORCLCDB
  15. Sur les deux serveurs, oracle1 et oracle2, sous l'utilisateur oracle, ajoutez un écouteur à la configuration Oracle Restart.

    srvctl add listener
  16. Sur le serveur oracle1, sous l'utilisateur oracle, ajoutez à la configuration et démarrez le service de base de données, ORCLCDB.

    srvctl add service -db ORCLCDB -service orclpdb -l PRIMARY -pdb ORCLPDB1


    srvctl start service -db ORCLCDB -service orclpdb
  17. Sur le serveur oracle2, sous l'utilisateur oracle, ajoutez le service de base de données, ORCLCDB_STBY à la configuration et démarrez l'instance de base de données

    srvctl add service -db ORCLCDB_STBY -service orclpdb -l PRIMARY -pdb ORCLPDB1


    srvctl start database -db ORCLCDB_STBY
  18. Sur les serveurs oracle1 et oracle2, démarrez le service ons.

    srvctl enable ons


    srvctl start ons




Démo "Switchover" sur une application de test Java







En conséquence, nous avons 2 serveurs oracle avec réplication en mode veille active et service ons, auxquels les événements de commutation seront envoyés, et l'application Java pourra traiter ces événements à mesure qu'ils arrivent.



Créons un utilisateur et une table de test dans Oracle.
  oracle1 oracle   sqlplus  

  • sqlplus / as sysdba
  • alter session set container=ORCLPDB1;
  • CREATE USER testus 
           IDENTIFIED BY test 
           DEFAULT TABLESPACE USERS 
           QUOTA UNLIMITED ON USERS;
  • GRANT CONNECT, 
          CREATE SESSION, 
          CREATE TABLE 
          TO testus;
  • CREATE TABLE TESTUS.MESSAGES (TIMEDATE TIMESTAMP, MESSAGE VARCHAR2(100));




Après avoir créé un utilisateur et une table de test, nous nous connectons au serveur oracle2 et «ouvrons» l'instance en lecture pour nous assurer que la réplication fonctionne.

 
 [oracle@oracle2 ~]$ sqlplus / as sysdba
 SQL> alter pluggable database all open;
 SQL> alter session set container=ORCLPDB1;
 SQL> column table_name format A10;
 SQL> column owner format A10;
 SQL> select table_name, owner from dba_tables where owner like '%TEST%';

TABLE_NAME OWNER
---------- ----------
MESSAGES   TESTUS


L'application de test se compose d'une seule classe Main, dans une boucle, elle essaie d'ajouter un enregistrement à la table de test, puis de lire le même enregistrement (voir les méthodes "putNewMessage ()" et "getLastMessage ()"). Il existe également la méthode "getConnectionHost ()", qui à partir de l'objet "connection" utilisant l '"API Reflection" obtient l'adresse IP de la connexion à la base de données. Comme vous pouvez le voir dans la console, après "basculement", cette adresse change.



Lancez l'application de test et exécutez le "basculement" dans la console Data Guard.



DGMGRL> switchover to orclcdb_stby;


Nous voyons comment l'adresse IP de connexion change dans le journal de l'application, le temps d'arrêt est de 1 minute:



[Wed Aug 26 23:56:55 MSK 2020]: Host 192.168.56.78: - 2020-08-26 23:56:55|  ?
[Wed Aug 26 23:56:56 MSK 2020]: Host 192.168.56.78: - 2020-08-26 23:56:56|  ?
[Wed Aug 26 23:56:57 MSK 2020]: Host 192.168.56.78: - 2020-08-26 23:56:57|  ?
[Wed Aug 26 23:56:58 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:57:02 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:57:06 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:57:10 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:57:14 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:57:18 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:57:23 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:57:27 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:57:31 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:57:35 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:57:39 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:57:43 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:57:47 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:57:51 MSK 2020]: Host 192.168.56.79: - 2020-08-26 23:57:52|  ?
[Wed Aug 26 23:57:53 MSK 2020]: Host 192.168.56.79: - 2020-08-26 23:57:53|  ?
[Wed Aug 26 23:57:54 MSK 2020]: Host 192.168.56.79: - 2020-08-26 23:57:54|  ?


Revenez pour être sûr.



DGMGRL> switchover to orclcdb;


La situation est symétrique.



[Wed Aug 26 23:58:54 MSK 2020]: Host 192.168.56.79: - 2020-08-26 23:58:54|  ?
[Wed Aug 26 23:58:55 MSK 2020]: Host 192.168.56.79: - 2020-08-26 23:58:55|  ?
[Wed Aug 26 23:58:56 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:59:00 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:59:04 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:59:08 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:59:12 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:59:16 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:59:20 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:59:24 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:59:28 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:59:32 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:59:36 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:59:40 MSK 2020]: SQLException: -  !
[Wed Aug 26 23:59:44 MSK 2020]: Host 192.168.56.78: - 2020-08-26 23:59:45|  ?
[Wed Aug 26 23:59:46 MSK 2020]: Host 192.168.56.78: - 2020-08-26 23:59:46|  ?


Faisons également attention aux connexions TCP sur les hôtes oralce1 et oracle2. Le port de données est occupé avec des connexions uniquement sur le primaire, le port ONS est occupé à la fois sur le primaire et la réplique.



Avant le basculement.

oracle1
Every 1.0s: ss -tapn | grep 192.168.56.1 | grep ESTAB | grep -v ":22"

ESTAB 0 0 192.168.56.78:1521 192.168.56.1:49819 users:(("oracle_21115_or"...))
ESTAB 0 0 192.168.56.78:1521 192.168.56.1:49822 users:(("oracle_21117_or"...))
ESTAB 0 0 [::ffff:192.168.56.78]:6200 [::ffff:192.168.56.1]:49820 users:(("ons"...))



oracle2
Every 1.0s: ss -tapn | grep 192.168.56.1 | grep ESTAB | grep -v ":22"

ESTAB 0 0 [::ffff:192.168.56.79]:6200 [::ffff:192.168.56.1]:49821 users:(("ons"...))


Après le basculement.

oracle1
Every 1.0s: ss -tapn | grep 192.168.56.1 | grep ESTAB | grep -v 22  Wed Aug 26 16:57:57 2020

ESTAB 0 0 [::ffff:192.168.56.78]:6200 [::ffff:192.168.56.1]:51457 users:(("ons"...))



oracle2
Every 1.0s: ss -tapn | grep 192.168.56.1 | grep ESTAB | grep -v ":22" Wed Aug 26 16:58:35 2020

ESTAB 0 0 192.168.56.79:1521 192.168.56.1:52259 users:(("oracle_28212_or"...))
ESTAB 0 0 192.168.56.79:1521 192.168.56.1:52257 users:(("oracle_28204_or"...))
ESTAB 0 0 [::ffff:192.168.56.79]:6200 [::ffff:192.168.56.1]:51458 users:(("ons"...))


Conclusion



Ainsi, nous avons simulé un cluster Data Guard dans un environnement de laboratoire avec un nombre minimum de paramètres et implémenté une connexion de basculement d'une application Java de test. Nous savons maintenant ce que le développeur attend du DBA et le DBA du développeur. Il reste à lancer et tester Fast Start Failover, mais peut-être dans le cadre d'un article séparé.



All Articles