When migrating a large database with GoldenGate, most of the volume is sometimes in old partitions which no longer change. A common shortcut is to move them first with expdp/impdp, even before GoldenGate is set up. Everything else, the active partitions and the non-partitioned tables, is exported once the extract is running, with PREPARECSN set. Instantiation filtering then makes the replicat skip what Data Pump already loaded.
However, there is an important aspect here: dba_apply_instantiated_objects has one row per table. Every impdp overwrites it, and there is no way for GoldenGate or Data Pump to know which import should be considered the correct one for populating the dba_apply_instantiated_objects view. The old partitions and the live data of a table share that row, so in a multi-import initial load the last import always wins.
Standard scenario: importing old partitions first
The old partitions of all partitioned tables are moved first, in one dump, before GoldenGate is involved. Since no GoldenGate extract exists yet, PREPARECSN has not run either:
$ expdp sales/***@PDB1 dumpfile=old_part.dmp tables=SALES.ORDERS_PART:P_OLD,SALES.ITEMS_PART:P_OLD
. . exported "SALES"."ITEMS_PART":"P_OLD" 5.523 KB 5 rows
. . exported "SALES"."ORDERS_PART":"P_OLD" 5.523 KB 5 rows
Job "SALES"."SYS_EXPORT_TABLE_01" successfully completed at Sun Oct 11 13:52:08 2026 elapsed 0 00:00:10
$ impdp sales/***@PDB2 dumpfile=old_part.dmp
. . imported "SALES"."ITEMS_PART":"P_OLD" 5.523 KB 5 rows
. . imported "SALES"."ORDERS_PART":"P_OLD" 5.523 KB 5 rows
Job "SALES"."SYS_IMPORT_FULL_01" successfully completed at Sun Oct 11 13:52:12 2026 elapsed 0 00:00:02
Querying the instantiation view on the target returns nothing, as expected:
SQL> SELECT source_database, source_object_name, instantiation_scn
FROM dba_apply_instantiated_objects
WHERE source_object_owner = 'SALES';
no rows selected
Data Pump only populates this view when the table was prepared with PREPARECSN before the export. These first imports are invisible to GoldenGate.
Starting the extract
The extract connects to PDB1 and captures the SALES schema into the trail pt. It is added, registered and started in the adminclient, logged in to PDB1. The registration SCN is where capture begins:
OGG (http://localhost:7810 ogg_test_01) 2> DBLOGIN USERIDALIAS oggadmin_pdb1 DOMAIN OracleGoldenGate
Successfully logged into database PDB1.
OGG (http://localhost:7810 ogg_test_01 as oggadmin_pdb1@CDB01/PDB1) 3> ADD EXTRACT EXTPT, INTEGRATED TRANLOG, BEGIN NOW
2026-10-11T13:52:13Z INFO OGG-08100 Integrated Extract added.
OGG (http://localhost:7810 ogg_test_01 as oggadmin_pdb1@CDB01/PDB1) 4> REGISTER EXTRACT EXTPT DATABASE
2026-10-11T13:52:14Z INFO OGG-02003 Extract group EXTPT successfully registered with database at SCN 189554050.
OGG (http://localhost:7810 ogg_test_01 as oggadmin_pdb1@CDB01/PDB1) 5> ADD EXTTRAIL pt, EXTRACT EXTPT
2026-10-11T13:52:14Z INFO OGG-08100 EXTTRAIL added.
OGG (http://localhost:7810 ogg_test_01 as oggadmin_pdb1@CDB01/PDB1) 6> VIEW PARAMS EXTPT
EXTRACT EXTPT
USERIDALIAS oggadmin_pdb1 DOMAIN OracleGoldenGate
EXTTRAIL pt
TABLE SALES.*;
OGG (http://localhost:7810 ogg_test_01 as oggadmin_pdb1@CDB01/PDB1) 7> START EXTRACT EXTPT
2026-10-11T13:52:14Z INFO OGG-00975 Extract group EXTPT starting.
2026-10-11T13:52:14Z INFO OGG-15426 Extract group EXTPT started.
Some workload follows on the live data, before PREPARECSN:
SQL> INSERT INTO sales.orders_part VALUES (1001, 'ACTIVE');
1 row created.
SQL> INSERT INTO sales.orders_part VALUES (1002, 'ACTIVE');
1 row created.
SQL> INSERT INTO sales.items_part VALUES (1001, 'ACTIVE');
1 row created.
SQL> INSERT INTO sales.items_part VALUES (1002, 'ACTIVE');
1 row created.
SQL> INSERT INTO sales.customers VALUES (4, 'LIVE');
1 row created.
SQL> COMMIT;
Commit complete.
Then the schema is prepared in the adminclient. ADD SCHEMATRANDATA ... ALLCOLS sets PREPARECSN on the schema in NOWAIT mode:
OGG (http://localhost:7810 ogg_test_01) 2> DBLOGIN USERIDALIAS oggadmin_pdb1 DOMAIN OracleGoldenGate
Successfully logged into database PDB1.
OGG (http://localhost:7810 ogg_test_01 as oggadmin_pdb1@CDB01/PDB1) 3> ADD SCHEMATRANDATA SALES ALLCOLS
2026-10-11T13:52:15Z INFO OGG-01788 SCHEMATRANDATA has been added on schema "SALES".
2026-10-11T13:52:15Z INFO OGG-01976 SCHEMATRANDATA for scheduling columns has been added on schema "SALES".
2026-10-11T13:52:15Z INFO OGG-01977 SCHEMATRANDATA for all columns has been added on schema "SALES".
2026-10-11T13:52:15Z INFO OGG-10154 Schema level PREPARECSN set to mode NOWAIT on schema "SALES"
Exporting and importing the live data
The active partitions are exported next, in a single expdp, deliberately without FLASHBACK_SCN. Data Pump chooses a consistent SCN itself, for each table:
$ expdp sales/***@PDB1 dumpfile=active_part.dmp tables=SALES.ORDERS_PART:P_ACTIVE,SALES.ITEMS_PART:P_ACTIVE
FLASHBACK automatically enabled to preserve database integrity.
. . exported "SALES"."ITEMS_PART":"P_ACTIVE" 5.5 KB 2 rows
. . exported "SALES"."ORDERS_PART":"P_ACTIVE" 5.5 KB 2 rows
Job "SALES"."SYS_EXPORT_TABLE_01" successfully completed at Sun Oct 11 13:52:29 2026 elapsed 0 00:00:12
Live inserts after that export are therefore not in the dump:
SQL> INSERT INTO sales.orders_part VALUES (1003, 'ACTIVE');
1 row created.
SQL> INSERT INTO sales.items_part VALUES (1003, 'ACTIVE');
1 row created.
SQL> COMMIT;
Commit complete.
Every other table goes in a third export, at the schema level, excluding the partitioned tables. Any number of normal tables fits in this one export, and a new partitioned table is added to the exclusion:
$ cat rest.par
dumpfile=rest.dmp
schemas=SALES
exclude=TABLE:"IN ('ORDERS_PART','ITEMS_PART')"
$ expdp sales/***@PDB1 parfile=rest.par
FLASHBACK automatically enabled to preserve database integrity.
. . exported "SALES"."CUSTOMERS" 5.515 KB 4 rows
Job "SALES"."SYS_EXPORT_SCHEMA_01" successfully completed at Sun Oct 11 13:52:55 2026 elapsed 0 00:00:24
A live insert after this export is not in the dump either:
SQL> INSERT INTO sales.customers VALUES (5, 'LIVE');
1 row created.
SQL> COMMIT;
Commit complete.
The partitioned tables already exist on the target, so the active partitions are appended. A regular import creates the normal tables:
$ impdp sales/***@PDB2 dumpfile=active_part.dmp table_exists_action=append
Table "SALES"."ORDERS_PART" exists. Data will be appended to existing table but all dependent metadata will be skipped due to table_exists_action of append
Table "SALES"."ITEMS_PART" exists. Data will be appended to existing table but all dependent metadata will be skipped due to table_exists_action of append
. . imported "SALES"."ITEMS_PART":"P_ACTIVE" 5.5 KB 2 rows
. . imported "SALES"."ORDERS_PART":"P_ACTIVE" 5.5 KB 2 rows
Job "SALES"."SYS_IMPORT_FULL_01" successfully completed at Sun Oct 11 13:53:00 2026 elapsed 0 00:00:03
$ impdp sales/***@PDB2 dumpfile=rest.dmp
. . imported "SALES"."CUSTOMERS" 5.515 KB 4 rows
Job "SALES"."SYS_IMPORT_FULL_01" successfully completed at Sun Oct 11 13:53:04 2026 elapsed 0 00:00:02
The instantiation view now has one row per table. The partitioned tables have SCNs from the second export, while CUSTOMERS has one from the third export:
SQL> SELECT source_database, source_object_name, instantiation_scn
FROM dba_apply_instantiated_objects
WHERE source_object_owner = 'SALES'
ORDER BY source_object_name;
SOURCE_DATABASE SOURCE_OBJECT_NAME INSTANTIATION_SCN
--------------- ------------------ -----------------
PDB1 CUSTOMERS 189585331
PDB1 ITEMS_PART 189572011
PDB1 ORDERS_PART 189572008
3 rows selected.
Replicat with instantiation filtering
Each instantiation SCN applies to the whole table, and we use instantiation filtering in the replicat. It is added and started in the adminclient:
OGG (http://localhost:7810 ogg_test_01) 2> DBLOGIN USERIDALIAS oggadmin_pdb2 DOMAIN OracleGoldenGate
Successfully logged into database PDB2.
OGG (http://localhost:7810 ogg_test_01 as oggadmin_pdb2@CDB02/PDB2) 3> ADD REPLICAT REPPT, INTEGRATED, EXTTRAIL pt, CHECKPOINTTABLE OGGADMIN.CHECKPOINT
2026-10-11T13:53:05Z INFO OGG-08100 Integrated Replicat added.
OGG (http://localhost:7810 ogg_test_01 as oggadmin_pdb2@CDB02/PDB2) 4> VIEW PARAMS REPPT
REPLICAT REPPT
DBOPTIONS ENABLE_INSTANTIATION_FILTERING
USERIDALIAS oggadmin_pdb2 DOMAIN OracleGoldenGate
MAP SALES.*, TARGET SALES.*;
OGG (http://localhost:7810 ogg_test_01 as oggadmin_pdb2@CDB02/PDB2) 5> START REPLICAT REPPT
2026-10-11T13:53:05Z INFO OGG-00975 Replicat group REPPT starting.
2026-10-11T13:53:05Z INFO OGG-15445 Replicat group REPPT started.
Once the replicat has caught up, the target tables have the same number of rows as the source:
SQL> SELECT COUNT(*) FROM sales.orders_part;
COUNT(*)
--------
8
1 row selected.
SQL> SELECT COUNT(*) FROM sales.items_part;
COUNT(*)
--------
8
1 row selected.
SQL> SELECT COUNT(*) FROM sales.customers;
COUNT(*)
--------
5
1 row selected.
In the adminclient, we can see the transaction done after creating the extract, on each table:
OGG (http://localhost:7810 ogg_test_01) 2> STATS REPLICAT REPPT, TOTAL, TABLE SALES.*
Sending STATS TOTAL TABLE SALES.* request to Replicat group REPPT ...
Start of statistics at 2026-10-11 13:53:18.
Integrated Replicat statistics:
Total transactions 2.00
Redirected 0.00
Replicated procedures 0.00
DDL operations 0.00
Stored procedures 0.00
Datatype functionality 0.00
Operation type functionality 0.00
Event actions 0.00
Database compatibility 0.00
Direct transactions ratio 0.00%
Replicating from SALES.ORDERS_PART to PDB2.SALES.ORDERS_PART:
*** Total statistics since 2026-10-11 13:53:07 ***
Total inserts 1.00
Total updates 0.00
Total deletes 0.00
Total upserts 0.00
Total discards 0.00
Total operations 1.00
Replicating from SALES.ITEMS_PART to PDB2.SALES.ITEMS_PART:
*** Total statistics since 2026-10-11 13:53:07 ***
Total inserts 1.00
Total updates 0.00
Total deletes 0.00
Total upserts 0.00
Total discards 0.00
Total operations 1.00
Replicating from SALES.CUSTOMERS to PDB2.SALES.CUSTOMERS:
*** Total statistics since 2026-10-11 13:53:07 ***
Total inserts 1.00
Total updates 0.00
Total deletes 0.00
Total upserts 0.00
Total discards 0.00
Total operations 1.00
End of statistics.
The only inserts are the three rows added after the exports, one per table. There is no ORA-00001: the rows inserted before the exports were replayed from the trail and skipped by the instantiation filtering. Without ENABLE_INSTANTIATION_FILTERING they would have hit the primary key.
FLASHBACK_SCN is not needed here. The replicat compares commit CSNs against instantiation_scn, not against the export’s flashback point. You only need PREPARECSN to have run before the export of the live data.
Foreign keys between tables that are in different exports are something to keep in mind.
Wrong order: importing old partitions after
What happens if, for some reason, you run the initial load of the active partitions first, with PREPARECSN and instantiation filtering, and then migrate the old partitions? Let’s try this, by first adding trandata:
OGG (http://localhost:7810 ogg_test_01) 2> DBLOGIN USERIDALIAS oggadmin_pdb1 DOMAIN OracleGoldenGate
Successfully logged into database PDB1.
OGG (http://localhost:7810 ogg_test_01 as oggadmin_pdb1@CDB01/PDB1) 3> ADD TRANDATA SALES.ORDERS_PART PREPARECSN NOWAIT
2026-10-11T13:53:42Z INFO OGG-15132 Logging of supplemental redo data enabled for table SALES.ORDERS_PART.
2026-10-11T13:53:42Z INFO OGG-15133 TRANDATA for scheduling columns has been added on table SALES.ORDERS_PART.
2026-10-11T13:53:42Z INFO OGG-15438 Enabling logical replication (with all keys) on auto capture table SALES.ORDERS_PART.
2026-10-11T13:53:42Z INFO OGG-15135 TRANDATA for instantiation CSN has been added on table SALES.ORDERS_PART.
The old partitions are exported before the extract exists:
$ expdp sales/***@PDB1 dumpfile=b_old.dmp tables=SALES.ORDERS_PART:P_OLD
FLASHBACK automatically enabled to preserve database integrity.
. . exported "SALES"."ORDERS_PART":"P_OLD" 5.523 KB 5 rows
Job "SALES"."SYS_EXPORT_TABLE_01" successfully completed at Sun Oct 11 13:53:55 2026 elapsed 0 00:00:11
The extract is then registered and started, as in the first scenario:
OGG (http://localhost:7810 ogg_test_01) 2> DBLOGIN USERIDALIAS oggadmin_pdb1 DOMAIN OracleGoldenGate
Successfully logged into database PDB1.
OGG (http://localhost:7810 ogg_test_01 as oggadmin_pdb1@CDB01/PDB1) 3> ADD EXTRACT EXTPT, INTEGRATED TRANLOG, BEGIN NOW
2026-10-11T13:53:57Z INFO OGG-08100 Integrated Extract added.
OGG (http://localhost:7810 ogg_test_01 as oggadmin_pdb1@CDB01/PDB1) 4> REGISTER EXTRACT EXTPT DATABASE
2026-10-11T13:54:00Z INFO OGG-02003 Extract group EXTPT successfully registered with database at SCN 189596053.
OGG (http://localhost:7810 ogg_test_01 as oggadmin_pdb1@CDB01/PDB1) 5> ADD EXTTRAIL pt, EXTRACT EXTPT
2026-10-11T13:54:00Z INFO OGG-08100 EXTTRAIL added.
OGG (http://localhost:7810 ogg_test_01 as oggadmin_pdb1@CDB01/PDB1) 6> START EXTRACT EXTPT
2026-10-11T13:54:00Z INFO OGG-00975 Extract group EXTPT starting.
2026-10-11T13:54:00Z INFO OGG-15426 Extract group EXTPT started.
Rows 1001 and 1002 are inserted into P_ACTIVE, and the live data is exported. Row 1003 is inserted after the export:
$ expdp sales/***@PDB1 dumpfile=b_active.dmp tables=SALES.ORDERS_PART:P_ACTIVE
FLASHBACK automatically enabled to preserve database integrity.
. . exported "SALES"."ORDERS_PART":"P_ACTIVE" 5.5 KB 2 rows
Job "SALES"."SYS_EXPORT_TABLE_01" successfully completed at Sun Oct 11 13:54:09 2026 elapsed 0 00:00:08
This time, on the target, the live data is imported first:
$ impdp sales/***@PDB2 dumpfile=b_active.dmp
. . imported "SALES"."ORDERS_PART":"P_ACTIVE" 5.5 KB 2 rows
Job "SALES"."SYS_IMPORT_FULL_01" successfully completed at Sun Oct 11 13:54:14 2026 elapsed 0 00:00:02
For now, the boundary is above the registration SCN 189596053:
SQL> SELECT source_object_name, instantiation_scn
FROM dba_apply_instantiated_objects
WHERE source_object_owner = 'SALES'
AND source_object_name = 'ORDERS_PART';
SOURCE_OBJECT_NAME INSTANTIATION_SCN
------------------ -----------------
ORDERS_PART 189610870
1 row selected.
The old partitions are then imported:
$ impdp sales/***@PDB2 dumpfile=b_old.dmp table_exists_action=append
Table "SALES"."ORDERS_PART" exists. Data will be appended to existing table but all dependent metadata will be skipped due to table_exists_action of append
. . imported "SALES"."ORDERS_PART":"P_OLD" 5.523 KB 5 rows
Job "SALES"."SYS_IMPORT_FULL_01" successfully completed at Sun Oct 11 13:54:17 2026 elapsed 0 00:00:01
If we check the table again, the boundary is now below the registration SCN, and more importantly below the instantiation SCN of the live data !
SQL> SELECT source_object_name, instantiation_scn
FROM dba_apply_instantiated_objects
WHERE source_object_owner = 'SALES'
AND source_object_name = 'ORDERS_PART';
SOURCE_OBJECT_NAME INSTANTIATION_SCN
------------------ -----------------
ORDERS_PART 189594418
1 row selected.
This means that a replicat using instantiation filtering will not filter the transactions which happened before the first import. If we add the replicat in the adminclient, and start it:
OGG (http://localhost:7810 ogg_test_01) 2> DBLOGIN USERIDALIAS oggadmin_pdb2 DOMAIN OracleGoldenGate
Successfully logged into database PDB2.
OGG (http://localhost:7810 ogg_test_01 as oggadmin_pdb2@CDB02/PDB2) 3> ADD REPLICAT REPPT, INTEGRATED, EXTTRAIL pt, CHECKPOINTTABLE OGGADMIN.CHECKPOINT
2026-10-11T13:54:19Z INFO OGG-08100 Integrated Replicat added.
OGG (http://localhost:7810 ogg_test_01 as oggadmin_pdb2@CDB02/PDB2) 4> START REPLICAT REPPT
2026-10-11T13:54:19Z INFO OGG-00975 Replicat group REPPT starting.
2026-10-11T13:54:19Z INFO OGG-15445 Replicat group REPPT started.
The replicat reads the instantiation SCN 189594418 from the target. It is now older than the live data export, so the transactions that export already contains are no longer filtered, and the replicat fails on the first trail record:
OGG (http://localhost:7810 ogg_test_01) 2> INFO REPLICAT REPPT
Replicat REPPT Last Started 2026-10-11 13:54 Status ABENDED
INTEGRATED
Checkpoint Lag 00:00:00 (updated 00:00:19 ago)
Log Read Checkpoint File pt000000000
First Record RBA 0
Encryption Profile LocalWallet
The replicat report shows the boundary and the error:
2026-10-11 13:54:25 INFO OGG-10155 Instantiation CSN filtering is enabled on table SALES.ORDERS_PART at CSN 189,594,418.
2026-10-11 13:54:31 WARNING OGG-02544 Unhandled error (ORA-00001: unique constraint (.) violated
ORA-00001: unique constraint (SALES.SYS_C0010450) violated) while processing the record at SEQNO 0, RBA 1793 in Integrated mode. REPLICAT will retry in Direct mode.
1001 and 1002 were already on the target from the live-data import, but their commit CSNs are now above the boundary.
Conclusion
instantiation_scnis per table, not per partition. The lastimpdpwill decide the boundary being used by instantiation filtering.impdpoverwrites it unconditionally, with no warning.- When using instantiation filtering, always import the dump which should contain the boundary last.
- Keep in mind that, depending on the context of your real replication, another instantiation method might be needed. Foreign keys, DDL replication, or many aspects a GoldenGate replication might need to address, were not covered in this blog.