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. |
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
LONGcolumns 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/manageris 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.