How to Apply Multiple EBS Patches in One ADOP Cycle — The Right Way
Every quarterly CPU cycle involves multiple patches — application tier patches, one-off fixes, prerequisite patches, and sometimes NLS patches on top. Running a separate ADOP cycle for each one is the most common mistake DBAs make. It means multiple prepare phases, multiple cutover windows, and hours of unnecessary downtime.
The right approach is to consolidate everything into a single ADOP cycle. One prepare. One cutover. One cleanup. The total downtime is the same regardless of how many patches you apply — so applying ten patches in one cycle costs the same cutover time as applying one.
This post covers two methods for applying multiple patches in one ADOP cycle — the comma-separated method and the admrgpch merge method — and explains when to use each one, how to handle conflicts, and what to watch out for.
Key principle: The cutover window in ADOP is fixed — it is the time needed to bounce services and switch filesystems. It does not grow significantly with the number of patches applied. Consolidating patches saves real downtime every quarter.
Two Methods for Applying Multiple Patches
ADOP gives you two ways to apply multiple patches in a single cycle. Understanding the difference helps you choose the right approach for each situation.
| Method | How It Works | Best For |
|---|---|---|
| Comma-separated patches | List all patch numbers in one apply command separated by commas. ADOP handles the merge automatically during apply. | Most CPU patching scenarios — fast, simple, no pre-work needed |
| admrgpch pre-merge | Merge patches manually before the ADOP cycle using the admrgpch utility. Apply the single merged patch via ADOP. | Large upgrade patches, release update packs, or when you want to pre-validate merge conflicts before the maintenance window |
For quarterly CPU patching, the comma-separated method is what you should use in almost every case. It is simpler, faster to set up, and fully supported by Oracle. The admrgpch method is covered later in this post for situations where it is specifically needed.
Method 1 — Comma-Separated Patches in One Apply Command
This is the standard approach for CPU patching. All patch numbers are listed in a single adop phase=apply command separated by commas. ADOP automatically merges the unified driver files during the apply phase and applies all patches in one pass.
Step 1 — Stage all patches
Download and unzip every patch into the $PATCH_TOP directory before starting the ADOP cycle. Each patch must be in its own numbered subdirectory.
# Confirm PATCH_TOP location echo $PATCH_TOP # Default: $NE_BASE/EBSapps/patch # Unzip each patch into its own directory unzip p36478206_R12_GENERIC.zip -d $PATCH_TOP unzip p35987654_R12_GENERIC.zip -d $PATCH_TOP unzip p36112233_R12_GENERIC.zip -d $PATCH_TOP # Verify each patch directory exists ls -la $PATCH_TOP/ # Should show: 36478206/ 35987654/ 36112233/ # On multi-node environments — patches only need to be staged # on the PRIMARY node when using a shared filesystem
Step 2 — Run the ADOP cycle with all patches in one command
# Source the run environment source /u01/oracle/R122/EBSapps.env run # Always dryrun first — no exceptions adop phase=apply \ patches=36478206,35987654,36112233 \ apply_mode=dryrun # Step 1 — Prepare adop phase=prepare # Step 2 — Apply all patches in one command adop phase=apply \ patches=36478206,35987654,36112233 \ workers=8 # Step 3 — Finalize adop phase=finalize # Step 4 — Cutover (only downtime window) adop phase=cutover # Step 5 — Cleanup adop phase=cleanup
When you list multiple patches with commas, ADOP automatically uses merge=yes internally. You do not need to specify it. The patches are merged on the fly during the apply phase and applied together in a single pass.
Applying patches in multiple apply commands within one cycle
You can also run multiple adop phase=apply commands within the same patching cycle without running cutover in between. This is useful when patches must be applied in a specific order — for example when one patch is a prerequisite for another.
# Start the cycle adop phase=prepare # Apply prerequisite patches first adop phase=apply patches=35987654 workers=8 # Then apply the main CPU patches adop phase=apply patches=36478206,36112233 workers=8 # Continue the cycle as normal adop phase=finalize adop phase=cutover adop phase=cleanup
You do not need to run finalize between multiple apply commands in the same cycle. Run finalize once after all apply commands are complete. This saves significant time in a large patching session.
Choosing the Right Number of Workers
The workers parameter controls how many parallel processes ADOP uses to apply patch jobs. More workers means faster apply — up to a point. Too many workers can exhaust database connections and cause the apply to fail.
| Environment Size | Recommended Workers | Notes |
|---|---|---|
| Small — 4 CPU cores, 16 GB RAM | 4 | Default is usually adequate for small environments |
| Medium — 8 CPU cores, 32 GB RAM | 6 to 8 | Good balance of speed and stability |
| Large — 16+ CPU cores, 64+ GB RAM | 8 to 16 | Test in non-production first — monitor DB connections |
sqlplus / as sysdba <<EOF -- Confirm processes parameter can support your worker count SHOW PARAMETER processes; -- Each worker needs approximately 3 DB connections -- workers=8 needs ~24 connections available above current usage -- Check current active sessions SELECT COUNT(*) FROM v$session WHERE status = 'ACTIVE'; EOF
Method 2 — Pre-Merging Patches with admrgpch
The admrgpch utility allows you to merge multiple patches into a single merged patch before the ADOP cycle begins. The main advantage is that conflicts between patches are identified and resolved before your maintenance window opens — not during it.
This method is particularly useful for large release update packs, upgrade patches, or situations where you are applying a large number of patches and want to validate compatibility upfront.
Step 1 — Stage all patches in PATCH_TOP
# Unzip all patches into PATCH_TOP cd $PATCH_TOP unzip /downloads/p36478206_R12_GENERIC.zip unzip /downloads/p35987654_R12_GENERIC.zip unzip /downloads/p36112233_R12_GENERIC.zip # Confirm patch directories are present ls -la $PATCH_TOP # 36478206/ 35987654/ 36112233/
Step 2 — Create a destination directory for the merged patch
# Create a destination directory under PATCH_TOP mkdir -p $PATCH_TOP/merged_cpu_apr2026 # Confirm it is empty ls -la $PATCH_TOP/merged_cpu_apr2026/
Step 3 — Run admrgpch to merge the patches
# Source the run environment source /u01/oracle/R122/EBSapps.env run # Run admrgpch # -s = source directory containing individual patches # -d = destination directory for the merged result admrgpch \ -s $PATCH_TOP \ -d $PATCH_TOP/merged_cpu_apr2026 # Review the output — look for conflicts or warnings # A merged driver file is created in the destination directory ls -la $PATCH_TOP/merged_cpu_apr2026/ # Should contain: fnd u_merged.drv (and others)
Step 4 — Move individual patch directories into the merged directory
This is the step most DBAs miss. ADOP looks for the individual patch directories inside the merged patch directory during the next prepare phase. If they are not there, the next prepare will fail.
# Move each individual patch directory into the merged destination mv $PATCH_TOP/36478206 $PATCH_TOP/merged_cpu_apr2026/ mv $PATCH_TOP/35987654 $PATCH_TOP/merged_cpu_apr2026/ mv $PATCH_TOP/36112233 $PATCH_TOP/merged_cpu_apr2026/ # Verify the merged directory structure ls -la $PATCH_TOP/merged_cpu_apr2026/ # Should now contain: # 36478206/ 35987654/ 36112233/ fnd u_merged.drv
Why this step is mandatory: During the next prepare phase after cutover, ADOP synchronises the patch filesystem and looks for the individual patch directories that were part of the previous cycle. If they are not inside the merged patch directory, prepare will fail with a missing patch directory error.
Step 5 — Apply the merged patch using ADOP
# Prepare adop phase=prepare # Apply using the merged patch directory # Specify the patchtop pointing to the merged directory adop phase=apply \ patches=merged_cpu_apr2026 \ patchtop=$PATCH_TOP/merged_cpu_apr2026 \ workers=8 # Continue normally adop phase=finalize adop phase=cutover adop phase=cleanup
Handling Merge Conflicts
A conflict occurs when two patches modify the same file or database object in incompatible ways. Both the comma-separated method and admrgpch will detect conflicts — they just do it at different times.
- Comma-separated method — conflict detected during the apply phase inside the maintenance window
- admrgpch method — conflict detected before the maintenance window when you run admrgpch
What a conflict looks like
WARNING: Conflict detected for file: $FND_TOP/patch/115/import/US/fndscsgn.ldt Modified by patches: 36478206, 35987654 Resolution: Patch 36478206 will take precedence (higher patch number)
How ADOP resolves conflicts automatically
For most conflicts, ADOP and admrgpch resolve them automatically using the following rules:
- The patch with the higher patch number takes precedence for file conflicts
- For database object conflicts, the last patch in the list wins
- Conflicts that cannot be resolved automatically are flagged as errors and must be resolved manually
When to involve Oracle Support
If admrgpch or the apply phase reports an unresolvable conflict — meaning it cannot determine which patch should win — raise a Service Request with Oracle Support before proceeding. Applying patches with unresolved conflicts can leave the application in an inconsistent state.
# For admrgpch — review the merge log immediately after running cat $PATCH_TOP/merged_cpu_apr2026/admrgpch.log | grep -i "conflict\|error\|warning" # For comma-separated — review the apply log during or after apply grep -i "conflict\|warning" \ $APPL_TOP_NE/admin/log/adop/<session_id>/<timestamp>/adop.log
Patch Ordering — Does Sequence Matter?
In most cases the order of patches in the comma-separated list does not matter because ADOP handles dependencies internally. However there are two situations where ordering is important.
Situation 1 — Prerequisite patches
If Patch B requires Patch A to be applied first, apply them in separate apply commands within the same cycle — not in the same comma-separated list. ADOP does not enforce prerequisite ordering within a single apply command.
# Apply the prerequisite patch first adop phase=apply patches=35987654 workers=8 # Then apply the patch that depends on it adop phase=apply patches=36478206 workers=8 # Both are within the same cycle — no cutover between them
Situation 2 — NLS patches
NLS (language) patches must always be applied after the base US English patch in a separate apply command. Do not combine US and NLS patches in the same comma-separated list.
# Apply the US base patch first adop phase=apply patches=36478206 workers=8 # Then apply NLS patches separately in the same cycle adop phase=apply patches=36478206_AR,36478206_FR workers=4 # Or use hotpatch mode if the NLS README approves it # One finalize and cutover covers everything adop phase=finalize adop phase=cutover adop phase=cleanup
Using an Input File for Large Patch Lists
When applying many patches, a long comma-separated list on the command line can become difficult to manage and prone to typing errors. ADOP supports an input file that lists all parameters cleanly.
# Create the input file — one parameter per line
cat > /stage/cpu_apr2026_input.txt << EOF
patches=36478206,35987654,36112233,36001122,35778899
workers=8
apply_mode=online
EOF
# Reference the input file in the apply command adop phase=apply input_file=/stage/cpu_apr2026_input.txt # The input file approach also works for dryrun adop phase=apply input_file=/stage/cpu_apr2026_input.txt \ apply_mode=dryrun
Common Mistakes When Applying Multiple Patches
| Mistake | Consequence | Correct Approach |
|---|---|---|
| Running a separate ADOP cycle for each patch | Multiple cutover windows — hours of unnecessary downtime per quarter | Consolidate all patches into one cycle with comma-separated list |
| Running finalize between multiple apply commands | Wastes time — finalize compiles everything, not just the last patch | Run finalize once after all apply commands are complete |
| Using admrgpch and not moving patch directories into merged folder | Next prepare phase fails looking for missing patch directories | Always move individual patch directories inside the merged destination |
| Mixing US and NLS patches in one comma-separated list | NLS patch may fail or apply in wrong order | Apply US patch first, NLS patches in a separate apply command |
| Not reading README files before consolidating | Miss a patch that requires downtime mode — wrong apply_mode used | Read every README before staging — note any mode requirements |
| Setting too many workers | DB processes limit exceeded — workers fail to connect | Check processes parameter and active sessions before setting workers |
| Not running dryrun before apply | Conflicts and mode issues discovered mid-apply in the maintenance window | Always run dryrun before every real apply — catches issues early |
Complete Example — CPU April 2026 Multi-Patch Cycle
This is a complete example of a quarterly CPU patching session applying five patches in one ADOP cycle using the comma-separated method.
# Environment setup source /u01/oracle/R122/EBSapps.env run # Stage all patches cd $PATCH_TOP unzip /downloads/p36478206_R12_GENERIC.zip unzip /downloads/p35987654_R12_GENERIC.zip unzip /downloads/p36112233_R12_GENERIC.zip unzip /downloads/p36001122_R12_GENERIC.zip unzip /downloads/p35778899_R12_GENERIC.zip # Dryrun first — validate before committing adop phase=apply \ patches=36478206,35987654,36112233,36001122,35778899 \ apply_mode=dryrun # Review dryrun log — confirm no errors or mode conflicts tail -50 $APPL_TOP_NE/admin/log/adop/<session_id>/<timestamp>/adop.log # Prepare — starts the patching cycle adop phase=prepare # Apply all patches in one command adop phase=apply \ patches=36478206,35987654,36112233,36001122,35778899 \ workers=8 # Monitor apply progress adop phase=status # Finalize — compile, generate, merge seed data adop phase=finalize # Cutover — notify users first, then run # This is the only step that requires a maintenance window adop phase=cutover # Verify patches registered in AD tables sqlplus apps/<apps_pwd> <<EOF SELECT bug_number, last_update_date FROM ad_bugs WHERE bug_number IN ( '36478206','35987654','36112233','36001122','35778899' ) ORDER BY bug_number; EOF # Cleanup — run after confirming system is stable adop phase=cleanup
Summary
- Always consolidate multiple patches into one ADOP cycle — one cutover regardless of patch count
- For CPU patching use the comma-separated method — it is simple, fast, and fully supported
- Use admrgpch when you want to pre-validate conflicts before the maintenance window
- If using admrgpch, always move individual patch directories into the merged destination folder
- Apply prerequisite patches in a separate apply command before the patches that depend on them
- Apply NLS patches in a separate apply command after the US base patch
- Run finalize only once — after all apply commands in the cycle are complete
- Always dryrun before every real apply — every time, no exceptions
No comments:
Post a Comment