Skip to content

ORA-01114: IO Error Writing Block to File - Fix Disk Write Failures

Error Text: ORA-01114: IO error writing block to file string (block # string)

The ORA-01114 error occurs when Oracle encounters a physical I/O failure while attempting to write a data block to a datafile. It always appears alongside ORA-01110, which identifies the specific file involved. This is a serious error indicating a storage-layer problem — Oracle was unable to persist data to disk, which can threaten database integrity. Immediate investigation is required to prevent data loss or corruption.

  • The filesystem hosting the datafile has no free space remaining
  • A datafile with AUTOEXTEND ON reached its MAXSIZE limit and the filesystem has no room to grow further
  • Archivelog destination filled up, indirectly blocking redo writes and cascading to datafile I/O

2. Physical Disk or Storage Hardware Failure

Section titled “2. Physical Disk or Storage Hardware Failure”
  • Underlying disk developed bad sectors or failed entirely
  • RAID controller failure causing writes to be rejected
  • SAN fabric connectivity loss causing the storage path to become unavailable
  • I/O timeout from a slow or failing storage device
  • ASM disk group lost one or more disks, dropping below the redundancy threshold
  • ASM disk group free space exhausted, preventing new extent allocation
  • ASM rebalance in progress combined with a disk failure leaving the group in a degraded state
  • NFS server became unavailable or rebooted, unmounting the Oracle datafile path
  • NFS mount options not set to Oracle-recommended values (hard, nointr, rsize/wsize)
  • Network partition between Oracle server and NFS filer causing write timeouts
  • Oracle OS user hit a ulimit restriction on file size
  • Kernel file descriptor limit exhausted
  • Permissions on the file or directory changed, blocking writes by the Oracle process
  • Disk write cache disabled on storage causing latency-induced timeouts
  • Asynchronous I/O (DISK_ASYNCH_IO) configuration mismatch with the OS
  • Corrupted block being written that is rejected by storage-level integrity checks
-- Get full details of the file referenced in the error
-- Replace &file_number with the number from the ORA-01114 message
SELECT
df.file#,
df.name AS file_path,
df.status,
df.enabled,
ts.name AS tablespace_name,
ROUND(df.bytes / 1024 / 1024, 2) AS size_mb,
ROUND(df.blocks * 8192 / 1024 / 1024, 2) AS blocks_mb
FROM v$datafile df
JOIN v$tablespace ts ON df.ts# = ts.ts#
WHERE df.file# = &file_number;
-- Check autoextend configuration for the file
SELECT
file_id,
file_name,
tablespace_name,
ROUND(bytes / 1024 / 1024, 2) AS current_size_mb,
autoextensible,
ROUND(maxbytes / 1024 / 1024, 2) AS max_size_mb,
ROUND(increment_by * 8192 / 1024 / 1024, 2) AS increment_mb
FROM dba_data_files
WHERE file_id = &file_number;
-- Check free space across all tablespaces and their datafiles
SELECT
ts.tablespace_name,
ts.status,
ROUND(SUM(df.bytes) / 1024 / 1024 / 1024, 2) AS total_gb,
ROUND(SUM(COALESCE(fs.free_bytes, 0)) / 1024 / 1024 / 1024, 2) AS free_gb,
ROUND(
(1 - SUM(COALESCE(fs.free_bytes, 0)) / NULLIF(SUM(df.bytes), 0)) * 100,
1
) AS pct_used
FROM dba_tablespaces ts
JOIN dba_data_files df ON ts.tablespace_name = df.tablespace_name
LEFT JOIN (
SELECT tablespace_name, SUM(bytes) AS free_bytes
FROM dba_free_space
GROUP BY tablespace_name
) fs ON ts.tablespace_name = fs.tablespace_name
GROUP BY ts.tablespace_name, ts.status
ORDER BY pct_used DESC NULLS LAST;
-- Review alert log for ORA-01114 occurrences and surrounding messages
SELECT
originating_timestamp,
message_text
FROM v$diag_alert_ext
WHERE message_text LIKE '%ORA-01114%'
OR message_text LIKE '%ORA-01110%'
OR message_text LIKE '%write error%'
OR message_text LIKE '%I/O error%'
ORDER BY originating_timestamp DESC
FETCH FIRST 100 ROWS ONLY;
-- If datafiles reside on ASM, check disk group status
SELECT
group_number,
name,
state,
type,
ROUND(total_mb / 1024, 2) AS total_gb,
ROUND(free_mb / 1024, 2) AS free_gb,
ROUND(usable_file_mb / 1024, 2) AS usable_gb,
offline_disks
FROM v$asm_diskgroup
ORDER BY name;
-- Check for ASM disks in an error or offline state
SELECT
group_number,
disk_number,
name,
path,
state,
mode_status,
total_mb,
free_mb,
read_errs,
write_errs
FROM v$asm_disk
WHERE write_errs > 0
OR state != 'NORMAL'
OR mode_status != 'ONLINE'
ORDER BY group_number, disk_number;
-- Review I/O statistics per datafile to spot high error counts
SELECT
file#,
name,
phywrts,
phyblkwrt,
writetim,
CASE WHEN phywrts > 0
THEN ROUND(writetim / phywrts, 4)
ELSE 0
END AS avg_write_time_cs,
wait_count,
time
FROM v$filestat fs
JOIN v$datafile df USING (file#)
ORDER BY wait_count DESC;
-- Check for sessions currently waiting on file I/O
SELECT
s.sid,
s.serial#,
s.username,
s.status,
s.event,
s.p1 AS file_number,
s.p2 AS block_number,
s.seconds_in_wait,
s.sql_id
FROM v$session s
WHERE s.event LIKE '%db file%'
OR s.event LIKE '%direct path write%'
ORDER BY s.seconds_in_wait DESC;

Before making any Oracle-level changes, verify the storage situation at the OS level:

Terminal window
# Check filesystem usage on the host containing the datafile
df -h /path/to/datafile/directory
# Check for I/O errors in the OS kernel log
dmesg | grep -i 'error\|fail\|i/o' | tail -50
# Check if NFS mount is still active
mount | grep nfs
# Verify the datafile is readable and writable by the oracle OS user
ls -lh /path/to/datafile.dbf
# Check Oracle process file descriptor limits
cat /proc/$(pgrep -n ora_dbw)/limits | grep 'open files'

If the filesystem is full, free space or add capacity before attempting Oracle recovery:

Terminal window
# Identify large files consuming space
du -sh /path/to/oracle/directories/* | sort -h | tail -20
# Remove old trace files if appropriate
find $ORACLE_BASE/diag -name '*.trc' -mtime +30 -delete
find $ORACLE_BASE/diag -name '*.trm' -mtime +30 -delete

After freeing OS space, add a new datafile to spread load:

-- Add a new datafile to the affected tablespace
ALTER TABLESPACE &tablespace_name
ADD DATAFILE '/u02/oradata/&tablespace_name._02.dbf'
SIZE 2G AUTOEXTEND ON NEXT 256M MAXSIZE 10G;
-- Or resize an existing autoextensible datafile if maxsize was the constraint
ALTER DATABASE DATAFILE '/u01/oradata/&tablespace_name._01.dbf'
AUTOEXTEND ON NEXT 256M MAXSIZE 20G;

3. Recover from a Disk or Storage Failure Using RMAN

Section titled “3. Recover from a Disk or Storage Failure Using RMAN”

If the underlying storage has failed and the file is damaged:

-- From RMAN: validate current state of all datafiles
VALIDATE DATABASE;
-- Restore and recover the damaged datafile
-- (Database can stay open in ARCHIVELOG mode)
RUN {
SQL 'ALTER DATABASE DATAFILE &file_number OFFLINE';
RESTORE DATAFILE &file_number;
RECOVER DATAFILE &file_number;
SQL 'ALTER DATABASE DATAFILE &file_number ONLINE';
}

If the datafile resides on NFS and the mount is lost:

Terminal window
# Remount the NFS share (run as root)
umount -l /nfs/oracle/datafiles
mount -o rw,hard,nointr,rsize=32768,wsize=32768,tcp,vers=3 \
nfsserver:/export/oracle /nfs/oracle/datafiles
# Verify the mount is active and files are visible
ls -lh /nfs/oracle/datafiles/*.dbf

Recommended NFS mount options for Oracle datafiles:

  • hard — Oracle requires hard mounts; soft mounts can silently lose writes
  • nointr — prevents signal interruption of I/O operations
  • rsize=32768,wsize=32768 — aligns I/O size with Oracle block sizes
  • tcp — use TCP for reliable transport
  • vers=3 or vers=4 — use NFSv3 or NFSv4 as appropriate

5. Address ASM Disk Group Space Exhaustion

Section titled “5. Address ASM Disk Group Space Exhaustion”
-- From ASM instance or ASMCMD: check disk group free space
SELECT name, ROUND(free_mb/1024,2) AS free_gb, ROUND(total_mb/1024,2) AS total_gb
FROM v$asm_diskgroup;
-- Add a disk to the ASM disk group to expand capacity
-- (Run from ASM instance or ASMCA)
ALTER DISKGROUP data ADD DISK '/dev/sde' NAME DATA_0004;
-- Monitor rebalance progress
SELECT operation, state, power, est_minutes FROM v$asm_operation;

If the write failure is related to async I/O configuration:

-- Check current async I/O settings
SHOW PARAMETER disk_asynch_io;
SHOW PARAMETER filesystemio_options;
-- For filesystem datafiles, ensure direct I/O is enabled
ALTER SYSTEM SET filesystemio_options = SETALL SCOPE=SPFILE;
-- Requires database restart to take effect
-- Create a procedure to alert when any tablespace exceeds 85% full
CREATE OR REPLACE PROCEDURE monitor_tablespace_space AS
BEGIN
FOR r IN (
SELECT
ts.tablespace_name,
ROUND(SUM(df.bytes) / 1024 / 1024, 2) AS total_mb,
ROUND(NVL(SUM(fs.bytes), 0) / 1024 / 1024, 2) AS free_mb,
ROUND(
(1 - NVL(SUM(fs.bytes), 0) / SUM(df.bytes)) * 100, 1
) AS pct_used
FROM dba_tablespaces ts
JOIN dba_data_files df ON ts.tablespace_name = df.tablespace_name
LEFT JOIN dba_free_space fs ON ts.tablespace_name = fs.tablespace_name
WHERE ts.contents != 'TEMPORARY'
GROUP BY ts.tablespace_name
HAVING ROUND((1 - NVL(SUM(fs.bytes),0)/SUM(df.bytes))*100, 1) > 85
) LOOP
DBMS_OUTPUT.PUT_LINE(
'WARNING: Tablespace ' || r.tablespace_name ||
' is ' || r.pct_used || '% full (' ||
r.free_mb || ' MB free)'
);
END LOOP;
END;
/
BEGIN
DBMS_SCHEDULER.CREATE_JOB(
job_name => 'MONITOR_TS_SPACE_JOB',
job_type => 'STORED_PROCEDURE',
job_action => 'monitor_tablespace_space',
repeat_interval => 'FREQ=HOURLY;INTERVAL=1',
enabled => TRUE,
comments => 'Alert when tablespace space usage exceeds 85%'
);
END;
/

2. Configure Autoextend with Sensible Limits

Section titled “2. Configure Autoextend with Sensible Limits”
-- Review all datafiles to ensure AUTOEXTEND is configured
SELECT
file_name,
tablespace_name,
ROUND(bytes/1024/1024, 2) AS current_mb,
autoextensible,
ROUND(maxbytes/1024/1024/1024, 2) AS max_gb,
ROUND(increment_by * 8192 / 1024 / 1024, 2) AS increment_mb
FROM dba_data_files
WHERE autoextensible = 'NO'
OR maxbytes = 0
ORDER BY tablespace_name;
-- Enable AUTOEXTEND on datafiles that have it disabled
ALTER DATABASE DATAFILE '/u01/oradata/users01.dbf'
AUTOEXTEND ON NEXT 128M MAXSIZE 10G;
  • Never place Oracle datafiles on filesystems that are shared with other applications consuming unpredictable amounts of space
  • Use ASM for Oracle datafiles wherever possible — it provides better I/O distribution and failure handling than raw filesystems
  • Enable Oracle Database’s fast-start fault recovery to minimize the duration of write-failure windows
  • Keep at least 15–20% free space on every filesystem hosting Oracle files as a buffer for unexpected growth
  • Configure DB_WRITER_PROCESSES appropriate for the storage subsystem (typically 1 per 8 CPUs for modern storage)

These Oracle Day by Day scripts can assist with storage and I/O analysis:

  • gvsess.sql — Identify sessions waiting on I/O events
-- Determine scope: how many files are affected?
SELECT file#, name, status, enabled FROM v$datafile WHERE status NOT IN ('ONLINE','SYSTEM');
-- Is the database still functional for other tablespaces?
SELECT tablespace_name, status FROM dba_tablespaces WHERE status != 'ONLINE';
-- Identify what users/applications are impacted
SELECT DISTINCT owner, segment_name, segment_type
FROM dba_segments
WHERE tablespace_name = '&affected_tablespace';
  1. Check the alert log for the ORA-01110 companion error identifying the exact file and the OS-level error underneath it
  2. Verify filesystem space with df -h before doing anything else — a full filesystem is the most common and easiest-to-fix cause
  3. Do not attempt to write more data to the affected tablespace until the root cause is resolved
  4. Engage the storage team if the issue is at the SAN, NFS, or hardware level — Oracle cannot self-heal a failed disk
-- Confirm all datafiles are online and writable
SELECT file#, name, status FROM v$datafile ORDER BY file#;
-- Force a checkpoint to ensure all dirty buffers flush successfully
ALTER SYSTEM CHECKPOINT;
-- Confirm no pending I/O errors in recent AWR data
SELECT event, total_waits, total_timeouts, time_waited_micro
FROM v$system_event
WHERE event LIKE '%write%'
OR event LIKE '%I/O%'
ORDER BY time_waited_micro DESC
FETCH FIRST 10 ROWS ONLY;