Excluding DDL in Integrated Extract using DBMS_STREAMS_ADM.SET_TAG
¶
A couple of months ago I had to configure an Oracle GoldenGate Integrated Extract to exclude specific DDL statements from replication.
Having worked a lot with Oracle Streams, I decided to utilize DBMS_STREAMS_ADM.SET_TAG
for that task.
Configuration¶
I found a relevant MOS document How to exclude ddl in IE (integrated extract) issued from a specific user? (Doc ID 2107293.1) pretty fast.
The document suggested adding TRANLOGOPTIONS EXCLUDETAG
to an extract parameter file, and then all DDL statements preceding with DBMS_STREAMS_SET.TAG
should not be replicated.
Unfortunately the provided solution did not work for me.
I used OGG Server 12.2.0.1.160823 on Linux x86-64 (which means that I applied the latest bundle patch available at the moment). The issue can be easily reproduced. The database version used in this test was 12.1.0.2.160719. Here are my extract and replicat parameter files:
GGSCI (misha2 as tc_ogg_replicat@db2) 112> view params etag
EXTRACT ETAG
USERIDALIAS db1_tc_ogg_extract
TRANLOGOPTIONS EXCLUDETAG 34
LOGALLSUPCOLS
EXTTRAIL ./dirdat/tc
DDL INCLUDE ALL
TABLE TC.*;
GGSCI (misha2 as tc_ogg_replicat@db2) 113> view params rtag
REPLICAT RTAG
USERIDALIAS db2_tc_ogg_replicat
MAP TC.*, TARGET TC.*;
The test schema TC
will be used for the demonstration, and I setup the extract to exclude any logical change records (LCRs) with tag 34.
Then I am going to create and start the OGG processes with using the following script:
Show
GGSCI (misha2 as tc_ogg_replicat@db2) 138> alter credentialstore add user tc_ogg_extract@db1 password tc_ogg_extract alias db1_tc_ogg_extract
Credential store in ./dircrd/ altered.
GGSCI (misha2 as tc_ogg_replicat@db2) 139> alter credentialstore add user tc_ogg_replicat@db2 password tc_ogg_replicat alias db2_tc_ogg_replicat
Credential store in ./dircrd/ altered.
GGSCI (misha2 as tc_ogg_replicat@db2) 140>
GGSCI (misha2 as tc_ogg_replicat@db2) 140> dblogin useridalias db1_tc_ogg_extract
Successfully logged into database.
GGSCI (misha2 as tc_ogg_extract@db1) 141> add extract etag integrated tranlog begin now
EXTRACT (Integrated) added.
GGSCI (misha2 as tc_ogg_extract@db1) 142> add exttrail ./dirdat/tc extract etag
EXTTRAIL added.
GGSCI (misha2 as tc_ogg_extract@db1) 143> register extract etag database
2016-10-31 12:46:49 INFO OGG-02003 Extract ETAG successfully registered with database at SCN 39029510.
GGSCI (misha2 as tc_ogg_extract@db1) 144>
GGSCI (misha2 as tc_ogg_extract@db1) 146> dblogin useridalias db2_tc_ogg_replicat
Successfully logged into database.
GGSCI (misha2 as tc_ogg_replicat@db2) 147> add replicat rtag , integrated, exttrail ./dirdat/tc
REPLICAT (Integrated) added.
GGSCI (misha2 as tc_ogg_replicat@db2) 148> start extract etag
Sending START request to MANAGER ...
EXTRACT ETAG starting
GGSCI (misha2 as tc_ogg_replicat@db2) 149> start replicat rtag
Sending START request to MANAGER ...
REPLICAT RTAG starting
I used two databases in my setup - db1
and db2
that I call SOURCE
and TARGET
in the rest of this blog post for the sake of clarity.
The extract configured to capture the changes from the SOURCE
database and write data to trail files.
The replicat reads the trail files and applies the changes to the TARGET
database.
Filtering DML¶
Next I am about to run the following code in SOURCE
from which the extract captures changes:
Show
TC@SOURCE> create sequence t_seq;
Sequence created.
TC@SOURCE>
TC@SOURCE> create table t(
2 id int default t_seq.nextval,
3 msg varchar2(10))
4 /
Table created.
TC@SOURCE>
TC@SOURCE> insert into t(msg) values ('NO TAG');
1 row created.
TC@SOURCE> commit;
Commit complete.
TC@SOURCE>
TC@SOURCE> exec dbms_streams_adm.set_tag( hextoraw('12'))
PL/SQL procedure successfully completed.
TC@SOURCE>
TC@SOURCE> insert into t(msg) values ('TAG '||rawtohex(dbms_streams_adm.get_tag));
1 row created.
TC@SOURCE> commit;
Commit complete.
TC@SOURCE>
TC@SOURCE> exec dbms_streams_adm.set_tag( hextoraw('34'))
PL/SQL procedure successfully completed.
TC@SOURCE>
TC@SOURCE> insert into t(msg) values ('TAG '||rawtohex(dbms_streams_adm.get_tag));
1 row created.
TC@SOURCE> commit;
Commit complete.
TC@SOURCE>
TC@SOURCE> exec dbms_streams_adm.set_tag( hextoraw('56'))
PL/SQL procedure successfully completed.
TC@SOURCE>
TC@SOURCE> insert into t(msg) values ('TAG '||rawtohex(dbms_streams_adm.get_tag));
1 row created.
TC@SOURCE> commit;
Commit complete.
Havind done that, I got the following results in the SOURCE
database:
TC@SOURCE> select * from t;
ID MSG
---------- ----------
1 NO TAG
2 TAG 12
3 TAG 34
4 TAG 56
And that is in TARGET
:
TC@TARGET> select * from t order by id;
ID MSG
---------- ----------
1 NO TAG
2 TAG 12
4 TAG 56
Notice that an insert of a record with ID=3, MSG="TAG 34"
was not replicated because we have filtered out that record on the extract side.
Filtering DDL¶
TRANLOGOPTIONS EXCLUDETAG
works flawlessly being executed for DML as it is shown above, but it does not work for DDL:
TC@SOURCE> exec dbms_streams_adm.set_tag( hextoraw('12'))
PL/SQL procedure successfully completed.
TC@SOURCE>
TC@SOURCE> alter table t add tag12 int;
Table altered.
TC@SOURCE>
TC@SOURCE> exec dbms_streams_adm.set_tag( hextoraw('34'))
PL/SQL procedure successfully completed.
TC@SOURCE>
TC@SOURCE> alter table t add tag34 int;
Table altered.
TC@SOURCE> describe t
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NUMBER(38)
MSG VARCHAR2(10)
TAG12 NUMBER(38)
TAG34 NUMBER(38)
I have added two columns to the table and the second one, TAG34
, should not have been replicated.
But in fact, both of the commands were replicated:
TC@TARGET> describe t
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NUMBER(38)
MSG VARCHAR2(10)
TAG12 NUMBER(38)
TAG34 NUMBER(38)
It means that the aforementioned MOS document How to exclude ddl in IE (integrated extract) issued from a specific user? (Doc ID 2107293.1) does not work in that configuration which, by the way, I think is quite typical. Luckily, Oracle Support published another note after we concluded our work on the SR: EXCLUDETAG Issue With Integrated Extract While Excluding DDL For Specific User (Doc ID 2185538.1).
We need to add the following line to the extract parameter file to get it working: TRANLOGOPTIONS _dbfilterddl
GGSCI (misha2 as tc_ogg_replicat@db2) 168> view params etag
EXTRACT ETAG
USERIDALIAS db1_tc_ogg_extract
TRANLOGOPTIONS EXCLUDETAG 34
TRANLOGOPTIONS _dbfilterddl
LOGALLSUPCOLS
EXTTRAIL ./dirdat/tc
DDL INCLUDE ALL
TABLE TC.*;
Once it is added, the same code that adds two columns worked as it should:
TC@SOURCE> describe t
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NUMBER(38)
MSG VARCHAR2(10)
TAG12 NUMBER(38)
TAG34 NUMBER(38)
TC@TARGET> describe t
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NUMBER(38)
MSG VARCHAR2(10)
TAG12 NUMBER(38)
It can be seen that the TAG34
column, being added with tag 34, was not replicated.
There is also a new line in the ggserr.log
file that was not present when I started the extract without _dbfilterddl
: Logmining server DDL filtering enabled.
Show
2016-10-31 13:54:33 INFO OGG-00963 Oracle GoldenGate Manager for Oracle, mgr.prm: Command received from GGSCI on host [172.16.113.245]:57437 (START EXTRACT ETAG ).
2016-10-31 13:54:33 INFO OGG-00960 Oracle GoldenGate Manager for Oracle, mgr.prm: Access granted (rule #6).
2016-10-31 13:54:34 INFO OGG-00992 Oracle GoldenGate Capture for Oracle, etag.prm: EXTRACT ETAG starting.
2016-10-31 13:54:34 INFO OGG-03059 Oracle GoldenGate Capture for Oracle, etag.prm: Operating system character set identified as UTF-8.
2016-10-31 13:54:34 INFO OGG-02695 Oracle GoldenGate Capture for Oracle, etag.prm: ANSI SQL parameter syntax is used for parameter parsing.
2016-10-31 13:54:38 INFO OGG-03522 Oracle GoldenGate Capture for Oracle, etag.prm: Setting session time zone to source database time zone 'GMT'.
2016-10-31 13:54:38 WARNING OGG-04033 Oracle GoldenGate Capture for Oracle, etag.prm: LOGALLSUPCOLS has set the NOCOMPRESSDELETES and GETUPDATEBEFORES parameters on.
2016-10-31 13:54:38 INFO OGG-01815 Oracle GoldenGate Capture for Oracle, etag.prm: Virtual Memory Facilities for: BR
anon alloc: mmap(MAP_ANON) anon free: munmap
file alloc: mmap(MAP_SHARED) file free: munmap
target directories:
/u01/app/oracle/12.2.0.1/ggs/BR/ETAG.
2016-10-31 13:54:38 INFO OGG-01851 Oracle GoldenGate Capture for Oracle, etag.prm: filecaching started: thread ID: 140594853938944.
2016-10-31 13:54:38 INFO OGG-00975 Oracle GoldenGate Manager for Oracle, mgr.prm: EXTRACT ETAG starting.
2016-10-31 13:54:38 INFO OGG-01815 Oracle GoldenGate Capture for Oracle, etag.prm: Virtual Memory Facilities for: COM
anon alloc: mmap(MAP_ANON) anon free: munmap
file alloc: mmap(MAP_SHARED) file free: munmap
target directories:
/u01/app/oracle/12.2.0.1/ggs/dirtmp.
2016-10-31 13:54:58 WARNING OGG-02045 Oracle GoldenGate Capture for Oracle, etag.prm: Database does not have streams_pool_size initialization parameter configured.
2016-10-31 13:54:59 INFO OGG-02248 Oracle GoldenGate Capture for Oracle, etag.prm: Logmining server DDL filtering enabled.
2016-10-31 13:55:08 INFO OGG-02068 Oracle GoldenGate Capture for Oracle, etag.prm: Integrated capture successfully attached to logmining server OGG$CAP_ETAG using OGGCapture API.
2016-10-31 13:55:08 INFO OGG-02089 Oracle GoldenGate Capture for Oracle, etag.prm: Source redo compatibility version is: 12.1.0.2.0.
2016-10-31 13:55:08 INFO OGG-02086 Oracle GoldenGate Capture for Oracle, etag.prm: Integrated Dictionary will be used.
2016-10-31 13:55:09 WARNING OGG-02905 Oracle GoldenGate Capture for Oracle, etag.prm: Replication of OID column in object tables may diverge.
2016-10-31 13:55:09 INFO OGG-00993 Oracle GoldenGate Capture for Oracle, etag.prm: EXTRACT ETAG started.
tl;dr¶
EXCLUDETAG parameter does not work when a tag is set using DBMS_STREAMS_ADM.SET_TAG
in OGG 12.2.0.1.160823.
It prevents replicating only DML commands and does not restrict DDL commands from being replicated.
We can use an underscore parameter _dbfilterddl
in the extract parameter file like in the following line:
TRANLOGOPTIONS _dbfilterddl
This way we restrict both DDL and DML commands from being replicated when the appropriate tag is set (or any in case we use EXCLUDETAG +
in the extract parameter file).