11g/12c : avec GoldenGate

  • Imprimer

Cet article fait suite à Migration 11g/12c. Il décrit la migration d’une base de données nommée SHAKA en 11.2.0.4 Entreprise Edition sur un serveur en Oracle Linux 64bit vers une 12.1.0.2 Entreprise Edition sur un autre serveur Oracle Linux avec Oracle GoldenGate 12.1.2:

Système source

Système cible

Oracle Database 11.2.0.4 Entreprise Edition

Oracle Database 12.1.0.2 Entreprise Edition

Nom de la base : SHAKA

Nom de la pluggable database : SHAKA
Container : BIGDB

Architecture : standalone

Architecture : standalone CDB

Nom du serveur : oradbm02

Nom du serveur : ora12cdb

OS : Oracle Linux 6.4 64bit

OS : Oracle Linux 6.7 64bit

La base source et/ou la base cible pourraient être en Standard Edition, GoldenGate est indépendant de l’édition de la base de données. D’ailleurs la base source et cible peuvent aussi avoir un characterset différent et un endian différent , la base source pourrait être en Windows ou Linux Intel (Little Endian) et la base cible en AIX Power (Big Endian).

Le but de l’article n’est pas d’expliquer en détail GoldenGate. En revanche toutes les commandes sont suffisantes pour le mettre en oeuvre dans le cas d’une migration simple, d’un schéma 11g vers une schéma 12c, et donc aussi permettre une première prise en main pour ceux qui ne connaitraient pas GoldenGate.

 

Un petit rappel sur GoldenGate:

Le principe de fonctionnement de GoldenGate, c’est de lire les journaux de log (redolog) et d’extraire en temps réel les modifications des objets que l’on souhaite répliquer (il peut aussi lire dans les archivelog). Ces modifications sont stockées dans des fichiers TRAIL par un proccess nommé EXTRACT. Ensuite un process nommé DATAPUMP envoie ce TRAIL sur le serveur cible, et là un proccess nommé REPLICAT joue les modifications écrites dans le TRAIL sur la base cible. C’est le workflow classique et conseillé dans le cas d’une migration :

Avant de démarrer le REPLICAT, il faut que la base cible contiennent les objets de la base source plus ou moins à jour (à un SCN connu), c’est la phase INITIAL LOAD, qui peut être faite par RMAN ou export/import. Dans le cas d’une migration de moteur export/import sera privilégié et encore plus dans le cas d’OS hétérogène. Une fois le REPLICAT démarré et les bases synchros, la bascule peut se faire.

 

 

Comme dans les autres migrations 11g/12c précédemment décrites sur le site, il n’y a qu’un schéma à migrer : U_TEST dont les données sont réparties sur 3 tablespaces soit environ 475Mo.

SQL-11g> select o.object_name,o.object_type,s.tablespace_name, s.bytes/1024/1024 Mo from dba_objects o, dba_segments s
where o.object_name = s.segment_name  and o.OWNER ='U_TEST' order by 2,1;

OBJECT_NAME                                    OBJECT_TYPE                TABLESPACE_NAME           MO
----------------------------------- ------------------- -------------------- ----------
COL14_COMBI_IDX                           INDEX                              TBS_TEST_IDX                      104
COL1_IDX                                               INDEX                              TBS_TEST_IDX                       72
COL4_IDX                                               INDEX                              TBS_TEST_IDX                       72
PK_TEST_LOAD                                                   INDEX                              TBS_TEST_IDX                       20
SYS_C003978                                        INDEX                              TBS_TEST_IDX                    .1875
SYS_C003979                                        INDEX                              TBS_TEST_IDX                        2
SYS_C003981                                        INDEX                              TBS_TEST_IDX                        2
SYS_IL0000014263C00003$$           INDEX                              TBS_IMAGE                         .0625
SYS_LOB0000014263C00003$$       LOB                   TBS_IMAGE                       88.125
TEST1                                                       TABLE                               TBS_IMAGE                           .75
TEST2                                                       TABLE                               TBS_TEST_DATA                                   3
TEST3                                                       TABLE                               TBS_TEST_DATA                                   3
T_TEST                                                    TABLE                               TBS_TEST_DATA                                 112

Mais dans le cas de GoldenGate ce n’est pas l’information la plus vitale pour préparer la migration, il y a une autre information essentielle à maitriser : y a-t-il des clefs primaires sur toutes les tables à migrer ?

Et dans notre cas, cela tombe bien, il y a 4 tables et elles ont toutes une pk ! Cela simplifiera la migration. Et pour information sur les 4 tables, une contient un champs BLOB (des images) pas de soucis pour GoldenGate, et 3 tables sont liées par des foreign key et cela ne pose pas problème car GoldenGate réplique dans le même ordre les modifications faites sur la base source. Si vous voulez donc mettre en œuvre GoldenGate comme dans cet article (pour une prise en main GoldenGate par exemple), voici le modèle physique du schéma U_TEST :

 

Maintenant avant de commencer à installer GoldenGate et à le configurer, comme dans les articles précédents (11g/12c : import full tablespace transportable,11g/12c : dataguard - import full tablespace transportable), il faut créer la base cible en 12c en architecture CDB :

SQL-12C> show pdbs

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

SQL-12C> create pluggable database SHAKA admin user goz identified by goz file_name_convert=('/oracle/oradata/BIGDB/pdbseed','/oracle/oradata/BIGDB/SHAKA');
Pluggable database created.

SQL-12C> alter pluggable database SHAKA open;

SQL-12C> show pdbs

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

 

Une fois la pluggable database créée, nous installons le software GoldenGate sur les 2 serveurs. L’installation de GoldenGate 12 que nous utilisons ici (12.1.2.1.0 pour être précis) est graphique contrairement à GoldenGate 11.

Sur ora12cdb, le serveur de la 12c :

[root@ora12cdb GoldenGate]# unzip gg_121.2.1.0_linux_x36_64.zip -d /delivery/
[root@ora12cdb delivery]# chown -R oracle.oinstall fbo_ggs_Linux_x64_shiphome/
[oracle@ora12cdb delivery]# cd /delivery/fbo_ggs_Linux_x64_shiphome/Disk1
[oracle@ora12cdb Disk1]$ ./runInstaller

1

2

1 : Bien choisir "for Oracle Database 12c", et Next

2: Choisir le répertoire où les binaires seront installés, ici '/oracle/ggate'
        et Next

3 : Install

4 : "patiente cela ne dure pas longtemps"

5 : Close

3

4

5

Ce n’est  pas obligatoire, mais nous mettons à jour le .bash_profile du compte oracle avec la variable $ORACLE_GG pointant sur le répertoire de l’installation GoldenGate :

[oracle@ora12cdb ~]$ vi .bash_profile
export ORACLE_GG=/oracle/ggate

Puis une fois les binaires installés, il faut générer les arborescences essentiel au bon fonctionnement de GoldenGate :

[oracle@ora12cdb ggate]$ ./ggsci
[oracle@ora12cdb ggate]$ cd $ORACLE_GG
Oracle GoldenGate Command Interpreter for Oracle
Version 12.1.2.1.0 OGGCORE_12.1.2.1.0_PLATFORMS_140727.2135.1_FBO
Linux, x64, 64bit (optimized), Oracle 12c on Aug  7 2014 10:21:34
Operating system character set identified as UTF-8.

Copyright (C) 1995, 2014, Oracle and/or its affiliates. All rights reserved.

GGSCI (ora12cdb.localdomain) 1> create subdirs

Creating subdirectories under current directory /oracle/ggate

Parameter files                /oracle/ggate/dirprm: already exists
Report files                   /oracle/ggate/dirrpt: created
Checkpoint files               /oracle/ggate/dirchk: created
Process status files           /oracle/ggate/dirpcs: created
SQL script files               /oracle/ggate/dirsql: created
Database definitions files     /oracle/ggate/dirdef: created
Extract data files             /oracle/ggate/dirdat: created
Temporary files                /oracle/ggate/dirtmp: created
Credential store files         /oracle/ggate/dircrd: created
Masterkey wallet files         /oracle/ggate/dirwlt: created
Dump files                     /oracle/ggate/dirdmp: created

 

Ensuite il faut faire presque exactement la même chose sur le serveur oradbm2, la seule différence et qu’il faut préciser que l’on installe GoldenGate pour une 11g :

[root@oradbm2 GoldenGate]# unzip gg_121.2.1.0_linux_x36_64.zip -d /delivery/
[root@oradbm2 GoldenGate]# chown -R oraee.oinstall /delivery/fbo_ggs_Linux_x64_shiphome/
[oraee@oradbm2 Disk1]$ cd /delivery/fbo_ggs_Linux_x64_shiphome/Disk1
[oraee@oradbm2 Disk1]$ ./runInstaller

C'est exactement comme sur  ora12cdb, sauf sur la première IHM, ici c'est Oracle GoldenGate pour la 11g:

 

[oraee@oradbm2 ~]$ vi .bash_profile
export ORACLE_GG=/oracle/ggate
[oraee@oradbm2 ~]$ cd $ORACLE_GG
[oraee@oradbm2 ggate]$ ./ggsci

GGSCI (oradbm2.localdomain) 1> create subdirs

Creating subdirectories under current directory /oracle/ggate

Parameter files                /oracle/ggate/dirprm: already exists
Report files                   /oracle/ggate/dirrpt: created
Checkpoint files               /oracle/ggate/dirchk: created
Process status files           /oracle/ggate/dirpcs: created
SQL script files               /oracle/ggate/dirsql: created
Database definitions files     /oracle/ggate/dirdef: created
Extract data files             /oracle/ggate/dirdat: created
Temporary files                /oracle/ggate/dirtmp: created
Credential store files         /oracle/ggate/dircrd: created
Masterkey wallet files         /oracle/ggate/dirwlt: created
Dump files                     /oracle/ggate/dirdmp: created

 

 

Le binaires sont en place. Maintenant il faut préparer les bases de données à GoldenGate.

Sur la base SHAKA de la 11g, il faut créer l’utilisateur GoldenGate et lui donner les droits nécessaires. Ici il sera DBA (ce n’est qu’un banc de test), mais il possible et conseiller de mettre uniquement les droit nécessaires sur une production.

SQL-11G> create user gguser identified by gguser;
SQL-11G> grant connect, dba to gguser;

Il faut activer le paramètre enable_goldengate_replication:

SQL-11G> alter system set enable_goldengate_replication=TRUE scope=both;

Toujours sur la 11g, il faut rajouter les supplemental log, cela permet de rajouter des informations en plus dans les redologs.

SQL-11G> alter database add supplemental log data;
SQL-11G> alter system switch logfile;
SQL-11G> select supplemental_log_data_min from v$database;

SUPPLEME
--------
YES

 

Repassons sur la 12c, sur le serveur ora12cdb. Je fais exprès de passer par une connexion bequeath à BIGDB puis de faire show pdbs et ensuite le connect avec l’alias tns SHAKA, pour bien faire voir que : attention nous sommes sur une CDB, nous créons l’utilisateur gguser sur la pluggable database et pas dans la root.

[oracle@ora12cdb ~]$ export ORACLE_SID=BIGDB
[oracle@ora12cdb ~]$ sqlplus / as sysdba
SQL-12C> show pdbs

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

SQL-12C > conn system/oracle@SHAKA
SQL-12C > create user gguser identified by gguser;
SQL-12C > grant connect, dba to gguser;

Comme sur la SHAKA source:

SQL-12C>alter system set enable_goldengate_replication=TRUE scope=both;
SQL-12C > alter database add supplemental log data;
SQL-12C > alter system switch logfile;
SQL-12C > select supplemental_log_data_min from v$database;

Ca y est les 2 bases sont prêtes pour GoldenGate!

Il est temps de commencer à paramétrer les process GodelGate et de les lancer, une dernière petite chose avant, il faut créer le fichier GLOBALS avec à l’intérieur le paramétrage du nom de la table de checkpoint, ce n’est pas obligatoire maintenant mais ce sera fait.

[oracle@ ora12cdb ggate]$ cd $ORACLE_GG
[oracle@ora12cdb ggate]$ vi GLOBALS
CheckpointTable GGS_CHECKPOINT

Puis paramétrage du process manager et démarrage du process :

[oracle@ora12cdb ggate]$  ./ggsci

GGSCI (ora12cdb.localdomain) 1> edit Param mgr
PORT 7809
DYNAMICPORTLIST 7810-7820
PurgeOldExtracts ./dirdat/*, UseCheckpoints

GGSCI (ora12cdb.localdomain) 2> start mgr
Manager started.

GGSCI (ora12cdb.localdomain) 3> info mgr

Manager is running (IP port ora12cdb.localdomain.7809, Process ID 3355).

Et idem sur le serveur source:

[oraee@oradbm2 ggate]$ vi GLOBALS
CheckpointTable GGS_CHECKPOINT

[oraee@oradbm2 ggate]$ cd $ORACLE_GG
[oraee@oradbm2 ggate]$ ./ggsci
GGSCI (oradbm2.localdomain) 1> edit Param mgr
PORT 7809
DYNAMICPORTLIST 7810-7820
PurgeOldExtracts ./dirdat/*, UseCheckpoints

GGSCI (oradbm2.localdomain) 2> start mgr
Manager started.

GGSCI (oradbm2.localdomain) 3> info mgr

Manager is running (IP port oradbm2.localdomain.7809, Process ID 3320).

Nous nous connectons sur la base source à travers l’outil en ligne de commande GGSCI, pour activer les supplemental log sur les tables du schéma à répliquer U_TEST :

GGSCI (oradbm2.localdomain) 4> DbLogin userID gguser, password gguser
Successfully logged into database.

GGSCI (oradbm2.localdomain as gguser@SHAKA) 5> add trandata u_test.*

Logging of supplemental redo data enabled for table U_TEST.TEST1.
TRANDATA for scheduling columns has been added on table 'U_TEST.TEST1'.
Logging of supplemental redo data enabled for table U_TEST.TEST2.
TRANDATA for scheduling columns has been added on table 'U_TEST.TEST2'.
Logging of supplemental redo data enabled for table U_TEST.TEST3.
TRANDATA for scheduling columns has been added on table 'U_TEST.TEST3'.
Logging of supplemental redo data enabled for table U_TEST.T_TEST.
TRANDATA for scheduling columns has been added on table 'U_TEST.T_TEST'.

 

Tout est prêt pour paramétrer le process d’extraction : EXTRACT. Toujours connecté sur la base avec GGSCI :

GGSCI (oradbm2.localdomain as gguser@SHAKA) 3> edit param extss
Extract extss
ExtTrail ./dirdat/es
userID gguser, password gguser
Table U_TEST.*;
REPORTCOUNT EVERY 60 SECONDS
REPORTROLLOVER AT 00:01

(la nomenclature ici : extss = ext pour extract, s pour SHAKA et s pour source)

GGSCI (oradbm2.localdomain as gguser@SHAKA) 4> add extract extss, tranlog, begin now

GGSCI (oradbm2.localdomain as gguser@SHAKA) 5> add extTrail ./dirdat/es, Extract extss, megabytes 20

 

L’extraction se fait donc dans les fichiers ./dirdat/esnnnnnn, et il faut envoyer le contenu sur le serveur cible grâce au process DATAPUMP.

Configuration du datapump:

GGSCI (oradbm2.localdomain as gguser@SHAKA) 6> edit param pumpss
Extract pumpss
RmtHost ora12cdb, MgrPort 7809, Compress
µRmtTrail ./dirdat/pt
passthru
Table U_TEST.*;

(ma nomenclature ici pumpss = pump pour datapump, s pour SHAKA et s pour source)

GGSCI (oradbm2.localdomain as gguser@SHAKA) 7> add extract pumpss, ExtTrailSource ./dirdat/es

GGSCI (oradbm2.localdomain as gguser@SHAKA) 8>  add RmtTrail ./dirdat/pt, Extract pumpss, megabytes 20

 

Une EXTRACT et DATAPUMP configurés, on croise les doigts et on lance:

GGSCI (oradbm2.localdomain as gguser@SHAKA) 10> start extract extss

GGSCI (oradbm2.localdomain as gguser@SHAKA) 13> start extract pumps

GGSCI (oradbm2.localdomain as gguser@SHAKA) 27> info ER *

EXTRACT    EXTSS     Last Started 2015-11-11 22:07   Status RUNNING
Checkpoint Lag       00:00:00 (updated 00:00:01 ago)
Process ID           4054
Log Read Checkpoint  Oracle Redo Logs
                     2015-11-11 22:20:39  Seqno 82, RBA 34281984
                     SCN 0.2254473 (2254473)

EXTRACT    PUMPSS    Last Started 2015-11-11 22:21   Status RUNNING

Checkpoint Lag       00:00:00 (updated 00:18:27 ago)
Process ID           4147
Log Read Checkpoint  File ./dirdat/es000000
                     First Record  RBA 0

 

Maintenant que l’EXTRACT est parti il faut générer l’INITIAL LOAD avant de configurer le REPLICATE… et oui, la base cible est vide ! Et dans les TRAIL de l’EXTRACT il n’y a que des modifications sur des objets existants (insert,update,delete)

Pour cela on commence par noter à quel SCN la base source se trouve :

SQL-11G>  select current_scn from v$database ;
CURRENT_SCN
-----------
    2254694

On exporte alors la base à ce SCN et on envoie sur la cible:

[oraee@oradbm2 ggate]$ expdp system/oracle directory=DATA_PUMP_DIR  dumpfile=u_test.dmp schemas=U_TEST flashback_scn=2254694
[oraee@oradbm2 log]$ scp u_test.dmp oracle@ora12cdb:/oracle/dumpmig/

Pour mieux visualiser par la suite que tout ce qui suit l’export va bien se répliquer :

SQL-11G> select count(*) from u_test.test1;
  COUNT(*)
----------
      9904

SQL-11G> select count(*) from u_test.test3;
  COUNT(*)
----------
     74704

SQL-11G> !./chargement.sh  2

SQL-11G> select count(*) from u_test.test1;
  COUNT(*)
----------
      9906

SQL-11G> select count(*) from u_test.test3;
  COUNT(*)
----------
     74714

Pour finir l’INITIAL LOAD, il ne reste plus qu’à importer l’export.  

[oracle@ora12cdb log]$ impdp system/oracle@SHAKA directory=PUMP_MIG  dumpfile=u_test.dmp schemas=U_TEST
[...]
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
. . imported "U_TEST"."T_TEST"                           91.06 MB 1270000 rows
. . imported "U_TEST"."TEST1"                            37.81 MB    9904 rows
. . imported "U_TEST"."TEST2"                            1.720 MB   74704 rows
. . imported "U_TEST"."TEST3"                            2.077 MB   74704 rows
Processing object type SCHEMA_EXPORT/PROCEDURE/PROCEDURE
Processing object type SCHEMA_EXPORT/PROCEDURE/ALTER_PROCEDURE
Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
[...]

Evidement maintenant dans la base cible il y a les données de la base source au SCN 2254694 mais il n’y a pas les lignes ajoutées après :

SQL-12C> select count(*) from u_test.test1;
  COUNT(*)
----------
      9904

SQL-12C> select count(*) from u_test.test3;
  COUNT(*)
----------
     74704

 

L’INITIAL LOAD fini, il ne reste plus qu’à configurer le REPLICATE et à le démarrer. Avant faire cela, ce n’est pas obligatoire, mais il est fortement conseillé de créer la table de checkpoint (pour une meilleure reprise en cas d’arrêt ou crash) :

[oracle@ora12cdb ggate]$ ./ggsci
GGSCI (ora12cdb.localdomain) 1>  dblogin userid gguser@shaka, password gguser

GGSCI (ora12cdb.localdomain as gguser@BIGDB/SHAKA) 2> add checkpointTable

No checkpoint table specified. Using GLOBALS specification (GGUSER.GGS_CHECKPOINT)...
Logon catalog name SHAKA will be used for table specification SHAKA.GGUSER.GGS_CHECKPOINT.
Successfully created checkpoint table SHAKA.GGUSER.GGS_CHECKPOINT.

Paramétrage du REPLICAT:

GGSCI (ora12cdb.localdomain as gguser@BIGDB/SHAKA) 6> edit param repst
Replicat repst
AssumeTargetDefs
DiscardFile ./dirrpt/repst.dsc, Purge
userID gguser@shaka, Password gguser
Map U_TEST.*, Target U_TEST.*;

(la nomenclature ici : repst = rep pour replicate, s pour SHAKA et t pour target)

Add and start :

GGSCI (ora12cdb.localdomain as gguser@BIGDB/SHAKA) 7> Add replicat repst, ExtTrail ./dirdat/pt
REPLICAT added.

GGSCI (ora12cdb.localdomain as gguser@BIGDB/SHAKA) 8> start replicat repst,aftercsn 2254694
Sending START request to MANAGER ...
REPLICAT REPST starting

GGSCI (ora12cdb.localdomain as gguser@BIGDB/SHAKA) 13> info replicat repst

REPLICAT   REPST     Last Started 2015-11-11 23:52   Status RUNNING
Checkpoint Lag       00:00:00 (updated 00:00:00 ago)
Process ID           4541
Log Read Checkpoint  File ./dirdat/pt000000
                     First Record  RBA 1465

Et voilà c’est fini “ça réplique”…

…vérifions cela

[oracle@ora12cdb dirrpt]$  sqlplus system/oracle@shaka

SQL-12C> select count(*) from u_test.test1;
  COUNT(*)
----------
      9906

SQL-12C> select count(*) from u_test.test3;
  COUNT(*)
----------
     74714

… les lignes insérées sur la source avant l’import sont arrivé sur la cible.

Il existe plusieurs commandes pour suivre les process extract, datapum et replicat, contentons-nous de celle qui check le lag (en // j'ai lancé un chargement) :

GGSCI (oradbm2.localdomain as gguser@SHAKA) 38> lag extss

Sending GETLAG request to EXTRACT EXTSS ...
Last record lag 1 seconds.

Ici une seconde de lag pendant un chargement sur la base source, vu que tous mes serveurs sont virtuels et sont sur le même disque SATA, c’est correct.

Le but étant une migration sans downtime, il faut préparer la bascule qui en fait va générer un léger downtime applicatif : arrêt des applications puis vérication lag à 0 et relance des applications sur la base cible. Downtime < 1minutes.

Le process de cette migration n’est pas très compliqué, il consiste juste à mettre en place GoldenGate, et GoldenGate réplique jusqu’au jour J. Cette migration nécessite donc une compétence GoldenGate. Dans l’exemple présenté ici, c’était assez basique : 1 schéma, 4 tables avec des pk, pas de séquence, pas de gestion de trigger… Cette méthode par GoldenGate a le grand avantage d’un downtime vraiment minimal contrairement aux autres méthodes « plus classiques » : export/import, 11g/12c : import full tablespace transportable et même celle utilisant une dataguard :11g/12c : dataguard - import full tablespace transportable.

Remarque :  Il est possible de configurer GoldenGate pour se synchroniser dans l’autre sens,  comme ça il est possible de revenir en arrière si quelque chose se passe mal sur la nouvelle base. Mais ceci est une autre histoire.

 

 

 {jcomments on}