For Part 2 click here: Troubleshooting GoldenGate Bidirectional (Active-Active) Replication 2 - Configuration of Macros and Exceptions Handling Routines
The following is an example of testing and troubleshooting Oracle Goldengate bidirectional active-active replication using odd and even sequences in Oracle 11gR2. For uni-directional replication configuration examples please visit homepage
We have two servers:
Hostname: | source | target |
Instance (11gR2): | source | target |
Schema: | source | source |
In bidirectional GoldenGate configuration changes made to either
database replicate to the other database in real time. The process works like
this:
esource1 (extract on source) -> psource1 (datapump on source) -> rsource1 (replicat
on target)
etarget1 (extract on target) -> ptarget1 (datapump on target) -> rtarget1 (replicat
on source)
GoldenGate does not replicate Oracle database sequences values in an active-active environment. The sequences must insert values on the target database from its own sequences. Therefore, to ensure that the source and destination sequences are unique, it is recommended to generate odd and even values to each system.
Lets create these processes and test our replication (please keep in mind we will have to change some of the parameters later on).
SOURCE | TARGET |
--./GLOBALS on source and target--
GGSCHEMA GGATE CHECKPOINTTABLE GGATE.CHKPTAB |
--./GLOBALS on source and target--
GGSCHEMA GGATE CHECKPOINTTABLE GGATE.CHKPTAB |
------------------------------------------------------------------ -- GoldenGate Manager on source and target-- -- Last updated on 20111015 by VG -- ------------------------------------------------------------------- PORT 7809 USERID ggate, PASSWORD oracle AUTOSTART EXTRACT * AUTOSTART REPLICAT * AUTORESTART EXTRACT *, RETRIES 3, WAITMINUTES 1, RESETMINUTES 60 AUTORESTART REPLICAT *, RETRIES 3, WAITMINUTES 1, RESETMINUTES 60 PURGEOLDEXTRACTS /opt/oracle/gg/dirdat/*, USECHECKPOINTS, MINKEEPDAYS 2 --Specifies to log the lag time as a warning in the event log LAGCRITICALMINUTES 5 --Specifies how often to report lag info to the event log LAGREPORTMINUTES 60 LAGINFOMINUTES 0 --Manages trail files to conserve space-- PURGEOLDEXTRACTS /opt/oracle/gg/dirdat/*, USECHECKPOINTS, MINKEEPDAYS 2 |
------------------------------------------------------------------ -- GoldenGate Manager on source and target-- -- Last updated on 20111015 by VG -- ------------------------------------------------------------------- PORT 7809 USERID ggate, PASSWORD oracle AUTOSTART EXTRACT * AUTOSTART REPLICAT * AUTORESTART EXTRACT *, RETRIES 3, WAITMINUTES 1, RESETMINUTES 60 AUTORESTART REPLICAT *, RETRIES 3, WAITMINUTES 1, RESETMINUTES 60 PURGEOLDEXTRACTS /opt/oracle/gg/dirdat/*, USECHECKPOINTS, MINKEEPDAYS 2 --Specifies to log the lag time as a warning in the event log LAGCRITICALMINUTES 5 --Specifies how often to report lag info to the event log LAGREPORTMINUTES 60 LAGINFOMINUTES 0 --Manages trail files to conserve space-- PURGEOLDEXTRACTS /opt/oracle/gg/dirdat/*, USECHECKPOINTS, MINKEEPDAYS 2 |
-------------------------------------------------------------------- -- Local extract ESOURCE1 for Source schhema -- -- Updated on 2011 Nov 18 by VG -- --------------------------------------------------------------------- --extract group-- extract ESOURCE1 --export sid setenv (ORACLE_SID=source) --connection to database-- userid ggate, password oracle --reporting-- ReportCount Every 30 Minutes, Rate Report at 01:00 ReportRollover at 01:15 --discard-- DiscardFile dirrpt/DRPROD1.dis, Append DiscardRollover at 02:00 ON SUNDAY --Bidirectional params-- --GETAPPLOPS-- --IGNOREREPLICATES-- --Redo log options-- TRANLOGOPTIONS COMPLETEARCHIVEDLOGTIMEOUT 600 --bound recovery-- BR BROFF --path and name for local destination trrail-- exttrail /opt/oracle/gg/dirdat/c1 --DDL support-- ddl include mapped objname source.* --DML support-- table source.*; |
-------------------------------------------------------------------- -- Local extract etarget1 for SOURCE on TARGET db -- -- Updated on 2011 Nov 18 by VG -- --------------------------------------------------------------------- --extract group-- extract ETARGET1 --export sid setenv (ORACLE_SID=target) --connection to database-- userid ggate, password oracle --reporting-- ReportCount Every 30 Minutes, Rate Report at 01:00 ReportRollover at 01:15 --discard-- DiscardFile dirrpt/DRPROD1.dis, Append DiscardRollover at 02:00 ON SUNDAY --Redo log options-- TRANLOGOPTIONS COMPLETEARCHIVEDLOGTIMEOUT 600 --bidirectional parameters-- --GETAPPLOPS-- --IGNOREREPLICATES-- --bound recovery-- BR BROFF --path and name for local destination trrail-- exttrail /opt/oracle/gg/dirdat/t1 --DDL support-- ddl include mapped objname source.* --DML support-- table source.*; |
-------------------------------------------------------------------- -- DataPump PSOURCE1 for SOURCE schema --- -- Updated on 2011 Nov 18 by VG -- --------------------------------------------------------------------- --dataPump group-- extract PSOURCE1 PassThru --hostname and port for trail-- rmthost target, mgrport 7809 --path and name for remote destination ttrail-- rmttrail /opt/oracle/gg/dirdat/c2 table source.* ; |
-------------------------------------------------------------------- -- DataPump PTARGET1 for SOURCE on TARGEET -- -- Updated on 2011 Nov 18 by VG -- --------------------------------------------------------------------- --dataPump group-- extract ptarget1 PassThru --hostname and port for trail-- rmthost source, mgrport 7809 --path and name for remote destination ttrail-- rmttrail /opt/oracle/gg/dirdat/t2 table SOURCE.* ; |
------------------------------------------------------------------- -- Replicat for SOURCE Schema on SOURCE server -- -- Last updated by VG -- -------------------------------------------------------------------- --Replicat group -- replicat RTARGET1 --export sid setenv (ORACLE_SID=source) --source and target definitions-- AssumeTargetDefs --target database login -- userid ggate, password oracle --PERFORMANCE PARMETERS-- --Double SQL transaction in 1 operation--- GROUPTRANSOPS 2000 --group similar transactions-- --BATCHSQL-- --error handling-- DDLERROR DEFAULT IGNORE RETRYOP --file for dicarded transaction -- discardfile /opt/oracle/gg/discard/RTARGET1_discard.txt, purge, megabytes 50 --Reporting-- ReportCount Every 30 Minutes, Rate Report at 01:00 ReportRollover at 01:15 DiscardRollover at 02:00 ON SUNDAY --ddl support-- --HANDLECOLLISIONS-- --Supress constraints, SUPRESSTRIGGERS iis not available in this version-- DBOPTIONS DEFERREFCONST DDL INCLUDE ALL DDLOPTIONS REPORT DDLERROR 942 DISCARD INCLUDE OPTYPE DROP REPERROR (1403, DISCARD) --Enable tracing-- --TRACE2-- --Specify table mapping --- map source.*, target source.* ; |
------------------------------------------------------------------- -- Replicat for SOURCE Schema on TARGET--- -- Last updated on Nov 18 2011 by VG --< -------------------------------------------------------------------- --Replicat group -- replicat RSOURCE1 --export sid setenv (ORACLE_SID=target) --source and target definitions-- AssumeTargetDefs --target database login -- userid ggate, password oracle --PERFORMANCE PARMETERS-- --Double SQL transaction in 1 operation--- GROUPTRANSOPS 2000 --group similar transactions-- BATCHSQL --error handling-- DDLERROR DEFAULT IGNORE RETRYOP --file for dicarded transaction -- discardfile /opt/oracle/gg/discard/PSOURCE1_discard.txt, purge, megabytes 50 --Reporting-- ReportCount Every 30 Minutes, Rate Report at 01:00 ReportRollover at 01:15 DiscardRollover at 02:00 ON SUNDAY --ddl support-- DDL INCLUDE ALL DDLOPTIONS REPORT DDLERROR 942 DISCARD INCLUDE OPTYPE DROP REPERROR (1403, DISCARD) HANDLECOLLISIONS --Specify table mapping --- map source.*, target source.* ; |
Now lets start all these created Goldengate processes on both servers and test this configuration.
To test replication we will create table CUSTOMERS on source and target, then create a sequence with odd CUSTOMER_ID on source and even on target.
SQL> CREATE TABLE
CUSTOMERS
(CUSTOMER_ID NUMBER PRIMARY KEY
,CUSTOMER_NAME VARCHAR2(30) NOT NULL
,CUSTOMER_REGISTRATION DATE
,CURRDATE DATE);
Table created.
SQL> CREATE SEQUENCE
CUSTOMER_ID_SEQ
INCREMENT BY 2
START WITH 2
NOMAXVALUE
NOMINVALUE
NOCYCLE
CACHE 500;
Sequence created.
This is an even sequence. It will generate numbers like 2, 4, 6, 8 and so on. Odd CUSTOMER_ID will be replicated from target only to avoid collision.
Now lets insert a hundred rows on source and see if they are replicated to target.
SQL> INSERT INTO CUSTOMERS SELECT
CUSTOMER_ID_SEQ.NEXTVAL,
DBMS_RANDOM.STRING('P',DBMS_RANDOM.VALUE(1,30)),
(SYSDATE-1825)+DBMS_RANDOM.VALUE(1,1820),
CURRENT_TIMESTAMP FROM DUAL CONNECT BY LEVEL <= 100;
100 rows created.
SQL> commit;
Commit complete.
SQL> select count(*) from customers;
COUNT(*)
----------
100
On target - these 100 rows
replicated OK.
SQL> select count(*) from customers;
COUNT(*)
----------
100
So, we know that uni-directional replication from source to target works because we just inserted a hundred rows into source and they were copied to target.
Now we will create an odd sequence and run the same insert statement on target. Number of rows should double in both databases (inserted by hand in target and then replicated by GG to source).
Lets create an odd sequence
(1,3,5,7,9, etc.) and insert another 100 rows with odd values, so they should be
created OK and replicated BACK to source:
SQL> CREATE SEQUENCE
CUSTOMER_ID_SEQ
INCREMENT BY 2
START WITH 1
NOMAXVALUE
NOMINVALUE
NOCYCLE
CACHE 500;
Sequence created.
SQL> INSERT INTO CUSTOMERS SELECT CUSTOMER_ID_SEQ.NEXTVAL,
DBMS_RANDOM.STRING('P',DBMS_RANDOM.VALUE(1,30)),
(SYSDATE-1825)+DBMS_RANDOM.VALUE(1,1820),
CURRENT_TIMESTAMP FROM DUAL CONNECT BY LEVEL <= 100;
100 rows created.
SQL> commit;
Commit complete.
SQL> select count(*) from customers;
COUNT(*)
----------
200
However, even though source has even customer_id and target has odd customer_id, the replicat that runs on source abends without inserting the new 100 rows from target:
GoldenGate error log reports:
2011-11-03 20:12:21 WARNING OGG-00869 Oracle GoldenGate Delivery for Oracle,
rtarget1.prm: OCI Error ORA-00001: unique
constraint (SOURCE.SYS_C0011221) violated (status = 1), SQL <INSERT /*+
RESTRICT_ALL_REF_CONS */ INTO "SOURCE"."CUSTOMERS" ("CUSTOMER_ID","CUSTOMER_NAME","CUSTOMER_REGISTRATION","CURRDATE")
VALUES (:a0,:a1,:a2,:a3)>.
2011-11-03 20:12:21 WARNING OGG-01004 Oracle GoldenGate Delivery for Oracle,
rtarget1.prm: Aborted grouped transaction
on 'SOURCE.CUSTOMERS', Database error 1 (OCI Error ORA-00001: unique constraint
(SOURCE.SYS_C0011221) violated (status =
1), SQL <INSERT /*+ RESTRICT_ALL_REF_CONS */ INTO "SOURCE"."CUSTOMERS" ("CUSTOMER_ID","CUSTOMER_NAME","CUSTOMER_REGISTRATION","CURRDATE")
VALUES (:a0,:a1,:a2,:a3)>).
2011-11-03 20:12:21 WARNING OGG-01003 Oracle GoldenGate Delivery for Oracle,
rtarget1.prm: Repositioning to rba 163624
in seqno 1.
2011-11-03 20:12:21 WARNING OGG-01154 Oracle GoldenGate Delivery for Oracle,
rtarget1.prm: SQL error 1 mapping SOURCE.
CUSTOMERS to SOURCE.CUSTOMERS OCI Error ORA-00001: unique constraint
(SOURCE.SYS_C0011221) violated (status = 1), SQL <IN
SERT /*+ RESTRICT_ALL_REF_CONS */ INTO "SOURCE"."CUSTOMERS" ("CUSTOMER_ID","CUSTOMER_NAME","CUSTOMER_REGISTRATION","CURRDATE")
VALUES (:a0,:a1,:a2,:a3)>.
2011-11-03 20:12:21 WARNING OGG-01003 Oracle GoldenGate Delivery for Oracle,
rtarget1.prm: Repositioning to rba 163624
in seqno 1.
2011-11-03 20:12:21 ERROR OGG-01296 Oracle GoldenGate Delivery for Oracle,
rtarget1.prm: Error mapping from SOURCE.CUSTOMERS to SOURCE.CUSTOMERS.
2011-11-03 20:12:21 ERROR OGG-01668 Oracle GoldenGate Delivery for Oracle,
rtarget1.prm: PROCESS ABENDING.
So, what is the problem?
There is no conflict between unique values in SOURCE.CUSTOMERS on source or destination. Yet GoldenGate abends the replicat on Source server with a unique constraint violation.
Metalink states that TRANLOGOPTIONS EXCLUDEUSER <repuser> needs to be added to extract param
files.
From the docs:
Oracle (Oracle 10g and later) Do either of the following to specify the
Replicat database user.
All transactions generated by this user will be excluded from being captured.
This information is available to Extract in the transaction record.
● Identify the Replicat database user by name with the following parameter
statement in the Extract parameter file.
TRANLOGOPTIONS EXCLUDEUSER <user name>
● Identify the Replicat database user by its numeric Oracle user-id (uid) with
the
following parameter statement in the Extract parameter file.
TRANLOGOPTIONS EXCLUDEUSERID <user-id>
http://download.oracle.com/docs/cd/E22355_01/doc.11111/e21512.pdf
Oracle® GoldenGate
Windows and UNIX Reference Guide
11g Release 1 Patch Set 1 (11.1.1.1)
E21512-02
page 39
TRANLOGOPTIONS EXCLUDEUSER
Typically, this option is used to identify Replicat transactions in a
bi-directional or cascading processing configuration, for the purpose of
excluding or capturing them. However, it can be used to identify transactions by
any other user, such as those of a specific business application.
So, in an effort to resolve abending replicat on source, this parameter is added to both extract param files:
--Redo log options--
TRANLOGOPTIONS EXCLUDEUSER ggate
Now, lets refresh the processes and restart the abended replicat on source.
GGSCI (source) 7> info RTARGET1 showch
GGSCI (source) 16> start replicat
RTARGET1, aftercsn 1161218
Sending START request to MANAGER ...
REPLICAT RTARGET1 starting
GGSCI (source) 17> info all
Program Status Group Lag Time Since Chkpt
MANAGER RUNNING
EXTRACT RUNNING ESOURCE1 00:00:00 00:00:08
EXTRACT RUNNING PSOURCE1 00:00:00 00:00:08
REPLICAT RUNNING RTARGET1 00:00:00 00:00:06
Now, lets clean up customers table
On source:
SQL> delete from customers;
100 rows deleted.
SQL> commit;
Commit complete.
SQL> select count(*) from customers;
COUNT(*)
----------
0
Lets check if odd and even sequences are in order:
Source:
SQL> SELECT CUSTOMER_ID_SEQ.NEXTVAL from dual;
NEXTVAL
----------
404
SQL>
Target:
SQL> delete from customers;
200 rows deleted.
SQL> commit;
Commit complete.
SQL> select count(*) from customers;
COUNT(*)
----------
0
SQL> SELECT CUSTOMER_ID_SEQ.NEXTVAL from dual;
NEXTVAL
----------
601
SQL>
Now lets test corrected bi-directional replication:
On source:
SQL> INSERT INTO CUSTOMERS SELECT CUSTOMER_ID_SEQ.NEXTVAL,
DBMS_RANDOM.STRING('P',DBMS_RANDOM.VALUE(1,30)),
(SYSDATE-1825)+DBMS_RANDOM.VALUE(1,1820),
CURRENT_TIMESTAMP FROM DUAL CONNECT BY LEVEL <= 100;
100 rows created.
SQL> commit;
Commit complete.
On target:
SQL> select count(*) from customers;
COUNT(*)
----------
100
SQL>
On target:
SQL> INSERT INTO CUSTOMERS SELECT CUSTOMER_ID_SEQ.NEXTVAL,
DBMS_RANDOM.STRING('P',DBMS_RANDOM.VALUE(1,30)),
(SYSDATE-1825)+DBMS_RANDOM.VALUE(1,1820),
CURRENT_TIMESTAMP FROM DUAL CONNECT BY LEVEL <= 100;
100 rows created.
SQL> commit;
Commit complete.
SQL> select count(*) from customers;
COUNT(*)
----------
200
These are 100 rows we just inserted on target on top of 100 rows replicated from source by GoldenGate.
On target:
SQL> select count(*) from customers;
COUNT(*)
----------
200
There are no loops (continuing re-insertion of 100 rows) and inserting 100 rows on either target or source replicates
them to the second instance only once.
Both odd and even CUSTOMER_IDs can be found on source and dest and they are
identical:
We now successfully configured and tested bidirectional replication in Oracle GoldenGate
These are corrected param files for bidirectional replication with the exclusion clause, the rest of parameters can be found in table above:
SOURCE:
+++++++++++++++++++++++++++++
---------------------------------------------------------------------
-- Local extract ESOURCE1 for Source schhema --
-- Updated on 2011 Nov 18 by VG --
---------------------------------------------------------------------
--extract group--
extract ESOURCE1
--export sid
setenv (ORACLE_SID=source)
--connection to database--
userid ggate, password oracle
--reporting--
ReportCount Every 30 Minutes, Rate
Report at 01:00
ReportRollover at 01:15
--discard--
DiscardFile dirrpt/DRPROD1.dis, Append
DiscardRollover at 02:00 ON SUNDAY
--Bidirectional params--
--GETAPPLOPS--
--IGNOREREPLICATES--
--Redo log options--
TRANLOGOPTIONS EXCLUDEUSER ggate
COMPLETEARCHIVEDLOGTIMEOUT 600
--bound recovery--
BR BROFF
--path and name for local destination trrail--
exttrail /opt/oracle/gg/dirdat/c1
--DDL support--
ddl include mapped objname source.*
--DML support--
table source.*;
+++++++++++++++++++++++++++++
TARGET
+++++++++++++++++++++++++++++
---------------------------------------------------------------------
-- Local extract etarget1 for SOURCE on TARGET db --
-- Updated on 2011 Nov 18 by VG --
---------------------------------------------------------------------
--extract group--
extract ETARGET1
--export sid
setenv (ORACLE_SID=target)
--connection to database--
userid ggate, password oracle
--reporting--
ReportCount Every 30 Minutes,
Rate
Report at 01:00
ReportRollover at 01:15
--discard--
DiscardFile dirrpt/DRPROD1.dis,
Append
DiscardRollover at 02:00 ON
SUNDAY
--Redo log options--
TRANLOGOPTIONS EXCLUDEUSER ggate
COMPLETEARCHIVEDLOGTIMEOUT 600
--bidirectional parameters--
--GETAPPLOPS--
--IGNOREREPLICATES--
--bound recovery--
BR BROFF
--path and name for local destination trrail--
exttrail /opt/oracle/gg/dirdat/t1
--DDL support--
ddl include mapped objname
source.*
--DML support--
table source.*;
++++++++++++++++++++++++++++++++++++
More demos:
-
Test your knowledge of Oracle GoldenGate
- >Oracle GoldenGate Instantiation with
DataPump
- Oracle GoldenGate Data Flow
(Architecture)
- Oracle GoldenGate: Install GoldenGate on
RedHat Linux
- Oraacle GoldenGate: Configure Uni-Directional
Replication
- Oraclle GoldenGate: Test Uni-Directional
Replication
Copyright © 2012 Vladimir Grigorian. All Rights Reserved