Oracle E-Business Suite (EBS) Archival Playbook - DBA Companion

Oracle E-Business Suite (EBS) Data Pump Migration Playbook for Archive DBAs

A DBA-focused playbook for moving historical Oracle E-Business Suite (EBS) data from an on-premises Oracle E-Business Suite (EBS) database into OCI Autonomous Data Warehouse. The goal is not to clone Oracle E-Business Suite (EBS). The goal is a validated, secure, reporting-ready archive for EBSArchive, audit access, historical inquiry, analytics, and eventual Oracle E-Business Suite (EBS) retirement.

What This Playbook Covers

Use this document when the OCI foundation exists and the DBA team needs a repeatable migration path: CPAT readiness, source sizing, character set checks, metadata export, data export, Object Storage staging, ADW import, row-count validation, and read-only hardening.

It intentionally stays at the database layer. Infrastructure setup belongs in the OCI build playbook. APEX reports, attachments, SSO behavior, and module authorization belong in the application playbook.

Who This Playbook Is For

This playbook is for the Oracle DBA who owns the source Oracle E-Business Suite (EBS) database, knows the real size and workload, and needs a repeatable path to move history into ADW for reporting. You export from source Oracle E-Business Suite (EBS), stage in Object Storage, import into ADW, validate row counts, and secure the target for read-only archive access.

Source

An on-premises Oracle E-Business Suite (EBS) database that is no longer used for new transactions but still contains historical records, attachments, and audit evidence.

Target

OCI Autonomous Data Warehouse, sized after source discovery and deployed as the customer-owned archive database for SQL, APEX reports, secure downloads, and future analytics on Oracle E-Business Suite (EBS) history.

Outcome

A validated archive that preserves business access to old invoices, journals, suppliers, projects, HR records, purchase orders, and supporting documents without keeping the full Oracle E-Business Suite (EBS) stack alive.

Playbook Map

Use these links as checkpoints. Each section explains what you are doing, why it happens at that point, and includes copy-ready commands.

Why Choose ADW, Not ATP, For This Archive

Choose ADW because EBSArchive is for historical reporting and analytics, not new transactions. ATP is optimized for transaction processing. ADW is the better fit when the workload is SQL reporting, APEX interactive reports, long scans, aggregations, analytics, columnar/compressed warehouse storage patterns, automatic indexing, and future ML or Select AI use cases on old Oracle E-Business Suite (EBS) history.

Reporting Workload

EBSArchive users search old invoices, journals, suppliers, projects, HR records, and attachments. They are not entering new Oracle E-Business Suite (EBS) transactions, so the archive is tuned for reads, filters, joins, and exports.

Warehouse Features

ADW provides a managed warehouse target with compression, scale, automatic indexing, SQL analytics, and APEX reporting close to the archived Oracle E-Business Suite (EBS) data.

Size Before Creating ADW

Do not create ADW first. Size the source database, active schemas, largest tables, expected dump volume, character set risk, and source CPU/I/O before choosing ADW storage and CPU.

Character Set Decision

Use the same database character set as the source when the target standard allows it. If ADW uses a different character set, treat conversion as a migration risk and test for ORA-12899 before the final load.

Migration Pattern: Metadata First, Data Second

The safest archive migration separates structure from rows. Metadata import reveals ADW compatibility issues early; data import happens after users, grants, indexes, triggers, and constraints are prepared.

Metadata First

Export object definitions before table data. This exposes ADW compatibility issues early, before long data movement starts.

Data Second

Export table data into separate dump pieces. Keep dump files, parfiles, export logs, import logs, and validation results together as the archive handoff package.

High-Level DBA Task Flow

For a 1 TB Oracle E-Business Suite (EBS) database, plan roughly 4-5 days for export/import movement and another 2-3 days for rebuild, validation, security, and audit evidence. Your timing depends on source CPU, I/O, network throughput, dump file count, ADW CPU, and how many compatibility fixes appear during metadata and data import.

CPAT Readiness - 0.5 day

Run CPAT before sizing ADW

Capture compatibility findings, database properties, character-set risk, and objects that need remediation or archive exceptions.

Prepare Export - 0.5 day

Size source and define schema scope

Confirm source size, CPU, filesystem space, largest tables, and active Oracle E-Business Suite (EBS) schemas before writing final parfiles.

Export - 1 to 1.5 days

Export metadata and data separately

Run metadata first, then data with parallelism matched to source capacity. Keep parfiles, dump files, logs, and master-table evidence.

Stage - 0.5 to 1 day

Upload dumps and logs to Object Storage

ADW imports from Object Storage; validation also needs the export logs.

Prepare Import - 0.5 to 1 day

Connect to ADW and create users

Create ADW after sizing, then configure wallet, Object Storage credential, Oracle E-Business Suite (EBS) users, quotas, grants, and metadata fixes.

Import - 1.5 to 2 days

Import metadata, prepare objects, load data

Review metadata errors, make indexes unusable, disable triggers/FKs, then load data with ADW CPU sized for the chosen parallelism.

Finalize - 2 to 3 days

Rebuild, validate, secure, and hand off

Rebuild indexes, enable constraints, reconcile every row-bearing table, document exclusions and invalid objects, lock schemas, and preserve evidence.

Part 1

Export From Source Oracle E-Business Suite (EBS)

Start with CPAT, then size the source, confirm character set and CPU/I/O, create an explicit Oracle directory, export metadata first, export data second, and upload dump files plus logs to Object Storage.

Run CPAT Before ADW Sizing

Run Oracle Cloud Premigration Advisor Tool (CPAT) before final ADW sizing and Data Pump design. CPAT gives the DBA an early inventory of database properties, source settings, compatibility findings, character-set risk, and objects that may need remediation, exclusion, special import handling, or validation before Oracle E-Business Suite (EBS) history is moved into ADW.

Use the current CPAT package documentation for the exact parameter names and target property format. The examples below show the pattern: define the target, run the source assessment, then turn each finding into a migration action or documented archive exception.

Checkpoint evidence: save the CPAT report, target properties, source database version, character set, database size, blocker list, and the decision for each blocker before ADW is provisioned.

Example ADW Target Properties

TargetInstanceProp.DB_BLOCK_SIZE=8192
TargetInstanceProp.DB_PLATFORM_ID=13
TargetInstanceProp.DB_TIME_ZONE=+00\:00
TargetInstanceProp.DB_VERSION=23.26.2.2.0
TargetInstanceProp.DIRECTORIES=DATA_PUMP_DIR,SQL_TCB_DIR
TargetInstanceProp.NLS_CHARACTERSET=AL32UTF8
TargetInstanceProp.NLS_NCHAR_CHARACTERSET=AL16UTF16
TargetInstanceProp.PDB_LOCKDOWN=DWCS
TargetInstanceProp.TABLESPACES=DATA,DBFS_DATA,SAMPLESCHEMA,SYSAUX,SYSTEM,TEMP
TargetInstanceProp.TABLESPACE_BLOCK_SIZE.DATA=8192
TargetInstanceProp.TABLESPACE_BLOCK_SIZE.DBFS_DATA=8192
TargetInstanceProp.TABLESPACE_BLOCK_SIZE.SAMPLESCHEMA=8192
TargetInstanceProp.TABLESPACE_BLOCK_SIZE.SYSAUX=8192
TargetInstanceProp.TABLESPACE_BLOCK_SIZE.SYSTEM=8192
TargetInstanceProp.TABLESPACE_BLOCK_SIZE.TEMP=8192

Example CPAT Parameter File

# cpat-ebs-adw26ai.cfg
connectstring=jdbc:oracle:thin:@ebsdb01.example.com:1521/ebs_pdb
username=SYS
sysdba=true
targetcloud=ADWS
migrationmethod=DATAPUMP
analysisprops=adw-26ai-target-properties.properties
outdir=./cpat-output
outfileprefix=EBS01
reportformat=TEXT,JSON,HTML
full=true

# Run CPAT.
premigration.sh --parfile cpat-ebs-adw26ai.cfg
CPAT Finding DBA Review Archive Decision
XMLType or XML schema objects Identify tables, views, and report dependencies. Import, redesign, or document as not needed for reporting.
Character set conversion Compare source character set with the intended ADW character set. Decide target character set before ADW is created.
LONG, LONG RAW, or datatype issue Confirm whether the affected table is in archive scope. Fix DDL, reload failed table, or document exclusion.
Java objects, libraries, DB links Separate runtime dependencies from reporting dependencies. Usually exclude runtime-only objects; document the reason.
Tablespace or directory assumptions Check whether assumptions affect archive-scope objects. Remap to ADW-safe tablespaces and directories.
A CPAT BLOCKER requires DBA review, but it does not automatically block an archive migration. The archive is not a full Oracle E-Business Suite (EBS) runtime clone. Every finding should be mapped to one outcome: fix before import, handle during import, validate after import, or document as not required for historical inquiry.

Size The Source Before Export

Do not create ADW or start Data Pump until you know the source size, source CPU/I/O, character set, largest schemas, largest tables, and free space on the export filesystem. Use this to choose ADW storage, ADW CPU, and Data Pump parallelism.

If the source uses a single-byte character set and ADW uses AL32UTF8, run DMU, CSSCAN, or the approved enterprise character-set assessment before final load. This is where many ORA-12899 fixes are found before they become import-window surprises.

Sizing SQL

-- Total segment size
select round(sum(bytes)/1024/1024/1024, 2) as db_size_gb
from dba_segments;

-- Largest schemas
select owner,
       round(sum(bytes)/1024/1024/1024, 2) as size_gb
from dba_segments
group by owner
order by size_gb desc;

-- Largest tables
select owner,
       segment_name,
       round(bytes/1024/1024/1024, 2) as size_gb
from dba_segments
where segment_type like 'TABLE%'
order by bytes desc
fetch first 30 rows only;

-- Source character set. Match this in the target when the target standard allows it.
select parameter, value
from nls_database_parameters
where parameter in ('NLS_CHARACTERSET','NLS_NCHAR_CHARACTERSET');

-- Source CPU/process capacity for Data Pump planning.
select name, value
from v$parameter
where name in ('cpu_count','processes','sessions','parallel_max_servers');

Run Character Set Assessment

# Preferred: DMU
# 1. Start DMU from a workstation or database server that can reach source EBS.
# 2. Connect to the source database as SYSDBA or an approved DBA user.
# 3. Set the target character set, for example AL32UTF8.
# 4. Scan the active Oracle E-Business Suite (EBS) schemas.
# 5. Export the report and review invalid data, lossy conversion, and column expansion risk.

cd $ORACLE_HOME/dmu
./dmu

# Fallback for older Oracle homes: CSSCAN.
sqlplus / as sysdba
@$ORACLE_HOME/rdbms/admin/csminst.sql

csscan userid=system full=y tochar=AL32UTF8 array=102400 process=8 log=ebs_csscan

ls -lh ebs_csscan.*
grep -i "exception\|lossy\|truncation\|exceed\|invalid" ebs_csscan.*

Rule of thumb: export filesystem free space should be at least 1.3x expected dump size unless compression has already been tested. For a 1 TB Oracle E-Business Suite (EBS) source, normally plan 4-5 days for prepare, export, upload, import, validation, and hardening.

Gather Stats And Active Oracle E-Business Suite (EBS) Schema List

If the source Oracle E-Business Suite (EBS) instance is no longer the active system after Fusion migration, gather fresh stats before export. Use the resulting row counts to identify the Oracle E-Business Suite (EBS) schemas that actually contain data, then reuse that list for export scope, import scope, disable scripts, and validation.

Gather Oracle E-Business Suite (EBS) Schema Stats

-- Run on the source Oracle E-Business Suite (EBS) database as APPS or a DBA user.
BEGIN
  FOR r IN (
    select oracle_username
    from   applsys.fnd_oracle_userid
    where  read_only_flag in ('A','E','U')
  )
  LOOP
    DBMS_STATS.GATHER_SCHEMA_STATS(
      ownname          => r.oracle_username,
      estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
      cascade          => TRUE
    );
  END LOOP;
END;
/

Create Active Schema List

set heading off feedback off pages 0 trimspool on
spool active_ebs_schemas.txt

select owner
from   dba_tables
where  owner in (
  select oracle_username
  from   applsys.fnd_oracle_userid
  where  read_only_flag in ('A','E','U')
)
and    num_rows > 0
group  by owner
order  by owner;

spool off

-- Review row totals before using the list in export/import parfiles.
select owner,
       count(*) table_count,
       sum(num_rows) total_rows
from   dba_tables
where  owner in (
  select oracle_username
  from   applsys.fnd_oracle_userid
  where  read_only_flag in ('A','E','U')
)
and    num_rows > 0
group  by owner
order  by owner;

Create Filesystem And Oracle Directory

Do not rely on the default DATA_PUMP_DIR. Use a filesystem path with enough space and make the Oracle directory object explicit.

Create Export Directory

df -h
sudo mkdir -p /u01/install/dpump
sudo chown oracle:oinstall /u01/install/dpump
sudo chmod 750 /u01/install/dpump
df -h /u01/install/dpump

Create Oracle Directory

create or replace directory EBS_EXPORT_DIR as '/u01/install/dpump';
grant read, write on directory EBS_EXPORT_DIR to system;

select directory_name, directory_path
from dba_directories
where directory_name = 'EBS_EXPORT_DIR';

The Oracle directory object does not create the OS directory. The filesystem path must already exist and be writable by the Oracle database OS user.

Export Metadata

Metadata export captures object definitions without table rows. In an Oracle E-Business Suite (EBS) archival project, this helps identify unsupported or unnecessary source objects before loading data.

Metadata Parfile

directory=EBS_EXPORT_DIR
dumpfile=ebsdb_metadata_full_%U.dmp
logfile=ebsdb_metadata_full.log
job_name=EBS_META_EXP
full=y
content=metadata_only
parallel=2
filesize=20G
logtime=all
metrics=y
keep_master=y

Run Metadata Export

source /u01/install/APPS/19.0.0/ebscdb_apps.env

nohup expdp system/manager@//localhost:1521/ebsdb \
  parfile=ebsdb_metadata_only_export.par \
  > ebsdb_metadata_only_export.out 2>&1 &

tail -f /u01/install/dpump/ebsdb_metadata_full.log
ls -lh /u01/install/dpump/ebsdb_metadata_full_*.dmp
grep -i "successfully completed\|error\|ora-\|warning" /u01/install/dpump/ebsdb_metadata_full.log

Export Data

Data export captures table rows separately from metadata. Use parallel=8 only when the source database has enough CPU, processes, and I/O headroom. Keep the export log with the dump files; it is part of the evidence trail.

Checkpoint evidence: preserve the data parfile, dump piece count, dump sizes, export log, and any ORA warnings before the files are uploaded to Object Storage.

Data Parfile

directory=EBS_EXPORT_DIR
dumpfile=ebsdb_data_full_%U.dump
logfile=ebsdb_data_full.log
job_name=EBS_DATA_EXP
full=y
content=data_only
parallel=8
filesize=20G
logtime=all
metrics=y
keep_master=y

Run Data Export

nohup expdp system/manager@//localhost:1521/ebsdb \
  parfile=ebsdb_data_only_export.par \
  > ebsdb_data_only_export.out 2>&1 &

tail -f /u01/install/dpump/ebsdb_data_full.log
ls -lh /u01/install/dpump/ebsdb_data_full_*.dump
grep -i "successfully completed\|error\|ora-\|warning" /u01/install/dpump/ebsdb_data_full.log

Upload Dumps To Object Storage

For enterprise use, prefer instance principals, a controlled transfer host, or a temporary pre-authenticated request. The API-key method below is useful for a lab, but do not publish or share private keys.

Checkpoint evidence: preserve the Object Storage listing, namespace, bucket name, dump piece count, dump sizes, and uploaded export logs before starting the ADW import.

Install And Configure OCI CLI

bash -c "$(curl -L https://raw.githubusercontent.com/oracle/oci-cli/master/scripts/install/install.sh)"
source ~/.bashrc
oci --version

mkdir -p ~/.oci
chmod 700 ~/.oci
vi ~/.oci/config
chmod 600 ~/.oci/config
chmod 600 ~/.oci/oci_api_key.pem

oci os ns get

OCI CLI Config Template

[DEFAULT]
user=<user_ocid>
fingerprint=<api_key_fingerprint>
tenancy=<tenancy_ocid>
region=<oci_region>
key_file=/home/oracle/.oci/oci_api_key.pem

Upload And Verify

oci os object put --bucket-name ebsdump --file /u01/install/dpump/ebsdb_metadata_full_01.dmp --name ebsdb_metadata_full_01.dmp
oci os object put --bucket-name ebsdump --file /u01/install/dpump/ebsdb_metadata_full_02.dmp --name ebsdb_metadata_full_02.dmp
oci os object put --bucket-name ebsdump --file /u01/install/dpump/ebsdb_metadata_full.log --name ebsdb_metadata_full.log

oci os object put --bucket-name ebsdump --file /u01/install/dpump/ebsdb_data_full_01.dump --name ebsdb_data_full_01.dump
oci os object put --bucket-name ebsdump --file /u01/install/dpump/ebsdb_data_full_02.dump --name ebsdb_data_full_02.dump
oci os object put --bucket-name ebsdump --file /u01/install/dpump/ebsdb_data_full.log --name ebsdb_data_full.log

oci os object list \
  --bucket-name ebsdump \
  --query "data[].{name:name,size:size}" \
  --output table

Part 2

Import Into ADW

Create ADW only after CPAT review and source sizing are complete. Then connect, create the Object Storage credential, clean Oracle E-Business Suite (EBS) user DDL, import metadata, review compatibility errors, import data, and validate the archive scope.

Before The Import Window

Complete these checks before importing into ADW so you can recover from test runs, explain expected exclusions, and avoid treating known compatibility issues as surprises.

  • Create the ADW only after CPAT review and source sizing. Set storage from database size and expected growth, and set CPU high enough for the chosen Data Pump import parallelism.
  • Match the source database character set when the target standard allows it. If the target character set differs, test conversion issues before the final load.
  • Review CPAT output from the first step. Unsupported or risky objects such as LONG columns and character-set findings should already have a fix, import approach, or documented archive exception.
  • Record the ADW backup/restore point approach before any destructive test import. Test imports used to discover ADW compatibility issues should be recoverable.
  • If a test import is used to discover table-level errors, restore ADW to the clean point before the final import. Do not continue final migration from a partially tested target.
  • Keep a timestamp for each major step: user creation, metadata import, grant fixes, data import, and validation.

Connect Your Workstation Or Bastion To ADW

Use a controlled host that can reach the private ADW endpoint: a corporate VPN host, temporary bastion session, or approved import compute instance. Download the ADW wallet, set TNS_ADMIN, and verify SQL*Plus and Data Pump before running imports.

If SQL*Plus reaches the wallet but the listener rejects the connection, check the ADW private endpoint access controls, network path, DNS, and service ACL settings before troubleshooting Data Pump.

Install Client Tools On The Import Host

# Oracle Linux example. Use your enterprise package process for production hosts.
sudo dnf install -y oracle-instantclient-release-el8
sudo dnf install -y oracle-instantclient-basic oracle-instantclient-sqlplus oracle-instantclient-tools
sudo dnf install -y screen unzip

sqlplus -v
impdp help=y

Download And Prepare Wallet

# Console path:
# Autonomous Database > DB Connection > Download wallet

# OCI CLI option:
oci db autonomous-database generate-wallet \
  --autonomous-database-id <adw_ocid> \
  --password '<wallet_password>' \
  --file Wallet_EBSARCHIVE.zip

mkdir -p /home/oracle/adw_wallet
unzip Wallet_EBSARCHIVE.zip -d /home/oracle/adw_wallet
chmod 600 /home/oracle/adw_wallet/*

# If needed, verify sqlnet.ora points to this wallet directory.
grep WALLET_LOCATION /home/oracle/adw_wallet/sqlnet.ora

Test ADW Wallet And Data Pump

export TNS_ADMIN=/home/oracle/adw_wallet
sqlplus admin/'<adw_admin_password>'@<adw_service_name>
impdp admin/'<adw_admin_password>'@<adw_service_name> help=y

Create Object Storage Credential

-- Option A: auth token style credential
BEGIN
  DBMS_CLOUD.CREATE_CREDENTIAL(
    credential_name => 'EBSDUMP_CRED',
    username        => '<oci_user_name_or_federated_user>',
    password        => '<oci_auth_token>'
  );
END;
/

-- Option B: API key style credential
BEGIN
  DBMS_CLOUD.CREATE_CREDENTIAL(
    credential_name => 'EBSDUMP_CRED',
    user_ocid       => '<user_ocid>',
    tenancy_ocid    => '<tenancy_ocid>',
    private_key     => '<private_key_text>',
    fingerprint     => '<api_key_fingerprint>'
  );
END;
/

Confirm ADW Data Pump Files

-- Files written by Data Pump into ADW DATA_PUMP_DIR, including SQLFILE output and logs.
select object_name, bytes, checksum, created
from table(dbms_cloud.list_files('DATA_PUMP_DIR'))
order by created desc;

Extract And Create Oracle E-Business Suite (EBS) Users

Use Data Pump SQLFILE to extract user DDL from the Object Storage metadata dump without importing objects. Clean the generated SQL against the reviewed active_ebs_schemas.txt list created during source discovery.

Extract User DDL With SQLFILE

-- create extract_ebs_users.par
directory=DATA_PUMP_DIR
credential=EBSDUMP_CRED
dumpfile=https://objectstorage.<region>.oraclecloud.com/n/<namespace>/b/<bucket>/o/ebsdb_metadata_full_%U.dmp
job_name=EBS_USERS_SQLFILE
sqlfile=create_ebs_users.sql
full=y
include=user
logtime=all
metrics=y
keep_master=y

Starter Cleanup Script

#!/usr/bin/env bash
set -euo pipefail

# Inputs from previous steps:
# - create_ebs_users.sql             generated by impdp SQLFILE
# - active_ebs_schemas.txt           generated during source schema discovery
# - optional_custom_schemas.txt      optional custom archive schemas reviewed with the app owner

TEMP_PASSWORD='<approved_temporary_password>'
KEEP_FILE='ebs_users_keep_final.txt'
SOURCE_SQL='create_ebs_users.sql'
CLEAN_SQL='create_ebs_users_clean.sql'
REJECT_SQL='create_ebs_users_rejected_for_review.sql'

# Build final keep list. Edit this file before continuing.
cat active_ebs_schemas.txt optional_custom_schemas.txt 2>/dev/null \
  | sed 's/[[:space:]]//g' \
  | grep -E '^[A-Z0-9_#$]+$' \
  | sort -u > "$KEEP_FILE"

vi "$KEEP_FILE"

# Keep CREATE/ALTER/GRANT statements only for approved schemas.
# Put removed user DDL into a reject file for audit/review.
awk -v keep="$KEEP_FILE" '
  BEGIN {
    while ((getline u < keep) > 0) allow[u]=1
  }
  {
    line=$0
    user=""
    if (match(line, /"(.[^"]*)"/, m)) user=m[1]
    else if (match(line, /(CREATE|ALTER|GRANT)[[:space:]]+(USER|CONNECT|RESOURCE|CONNECT, RESOURCE TO)[[:space:]]+([A-Z0-9_#$]+)/, m)) user=m[3]

    if (user == "" || allow[user]) print line > "create_ebs_users_keep.tmp"
    else print line > "create_ebs_users_reject.tmp"
  }
' "$SOURCE_SQL"

# Remove source tablespace/quota clauses and replace passwords.
sed -E \
  -e 's/DEFAULT TABLESPACE [^ ]+//Ig' \
  -e 's/TEMPORARY TABLESPACE [^ ]+//Ig' \
  -e 's/QUOTA [^;]+ ON [^;]+//Ig' \
  -e 's/IDENTIFIED BY VALUES '\''[^'\'']+'\''/IDENTIFIED BY "'$TEMP_PASSWORD'"/Ig' \
  -e 's/IDENTIFIED BY "[^"]+"/IDENTIFIED BY "'$TEMP_PASSWORD'"/Ig' \
  create_ebs_users_keep.tmp > "$CLEAN_SQL"

mv create_ebs_users_reject.tmp "$REJECT_SQL" 2>/dev/null || touch "$REJECT_SQL"
rm -f create_ebs_users_keep.tmp

# Add edition enablement for kept Oracle E-Business Suite (EBS) users.
# Grant DATA quota separately after users exist.
{
  echo ""
  echo "-- Review before execution: enable editions for required Oracle E-Business Suite (EBS) schemas."
  while read -r user; do
    if [ "$user" != "APPS" ]; then
      echo "ALTER USER $user ENABLE EDITIONS;"
    fi
  done < "$KEEP_FILE"
} >> "$CLEAN_SQL"

echo "Review before running:"
echo "  $CLEAN_SQL"
echo "  $REJECT_SQL"

Run Extraction, Download, Clean, And Create Users

export TNS_ADMIN=/home/oracle/adw_wallet
impdp admin/'<adw_admin_password>'@<adw_service_name> parfile=extract_ebs_users.par

# The SQLFILE is created inside ADW DATA_PUMP_DIR.
# Upload it from ADW DATA_PUMP_DIR to Object Storage.
sqlplus admin/'<adw_admin_password>'@<adw_service_name> <<SQL
BEGIN
  DBMS_CLOUD.PUT_OBJECT(
    credential_name => 'EBSDUMP_CRED',
    object_uri      => 'https://objectstorage.<region>.oraclecloud.com/n/<namespace>/b/<bucket>/o/create_ebs_users.sql',
    directory_name  => 'DATA_PUMP_DIR',
    file_name       => 'create_ebs_users.sql'
  );
END;
/
SQL

# Download the SQL file to the bastion/workstation for review.
oci os object get \
  --bucket-name <bucket> \
  --name create_ebs_users.sql \
  --file create_ebs_users.sql

# Review and clean the downloaded file before running it:
# 1. Keep users listed in active_ebs_schemas.txt.
# 2. Add approved custom schemas in optional_custom_schemas.txt when needed.
# 3. Remove Oracle-maintained, monitoring, personal, backup, and non-Oracle E-Business Suite (EBS) users.
# 4. Remove source tablespace clauses and quotas that do not apply to ADW.
# 5. Replace generated passwords with approved temporary passwords.
# 6. Keep or add ALTER USER ... ENABLE EDITIONS for required Oracle E-Business Suite (EBS) schemas.
chmod +x clean_ebs_users_sql.sh
./clean_ebs_users_sql.sh
vi create_ebs_users_clean.sql
vi create_ebs_users_rejected_for_review.sql

sqlplus admin/'<adw_admin_password>'@<adw_service_name> @create_ebs_users_clean.sql

sqlplus admin/'<adw_admin_password>'@<adw_service_name> <<SQL
select username, account_status, editions_enabled
from dba_users
where username in ('APPS','APPLSYS','GL','AP','AR','PO','FA','CE','HR')
order by username;
SQL

Grant DATA Tablespace Quota

# Run after create_ebs_users_clean.sql completes successfully.
awk '{print "ALTER USER " $1 " QUOTA UNLIMITED ON DATA;"}' \
  ebs_users_keep_final.txt > grant_ebs_user_quota.sql

export TNS_ADMIN=/home/oracle/adw_wallet
sqlplus admin/'<adw_admin_password>'@<adw_service_name> @grant_ebs_user_quota.sql

sqlplus admin/'<adw_admin_password>'@<adw_service_name> <<SQL
select username, tablespace_name, max_bytes
from dba_ts_quotas
where tablespace_name = 'DATA'
and username in ('APPS','APPLSYS','GL','AP','AR','PO','FA','CE','HR')
order by username;
SQL

Import Metadata

Import metadata before data. Expect some Oracle E-Business Suite (EBS) object types to fail in ADW; separate acceptable archive exclusions from real import blockers before loading rows.

Metadata Import Parfile

directory=DATA_PUMP_DIR
credential=EBSDUMP_CRED
dumpfile=https://objectstorage.<region>.oraclecloud.com/n/<namespace>/b/<bucket>/o/ebsdb_metadata_full_%U.dmp
logfile=ebs_metadata_import.log
job_name=EBS_META_IMP
full=y
content=metadata_only
remap_tablespace=%:DATA
transform=segment_attributes:n
transform=dwcs_cvt_iots:y
transform=constraint_use_default_index:y
partition_options=merge
exclude=user,profile,materialized_view,materialized_view_log
exclude=materialized_zonemap,tablespace,tablespace_quota,db_link,statistics,cluster
exclude=job,xmlschema,trusted_db_link,directory,library,context,java_class,java_source
exclude=java_resource
logtime=all
metrics=y
keep_master=y

Run Metadata Import

export TNS_ADMIN=/home/oracle/adw_wallet

nohup impdp admin/'<adw_admin_password>'@<adw_service_name> \
  parfile=import_ebs_metadata.par \
  > import_ebs_metadata.out 2>&1 &

tail -f import_ebs_metadata.out

Review Metadata Errors And Grants

Do not move to data import until the metadata log has been reviewed. Some ORA errors are expected for unsupported Oracle E-Business Suite (EBS) runtime objects; missing grants and missing base objects need review before data load.

Object grants can make metadata import look stuck, especially when grants point to users excluded from the archive. Use the Data Pump master table and job status to distinguish a slow grant phase from a failed import.

Stop/go checkpoint: save the metadata import log, ORA summary, invalid object summary, broken synonym list, APPS grant review, and any corrected table DDL before data import.

Upload And Analyze Import Log

BEGIN
  DBMS_CLOUD.PUT_OBJECT(
    credential_name => 'EBSDUMP_CRED',
    object_uri      => 'https://objectstorage.<region>.oraclecloud.com/n/<namespace>/b/<bucket>/o/ebs_metadata_import.log',
    directory_name  => 'DATA_PUMP_DIR',
    file_name       => 'ebs_metadata_import.log'
  );
END;
/

oci os object get --bucket-name <bucket> --name ebs_metadata_import.log --file ebs_metadata_import.log
grep -Eo 'ORA-[0-9]+' ebs_metadata_import.log | sort | uniq -c | sort -nr

Invalid Object Summary

select owner, count(*) as invalid_count
from dba_objects
where status = 'INVALID'
and owner not in ('SYS','SYSTEM')
group by owner
order by invalid_count desc;

select object_type, count(*) as invalid_count
from dba_objects
where status = 'INVALID'
and owner = 'APPS'
group by object_type
order by invalid_count desc;

APPS Compile Errors

select *
from dba_errors
where owner = 'APPS'
order by name, sequence;

select type, count(*) as error_count
from dba_errors
where owner = 'APPS'
group by type
order by error_count desc;

select o.object_name,
       o.object_type,
       e.line,
       e.text
from dba_objects o
join dba_errors e
  on o.owner = e.owner
 and o.object_name = e.name
where o.owner = 'APPS'
and o.status = 'INVALID'
fetch first 50 rows only;

Broken APPS Synonyms

select synonym_name, table_owner, table_name
from dba_synonyms s
where owner = 'APPS'
and not exists (
  select 1
  from dba_objects o
  where o.owner = s.table_owner
  and o.object_name = s.table_name
)
order by synonym_name;

select distinct s.table_owner, s.table_name
from dba_synonyms s
where s.owner = 'APPS'
and not exists (
  select 1
  from dba_objects o
  where o.owner = s.table_owner
  and o.object_name = s.table_name
)
order by s.table_owner, s.table_name;

Review APPS Grants

-- Review existing grants before adding anything.
select owner, table_name, privilege
from dba_tab_privs
where grantee = 'APPS'
and (
  table_name like 'DBMS\_%' escape '\'
  or table_name like 'DBA\_%' escape '\'
  or table_name like 'V\_$%' escape '\'
  or table_name like 'GV\_$%' escape '\'
)
order by owner, table_name, privilege;

-- Add only the grants required by compile errors and approved for the archive.
grant select on sys.v_$database to apps;
grant select on sys.v_$instance to apps;
grant execute on sys.dbms_crypto to apps;
grant execute on sys.dbms_lock to apps;
grant execute on sys.dbms_pipe to apps;
grant execute on ctxsys.ctx_ddl to apps;
grant select on sys.v_$session to apps;
grant select on sys.gv_$session to apps;
grant select on sys.v_$parameter to apps;
grant select on sys.v_$parameter2 to apps;

-- Do not grant DBMS_SYSTEM unless there is a documented archive need and security approval.

Extract APPS Grants From Metadata

-- create extract_ebs_grants.par
directory=DATA_PUMP_DIR
credential=EBSDUMP_CRED
dumpfile=https://objectstorage.<region>.oraclecloud.com/n/<namespace>/b/<bucket>/o/ebsdb_metadata_full_%U.dmp
sqlfile=create_ebs_grants.sql
full=y
include=object_grant
keep_master=y

export TNS_ADMIN=/home/oracle/adw_wallet
impdp admin/'<adw_admin_password>'@<adw_service_name> parfile=extract_ebs_grants.par

sqlplus admin/'<adw_admin_password>'@<adw_service_name> <<SQL
BEGIN
  DBMS_CLOUD.PUT_OBJECT(
    credential_name => 'EBSDUMP_CRED',
    object_uri      => 'https://objectstorage.<region>.oraclecloud.com/n/<namespace>/b/<bucket>/o/create_ebs_grants.sql',
    directory_name  => 'DATA_PUMP_DIR',
    file_name       => 'create_ebs_grants.sql'
  );
END;
/
SQL

oci os object get --bucket-name <bucket> --name create_ebs_grants.sql --file create_ebs_grants.sql
grep -i 'GRANT .*TO "APPS"' create_ebs_grants.sql > ebsdb_apps_grants.sql

# Review ebsdb_apps_grants.sql before execution.

Fix ORA-64308 Metadata Tables

# ORA-64308 occurs during table DDL creation when a hybrid columnar
# compressed table contains a LONG column. Do not assume ADW/Data Pump
# will automatically convert LONG to another datatype during import.
# Recreate the affected table without hybrid columnar compression, or
# manually convert LONG only when the archive design and data profile allow it.
grep -n 'ORA-64308' ebs_metadata_import.log
grep -B2 'ORA-64308' ebs_metadata_import.log | grep 'Object type TABLE' | sort -u

-- create extract_ora_64308_tables.par
directory=DATA_PUMP_DIR
credential=EBSDUMP_CRED
dumpfile=https://objectstorage.<region>.oraclecloud.com/n/<namespace>/b/<bucket>/o/ebsdb_metadata_full_%U.dmp
sqlfile=create_ora_64308_tables.sql
tables=<OWNER.TABLE_NAME>
keep_master=y

impdp admin/'<adw_admin_password>'@<adw_service_name> parfile=extract_ora_64308_tables.par

# You edit create_ora_64308_tables.sql:
# - remove hybrid columnar compression clauses
# - do not rely on automatic LONG conversion
# - replace LONG with an approved target datatype only if the archive design and data profile allow it
# - remove indexes, triggers, PK/FK sections from the generated SQL
# - create corrected tables before data import

Compile Synonyms And Packages

begin
  for r in (
    select owner, object_name
    from dba_objects
    where object_type = 'SYNONYM'
    and status = 'INVALID'
    and owner in ('APPS','APPLSYS')
  ) loop
    execute immediate 'alter synonym "' || r.owner || '"."' || r.object_name || '" compile';
  end loop;
end;
/

begin
  for r in (
    select object_name
    from dba_objects
    where owner = 'APPS'
    and object_type = 'PACKAGE'
    and status = 'INVALID'
  ) loop
    execute immediate 'alter package APPS.' || r.object_name || ' compile';
    execute immediate 'alter package APPS.' || r.object_name || ' compile body';
  end loop;
end;
/

BEGIN
  UTL_RECOMP.RECOMP_PARALLEL(8);
END;
/

select owner, object_type, count(*) as invalid_count
from dba_objects
where status = 'INVALID'
and owner not in ('SYS','SYSTEM')
group by owner, object_type
order by invalid_count desc;

Prepare Data Import

Before loading rows, make imported indexes unusable and disable archive-side constraints and triggers. Use the active schema list generated from source stats, not a generic module list. Keep every generated script so you can prove what was changed and later rebuild or re-enable it.

Some teams exclude indexes during metadata import and recreate them later; this playbook imports metadata first and makes indexes unusable before loading data. Either pattern is acceptable when the outcome is the same: do not maintain indexes during bulk load, then rebuild and validate them after rows are loaded.

Generate Disable Scripts

-- Replace these inserts with the reviewed active_ebs_schemas.txt values.
create table import_active_schemas (owner varchar2(128));

insert into import_active_schemas values ('AP');
insert into import_active_schemas values ('AR');
insert into import_active_schemas values ('GL');
commit;

set heading off feedback off pages 0 lines 200 trimspool on
spool make_indexes_unusable.sql
select 'alter index "' || owner || '"."' || index_name || '" unusable;'
from dba_indexes
where owner in (select owner from import_active_schemas)
and index_type not in ('LOB')
and status <> 'UNUSABLE';
spool off

spool disable_fk_constraints.sql
select 'alter table "' || owner || '"."' || table_name || '" disable constraint "' || constraint_name || '";'
from dba_constraints
where constraint_type = 'R'
and owner in (select owner from import_active_schemas);
spool off

spool disable_triggers.sql
select 'alter trigger "' || owner || '"."' || trigger_name || '" disable;'
from dba_triggers
where owner in (select owner from import_active_schemas);
spool off

@make_indexes_unusable.sql
@disable_fk_constraints.sql
@disable_triggers.sql

Import Data

Import the active schemas required by APEX reports first. Import remaining archive schemas in a second pass when the priority reporting scope is loaded and validated. Match parallel=8 to ADW CPU and dump file count so import workers can actually run in parallel.

Data Pump Job Control

select owner_name, job_name, operation, job_mode, state
from dba_datapump_jobs
order by owner_name, job_name;

-- When keep_master=y is used, inspect the master table for phase progress.
select object_type, processing_status, processing_state, count(*) object_count
from admin.<job_name>
where process_order > 0
group by object_type, processing_status, processing_state
order by object_count desc;

-- Attach only when you need to inspect, stop, or kill a running job.
impdp admin/'<adw_admin_password>'@<adw_service_name> attach=<owner.job_name>

-- Inside the Data Pump prompt:
-- Import> STATUS
-- Import> START_JOB
-- Import> CONTINUE_CLIENT
-- Import> STOP_JOB=IMMEDIATE
-- Import> KILL_JOB

Data Import Parfile

directory=DATA_PUMP_DIR
credential=EBSDUMP_CRED
dumpfile=https://objectstorage.<region>.oraclecloud.com/n/<namespace>/b/<bucket>/o/ebsdb_data_full_%U.dump
logfile=ebs_data_only_import.log
job_name=EBS_DATA_IMP
content=data_only
schemas=<active_schema_list_comma_separated>
parallel=8
table_exists_action=append
partition_options=merge
exclude=statistics
logtime=all
metrics=y
keep_master=y

Run Data Import And Save Log

export TNS_ADMIN=/home/oracle/adw_wallet

nohup impdp admin/'<adw_admin_password>'@<adw_service_name> \
  parfile=import_ebs_data_only.par \
  > import_ebs_data_only.out 2>&1 &

tail -f import_ebs_data_only.out

BEGIN
  DBMS_CLOUD.PUT_OBJECT(
    credential_name => 'EBSDUMP_CRED',
    object_uri      => 'https://objectstorage.<region>.oraclecloud.com/n/<namespace>/b/<bucket>/o/ebs_data_only_import.log',
    directory_name  => 'DATA_PUMP_DIR',
    file_name       => 'ebs_data_only_import.log'
  );
END;
/

Fix ORA-12899 Data Load Tables

# ORA-12899 appears during data load when a source value is too wide
# for the target column. In Oracle E-Business Suite (EBS) archives this can happen after character
# set conversion, for example when source byte semantics meet ADW AL32UTF8.
grep -n 'ORA-12899' ebs_data_only_import.log
grep -n 'KUP-11007: conversion error loading table' ebs_data_only_import.log

# Identify affected tables/columns from the Data Pump log, then extract
# table DDL and recreate the table with wider or CHAR semantics columns.
-- create extract_ora_12899_tables.par
directory=DATA_PUMP_DIR
credential=EBSDUMP_CRED
dumpfile=https://objectstorage.<region>.oraclecloud.com/n/<namespace>/b/<bucket>/o/ebsdb_metadata_full_%U.dmp
sqlfile=create_ora_12899_tables.sql
tables=<OWNER.TABLE_NAME>
keep_master=y

impdp admin/'<adw_admin_password>'@<adw_service_name> parfile=extract_ora_12899_tables.par

# You edit create_ora_12899_tables.sql before rerun:
# - change VARCHAR2(n BYTE) to VARCHAR2(n CHAR), or widen the column
# - replace LONG only if the target design requires it and the app can support it
# - remove indexes, triggers, PK/FK sections from generated SQL
# - recreate the corrected table, then rerun the failed table import

Rerun Failed Tables

-- Use after reviewing ebs_data_only_import.log.
-- create import_failed_tables.par
directory=DATA_PUMP_DIR
credential=EBSDUMP_CRED
dumpfile=https://objectstorage.<region>.oraclecloud.com/n/<namespace>/b/<bucket>/o/ebsdb_data_full_%U.dump
logfile=ebs_failed_tables_import.log
job_name=EBS_FAILED_TABLES_IMP
content=data_only
tables=AR.AR_PAYMENTS_INTERFACE_ALL,MSC.MSC_ST_SYSTEM_ITEMS
table_exists_action=append
exclude=statistics
logtime=all
metrics=y
keep_master=y

impdp admin/'<adw_admin_password>'@<adw_service_name> parfile=import_failed_tables.par

FND_LOBS Handling

-- Large attachment tables may be handled separately.
-- Confirm archive scope and storage impact before importing FND_LOBS.

-- Optional separate import pattern:
directory=DATA_PUMP_DIR
credential=EBSDUMP_CRED
dumpfile=https://objectstorage.<region>.oraclecloud.com/n/<namespace>/b/<bucket>/o/ebsdb_data_full_%U.dump
logfile=fnd_lobs_import.log
content=data_only
tables=FND.FND_LOBS
table_exists_action=append
metrics=y
keep_master=y

Validate And Secure Archive ADW

After data load, prove the archive rows were loaded, compile what matters for archive reporting, then harden the database so it behaves like a read-only archive. Use the active Oracle E-Business Suite (EBS) schema list from the source discovery step instead of locking or compiling by old user id ranges.

Audit Validation Standard

Every in-scope table with data should be imported and reconciled, or listed in an exception log with the archive reason. Treat invalid objects the same way: fix objects needed by EBSArchive reports; document objects tied to retired Oracle E-Business Suite (EBS) runtime behavior.

Rebuild Indexes After Data Load

set heading off feedback off pages 0 lines 300 trimspool on
spool rebuild_indexes_nologging.sql

select 'alter index "' || owner || '"."' || index_name || '" rebuild nologging;'
from dba_indexes
where owner in (select owner from import_active_schemas)
and status = 'UNUSABLE'
and index_type not in ('LOB');

spool off

@rebuild_indexes_nologging.sql

select owner, index_name, status
from dba_indexes
where owner in (select owner from import_active_schemas)
and status <> 'VALID'
order by owner, index_name;

Enable And Validate

-- Run reviewed enable scripts generated from DBA metadata.
@enable_triggers.sql
@enable_fk_constraints.sql

-- Row count spot check. Replace table list with archive scope tables.
select 'GL_JE_HEADERS' table_name, count(*) row_count from gl.gl_je_headers
union all
select 'AP_CHECKS_ALL', count(*) from ap.ap_checks_all
union all
select 'RA_CUSTOMER_TRX_ALL', count(*) from ar.ra_customer_trx_all;

-- Capture remaining import issues.
select owner, object_type, count(*) invalid_count
from dba_objects
where status = 'INVALID'
and owner not in ('SYS','SYSTEM')
group by owner, object_type
order by invalid_count desc;

Compare Export And Import Rows

# Download the export and import logs first.
oci os object get --bucket-name <bucket> --name ebsdb_data_full.log --file ebsdb_data_full.log
oci os object get --bucket-name <bucket> --name ebs_data_only_import.log --file ebs_data_only_import.log

# Compare exported row lines with imported row lines and preserve the output.
grep ' rows' ebsdb_data_full.log | grep -v '0 KB' | sort > export_rows.lst
grep ' rows' ebs_data_only_import.log | grep -v '0 KB' | sort > import_rows.lst
diff -u export_rows.lst import_rows.lst > row_count_diff.lst

# Every exported table with rows should either match import output
# or appear in archive_exceptions.md with the archive reason.
# Review exceptions before business sign-off.

Generate Target Row Counts

-- Use for source and target when the source database is still available.
-- Compare the two CSV files as part of migration sign-off.
set heading off feedback off pages 0 lines 400 trimspool on
spool archive_table_counts.csv

select owner || ',' || table_name || ',' || num_rows
from dba_tables
where owner in (select owner from import_active_schemas)
and num_rows > 0
order by owner, table_name;

spool off

Compile Synonyms And Schemas

set heading off feedback off pages 0 lines 300 trimspool on

spool compile_public_synonyms.sql
select 'alter public synonym "' || object_name || '" compile;'
from dba_objects
where owner = 'PUBLIC'
and object_type = 'SYNONYM'
and status <> 'VALID';
spool off

spool compile_schema_synonyms.sql
select 'alter synonym "' || owner || '"."' || object_name || '" compile;'
from dba_objects
where owner <> 'PUBLIC'
and object_type = 'SYNONYM'
and status <> 'VALID';
spool off

@compile_public_synonyms.sql
@compile_schema_synonyms.sql

begin
  for r in (select owner from import_active_schemas) loop
    dbms_utility.compile_schema(schema => r.owner, compile_all => false);
  end loop;
  dbms_utility.compile_schema(schema => 'APPS', compile_all => false);
end;
/

select owner, object_type, count(*) invalid_count
from dba_invalid_objects
group by owner, object_type
order by owner, object_type;

Read-Only Hardening

-- Run only after validation and business approval.
-- Confirm these revokes do not break required APEX archive views.
revoke insert any table from apps;
revoke update any table from apps;
revoke delete any table from apps;
revoke select any sequence from apps;

-- Lock imported Oracle E-Business Suite (EBS) schemas that should not be used interactively.
-- Keep APPS unlocked for the archive application if required.
set heading off feedback off pages 0 lines 200 trimspool on
spool lock_archive_schemas.sql
select 'alter user "' || username || '" account lock;'
from dba_users
where username in (select owner from import_active_schemas)
and username <> 'APPS'
order by username;
spool off

@lock_archive_schemas.sql

-- Optional after load if approved for ADW.
exec dbms_auto_index.configure('AUTO_INDEX_MODE','IMPLEMENT');

Define ADW Backup, Restore, And Runtime Operations

Before handoff, agree how the archive ADW will be recovered, scaled, stopped, or restarted. Migration windows may need higher CPU, while steady-state archive reporting usually needs less capacity. Do not rely on memory of the migration setup; record the operating model.

Operations Checklist

# Archive ADW operations checklist
- Confirm automatic backup and restore policy.
- Record restore approach before destructive test imports.
- Record the UTC timestamp for each restore point or import checkpoint.
- Before restoring ADW, upload or download any needed DATA_PUMP_DIR logs and SQLFILE output.
- After restoring ADW, check dba_datapump_jobs and stop or clean any stale import jobs.
- Record ADW CPU/storage used for migration.
- Record steady-state ADW CPU/storage after migration.
- Decide whether ADW can be stopped outside agreed archive access windows.
- Rotate ADW wallet after implementation if migration hosts or contractors used it.
- Reset or rotate ADMIN credentials after go-live.
- Preserve Object Storage dump/log retention policy and lifecycle rules.

Preserve The Handoff Package

Keep the evidence package together so your team can reproduce the archive load, review exceptions, and answer audit questions after go-live.

Keep Together

  • Metadata dump pieces
  • Data dump pieces
  • Metadata and data export logs
  • Metadata and data import logs
  • Metadata and data parfiles
  • User, grant, disable, and enable scripts
  • Row-count comparison output
  • Archive exception log for excluded tables and invalid objects
  • Object Storage listing or manifest
  • ADW backup, restore, wallet rotation, and runtime operations notes

Before Import

  • Review export logs for ORA errors and warnings
  • Confirm expected dump file count and size
  • Confirm ADW directory and credentials
  • Plan metadata import before data import
  • Define validation queries before loading
  • Define exception criteria for tables and invalid objects

DBA Notes

These are the operating assumptions behind the commands above; adjust them for the enterprise source database and approval process.

  • system/manager is acceptable only for an Oracle E-Business Suite (EBS) Vision lab. Enterprise exports should use an approved export account with required Data Pump privileges.
  • Data Pump dumps alone are not enough. Preserve logs and validation results so the archive is auditable.
  • The archived ADW database does not need to be a perfect clone of Oracle E-Business Suite (EBS). It needs to be a validated reporting archive for the agreed scope.
By Gopal Mallya Oracle E-Business Suite archive, decommissioning, and reporting modernization Connect on LinkedIn