In a recent migration, Data Pump couldn’t validate a foreign key constraint because rows were missing in the parent table.
01-JUN-26 03:12:18.148: W-8 Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/REF_CONSTRAINT
01-JUN-26 03:18:58.517: ORA-39083: Object type REF_CONSTRAINT:"APPUSER"."FK_CHILDTABLE_C001" failed to create with error:
ORA-02298: cannot validate (APPUSER.FK_CHILDTABLE_C001) - parent keys not found
ALTER TABLE "APPUSER"."CHILDTABLE" ADD CONSTRAINT "FK_CHILDTABLE_C001"
FOREIGN KEY ("C001") REFERENCES "APPUSER"."PARENTTABLE" ("C001") ENABLE
In the source database, the constraint was validated. How come rows are now missing?
Data Pump Export
By default, a Data Pump export is not fully consistent. Instead, each table is consistent only within that object. Here’s an example:
| Object | SCN |
|---|---|
| Export starts | 100 |
| Table, T1 | 110 |
| Table, PARENT1 | 120 |
| Table, CHILD1 | 130 |
| Export finishes | 140 |
If no users are connected to the system, the export is logically consistent even though the tables were exported as of different SCNs.
But imagine the following:
- There is a parent/child relationship between PARENT1 and CHILD1 enforced by a foreign key constraint.
- A user inserts data at SCN 125. So, in between the export of PARENT1 and CHILD1.
- Parent row is not exported because PARENT1 is exported as of SCN 120.
- Child row is exported because CHILD1 is exported as of SCN 130.
During import, Data Pump can’t create and validate the foreign key constraint because the parent rows are missing.
GoldenGate
In this specific migration, this wasn’t a real problem because Data Pump and GoldenGate work together.
- On export, Data Pump notes the SCN at which each table were exported.
- On import, Data Pump writes the SCNs into the target database.
- GoldenGate uses Automatic Per Table Instantiation to start the replication from the SCN at which the export was made.
| Object | Replicat starts at SCN |
|---|---|
| Table, T1 | 110 |
| Table, PARENT1 | 120 |
| Table, CHILD1 | 130 |
Once GoldenGate has replicated the changes beyond SCN 125, we could create and validate the constraint.
Zero Downtime Migration (ZDM)
We were doing the migration using ZDM. We had to instruct ZDM to ignore the error using the response file parameter:
IGNOREIMPORTERRORS=ORA-02298,...
Other Solutions
Fully Consistent Export
You can instruct Data Pump to make a fully consistent export, so all tables are exported as of the same SCN. Using the example from above:
| Object | SCN |
|---|---|
| Export starts | 100 |
| Table, T1 | 100 |
| Table, PARENT1 | 100 |
| Table, CHILD1 | 100 |
| Export finishes | 140 |
To do so, add the following parameter:
expdp ... flashback_time=systimestamp
In ZDM, you use the response file parameter:
DATAPUMPSETTINGS_DATAPUMPPARAMETERS_FLASHBACKTIME=SYSTIMESTAMP
This requires that there’s enough UNDO in your database. If your export runs for 4 hours before it reaches CHILD1, then you potentially need a lot of undo to read the table as it looked 4 hours ago.
On an big, active database there is a risk that your export now fails with:
ORA-31693: Table data object "APPUSER"."CHILD1" failed to load/unload and is being skipped due to error:
ORA-02354: error in exporting/importing data
ORA-01555: snapshot too old: rollback segment number 1 with name "_SYSSMU15_987654321$" too small
In which case you should start the export in an off-peak period or from a standby database.
Standby Database
If exporting from your primary database gives you problems with ORA-01555, consider doing it from a snapshot standby database.
If no one is using the standby database, then you don’t even have to perform a fully consistent export using FLASHBACK_SCN or FLASHBACK_TIME.
That’s It
Normally, seeing ORA-02298 during a Data Pump import is a serious problem.
However, if you’re doing an initial load then you can probably validate the constraint once replication starts.
Happy exporting!