Oracle Redo Log Configuration and I/O design
In this topic, I will explore best practices for defining and designing the Oracle redo log architecture in an operational environment to achieve better I/O performance and availability.
I/O Configuration and Design
The I/O
subsystem is a vital component of an Oracle database. This chapter introduces
fundamental I/O concepts, discusses the I/O requirements of different parts of
the database, and provides sample configurations for I/O subsystem design.
About I/O
Every Oracle
AI Database reads or writes data on disk, thus generating disk I/O.
The performance of many software applications is inherently limited by disk
I/O. Applications that spend majority of their CPU time waiting for I/O
activity to complete are said to be I/O-bound.
Oracle AI
Database is designed so that if an application is well written, its
performance should not be limited by I/O. Tuning I/O can enhance the
performance of the application if the I/O system is operating at or near
capacity and is not able to service the I/O requests within an acceptable time.
However, tuning I/O cannot help performance if the application is not I/O-bound
(for example, when CPU is the limiting factor).
Consider
the following database requirements when designing an I/O system:
- Storage, such as minimum disk
capacity
- Availability, such as continuous
(24 x 7) or business hours only
- Performance, such as I/O
throughput and application response times
Many I/O
designs plan for storage and availability requirements with the assumption that
performance will not be an issue. This is not always the case. Optimally, the
number of disks and controllers to be configured should be determined by I/O
throughput and redundancy requirements. The size of disks can then be
determined by the storage requirements.
When
developing an I/O design plan, consider using Oracle Automatic Storage
Management (Oracle ASM). Oracle ASM is an integrated, high-performance database
file system and disk manager that is based on the principle that the database
should manage storage instead of requiring an administrator to do it.
Oracle recommends that you use Oracle ASM for your database file storage, instead of raw devices or the operating system file system. Oracle ASM provides the following key benefits:
- Striping
- Mirroring
- Online storage reconfiguration
and dynamic rebalancing
- Managed file creation and
deletion
1. Deep understanding — why alternate-disk redo design matters
In Oracle
Database, redo logging involves two main processes:
|
Process |
Function |
I/O Pattern |
Critical Concern |
|
LGWR (Log Writer) |
Writes redo entries to current redo log members |
Sequential, low-latency writes |
Latency directly affects commit performance |
|
ARCH (Archiver) |
Reads full redo log groups after a
log switch and writes archived redo logs to archive destinations |
Sequential read + write |
Can stall LGWR if it falls behind |
Contention
point
If both LGWR
and ARCH operate on the same physical disks, I/O contention occurs:
- ARCH reads full redo logs while
LGWR tries to write to the next one.
- ARCH → sequential reads
- LGWR → sequential writes
→ competing I/O queue = slower commit response time and possible "log file switch (archiving needed)" waits.
2. Alternating-disk architecture (revised grouping)
Goal:
separate LGWR writes from ARCH reads by alternating redo-members placement
across physical disks.
Archived Redo Logs
If the
archiver is slow, then it might be prudent to prevent I/O contention between
the archiver process and LGWR by ensuring that archiver reads and LGWR writes
are separated. This is achieved by placing logs on alternating drives.
For example,
suppose a system has four redo log groups, each group with two members. To
create separate-disk access, the eight log files should be labeled 1a, 1b, 2a,
2b, 3a, 3b, 4a, and 4b. This requires at least four disks, plus one disk for
archived files.
The
following figure illustrates how redo members should be distributed across
disks to minimize contention.
|
Redo
Group |
Member
A |
Member
B |
|
Group
1 |
Disk
1a |
Disk
3a |
|
Group
2 |
Disk
2a |
Disk
4a |
|
Group
3 |
Disk
1b |
Disk
3b |
|
Group
4 |
Disk
2b |
Disk
4b |

In this
example, LGWR switches out of log group 1 (member 1a and 1b) and writes to log
group 2 (2a and 2b). Concurrently, the archiver process reads from group 1 and
writes to its archive destination. Note how the redo log files are isolated
from contention.
Note:
Mirroring redo
log files, or maintaining multiple copies of each redo log file on separate
disks, does not slow LGWR considerably. LGWR writes to each disk in parallel
and waits until each part of the parallel write is complete. Thus, a parallel
write does not take longer than the longest possible single-disk write.
Because redo
logs are written serially, drives dedicated to redo log activity generally
require limited head movement. This significantly accelerates log writing.
Why this helps:
When logs rotate, ARCH will be reading older groups that are placed on
different spindles/paths than LGWR’s current target. The alternating pattern
reduces read/write head / controller contention and improves commit latency.
ASM Implementation Example
Assumptions
- Linux with oracleasm kernel
module installed/configured (Oracle ASMLib).
- Devices available: /dev/sdb1 …
/dev/sdi1 (adjust to your actual device names).
- Commands that operate on ASM
(diskgroup creation) run as the Grid Infrastructure owner (e.g. grid), or
use sqlplus / as sysasm for CREATE DISKGROUP.
- Database SYSDBA commands run on
the database instance.
Step 0 — Prepare environment variables (example)
# as grid
user (adjust ORACLE_HOME and ASM SID)
export
ORACLE_HOME=/u01/app/grid
export
PATH=$ORACLE_HOME/bin:$PATH
export
ORACLE_SID=+ASM
Step 1 — Create ASM device entries with oracleasm
Use
oracleasm createdisk to expose devices to ASM (ASMLib). Replace /dev/sdb1 →
your device path.
# as root
(or user with permission to run oracleasm)
# Create 8
ASM device identifiers mapping to physical devices
/usr/sbin/oracleasm createdisk DISK_1A /dev/sdb1
/usr/sbin/oracleasm createdisk DISK_1B /dev/sdc1
/usr/sbin/oracleasm createdisk DISK_2A /dev/sdd1
/usr/sbin/oracleasm createdisk DISK_2B /dev/sde1
/usr/sbin/oracleasm createdisk DISK_3A /dev/sdf1
/usr/sbin/oracleasm createdisk DISK_3B /dev/sdg1
/usr/sbin/oracleasm createdisk DISK_4A /dev/sdh1
/usr/sbin/oracleasm createdisk DISK_4B /dev/sdi1
/usr/sbin/oracleasm
listdisks
# or
/usr/sbin/oracleasm
querydisk -p DISK_1A # prints device
path mapped
Step 2 — Create ASM diskgroups (example)
Two common
approaches:
A. Create two diskgroups +REDO_A and
+REDO_B grouping A-side and B-side disks
This keeps 1a/2a/3a/4a in one diskgroup and 1b/2b/3b/4b in
another.
-- connect
as SYSASM
sqlplus / as
sysasm
|
CREATE DISKGROUP REDO_A EXTERNAL REDUNDANCY
DISK 'ORCL:DISK_1A' NAME redo_1a, 'ORCL:DISK_2A' NAME redo_2a, 'ORCL:DISK_3A' NAME redo_3a, 'ORCL:DISK_4A' NAME redo_4a
ATTRIBUTE 'au_size'='1048576'; |
CREATE DISKGROUP REDO_B EXTERNAL REDUNDANCY
DISK 'ORCL:DISK_1B' NAME redo_1b, 'ORCL:DISK_2B' NAME redo_2b, 'ORCL:DISK_3B' NAME redo_3b, 'ORCL:DISK_4B' NAME redo_4b
ATTRIBUTE 'au_size'='1048576'; |
Step 3 — Create redo log groups using your requested pairings
You asked
for putting 1a & 3a into a redo group, 2a & 4a together, and similarly
for the B-side. Following that layout we create 4 groups:
-- connect
to the database as SYSDBA
sqlplus / as
sysdba
--
Group 1: members on disks 1a and 3a
ALTER DATABASE ADD LOGFILE GROUP 1
('+REDO_A/redo_group1_1a.log', '+REDO_A/redo_group1_3a.log')
SIZE 512M;
--
Group 2: members on disks 2a and 4a
ALTER DATABASE ADD LOGFILE GROUP 2
('+REDO_A/redo_group2_2a.log', '+REDO_A/redo_group2_4a.log')
SIZE 512M;
--
Group 3: members on disks 1b and 3b
ALTER DATABASE ADD LOGFILE GROUP 3
('+REDO_B/redo_group3_1b.log', '+REDO_B/redo_group3_3b.log')
SIZE 512M;
--
Group 4: members on disks 2b and 4b
ALTER DATABASE ADD LOGFILE GROUP 4
('+REDO_B/redo_group4_2b.log', '+REDO_B/redo_group4_4b.log') SIZE 512M;
Important
notes:
- This places the two members of
each redo group on disks that you requested (e.g., group 1 uses 1a
& 3a).
- Typically, multiplexing places
members on different disk groups or failure groups; here we followed your
requested mapping. If you want members to be on different physical
controllers, ensure the underlying disks (1a vs 3a) are on different
controllers/enclosures or assign them to different ASM failure groups when
creating the diskgroup.
- If you prefer each member to be
in a different diskgroup (for stronger isolation), create groups with
('+REDO_A/…', '+REDO_B/…') pairs. Let me know if you want that variant.
Step 4 — Separate archive destination (recommended)
Put archived
logs on a distinct ASM diskgroup (or filesystem) to eliminate ARCH → LGWR
contention:
-- create +ARCH_DG (one example diskgroup)
-- then:
ALTER SYSTEM SET
log_archive_dest_1='LOCATION=+ARCH_DG/arch' SCOPE=BOTH;
Validation
/ verification
Check redo
members in database:
SET PAGESIZE 200
COLUMN MEMBER FORMAT A60
SELECT g.group#, g.thread#, g.status, f.member
FROM v$log g JOIN v$logfile f ON g.group# = f.group#
ORDER BY g.group#, f.member;
Check ASM
disks / diskgroups:
# as grid
asmcmd lsdg
asmcmd lsdsk -k
# show disks and their names
asmcmd lsdsk -G REDO_A
asmcmd lsdsk -G REDO_B
Check oracleasm device mappings (if needed):
/usr/sbin/oracleasm listdisks
/usr/sbin/oracleasm
querydisk -p DISK_1A
Cautions & practical advice:
- If underlying physical
controllers still map multiple 1a/3a disks to the same
controller, you'll not gain the intended separation — verify physical
controller/enclosure mapping. Use ASM failure groups if you want to
express enclosure/controller boundaries in ASM: create diskgroups with FAILGROUP
definitions and assign disks accordingly.
- Test failover and archiving
under load: do a log switch and observe ARCH reading and LGWR writing—use
iostat / vmstat and asmcmd iostat to verify no hot spots.
- Keep at least two members per
group (multiplexing) so a single disk failure won't block recovery.
Consider using NORMAL or HIGH redundancy for extra protection (but that
changes how many physical disks required).
|
Disk |
Device |
Controller / Enclosure |
Purpose |
|
1a |
/dev/sdb1 |
CONTROLLER_A |
Redo member (Group 1 / Group 2
A-side) |
|
2a |
/dev/sdd1 |
CONTROLLER_A |
Redo member (Group 2 A-side) |
|
3a |
/dev/sdf1 |
CONTROLLER_B |
Redo member (Group 1 / Group 2
A-side) |
|
4a |
/dev/sdh1 |
CONTROLLER_B |
Redo member (Group 2 A-side) |
|
1b |
/dev/sdc1 |
CONTROLLER_C |
Redo member (Group 3 / Group 4
B-side) |
|
2b |
/dev/sde1 |
CONTROLLER_C |
Redo member (Group 3 / Group 4
B-side) |
|
3b |
/dev/sdg1 |
CONTROLLER_D |
Redo member (Group 3 / Group 4
B-side) |
|
4b |
/dev/sdi1 |
CONTROLLER_D |
Redo member (Group 4 B-side) |
ASM Diskgroup Creation Strategy
We’ll create
two ASM diskgroups for redo logs:
+REDO_A — for A-side disks (1a–4a), mirrored between
CONTROLLER_A and CONTROLLER_B
+REDO_B — for B-side disks (1b–4b), mirrored between
CONTROLLER_C and CONTROLLER_D
Each
diskgroup uses NORMAL REDUNDANCY, so ASM keeps one mirrored copy on a different
failgroup.
SQL
Commands (run as SYSASM)
-- Diskgroup
for A-side redo
CREATE DISKGROUP REDO_A NORMAL REDUNDANCY
FAILGROUP FG_A1
DISK
'ORCL:DISK_1A', 'ORCL:DISK_2A'
FAILGROUP FG_A2 DISK
'ORCL:DISK_3A', 'ORCL:DISK_4A'
ATTRIBUTE
'au_size'='4M',
'compatible.asm'='19.0.0.0.0',
'compatible.rdbms'='19.0.0.0.0',
'sector_size'='512',
'disk_repair_time'='3.6h';
CREATE DISKGROUP REDO_B NORMAL REDUNDANCY
FAILGROUP FG_B1
DISK
'ORCL:DISK_1B',
'ORCL:DISK_2B'
FAILGROUP FG_B2
DISK
'ORCL:DISK_3B',
'ORCL:DISK_4B'
ATTRIBUTE
'au_size'='4M',
'compatible.asm'='19.0.0.0.0',
'compatible.rdbms'='19.0.0.0.0',
'sector_size'='512',
'disk_repair_time'='3.6h';
Notes:
- NORMAL REDUNDANCY mirrors each
extent between FG_A1 and FG_A2 (and similarly FG_B1 and FG_B2).
- This ensures no mirror copies
reside on the same physical controller.
- au_size=4M is optimal for redo
diskgroups because redo I/O is mostly sequential and benefits from larger
allocation units.
- disk_repair_time allows
temporary offline disks to auto-recover without forced rebalance.
Example Verification (after creation)
asmcmd lsdg
asmcmd lsdsk -G REDO_A -k
asmcmd lsdsk -G REDO_B -k
Expected output snippet:
|
Group |
Failgroup |
Disk |
Path |
State |
|
REDO_A |
FG_A1 |
DISK_1A |
ORCL:DISK_1A |
NORMAL |
|
REDO_A |
FG_A1 |
DISK_2A |
ORCL:DISK_2A |
NORMAL |
|
REDO_A |
FG_A2 |
DISK_3A |
ORCL:DISK_3A |
NORMAL |
|
REDO_A |
FG_A2 |
DISK_4A |
ORCL:DISK_4A |
NORMAL |
|
REDO_B |
FG_B1 |
DISK_1B |
ORCL:DISK_1B |
NORMAL |
|
REDO_B |
FG_B1 |
DISK_2B |
ORCL:DISK_2B |
NORMAL |
|
REDO_B |
FG_B2 |
DISK_3B |
ORCL:DISK_3B |
NORMAL |
|
REDO_B |
FG_B2 |
DISK_4B |
ORCL:DISK_4B |
NORMAL |
Then
Create Redo Log Groups in DB
-- as SYSDBA (not SYSASM)
ALTER DATABASE ADD LOGFILE
GROUP 1
('+REDO_A/redo_g1_1a.log',
'+REDO_A/redo_g1_3a.log') SIZE 512M;
ALTER DATABASE ADD LOGFILE
GROUP 2
('+REDO_A/redo_g2_2a.log',
'+REDO_A/redo_g2_4a.log') SIZE 512M;
ALTER DATABASE ADD LOGFILE
GROUP 3
('+REDO_B/redo_g3_1b.log',
'+REDO_B/redo_g3_3b.log') SIZE 512M;
ALTER DATABASE ADD LOGFILE
GROUP 4
('+REDO_B/redo_g4_2b.log',
'+REDO_B/redo_g4_4b.log') SIZE 512M;
Performance & Design Best Practices
|
Topic |
Recommendation |
|
I/O Distribution |
Always verify that each failgroup
maps to a separate controller path. |
|
Redo-only Diskgroup |
Keep redo logs in dedicated ASM
diskgroups to avoid random I/O interference. |
|
AU Size |
4 MB or 8 MB AU sizes are optimal
for redo workloads. |
|
ASM Rebalance Power |
Set ASM_POWER_LIMIT to 8–12 during
maintenance to avoid I/O stalls. |
|
Arch Dest Separation |
Store archives in a distinct
diskgroup +ARCH_DG or filesystem to prevent LGWR-ARCH contention. |