Skip to content

ORA-15042 ASM Disk Is Missing - Disk Recovery and Replacement Guide

ORA-15042: ASM Disk “disk_name” Is Missing

Section titled “ORA-15042: ASM Disk “disk_name” Is Missing”

Error Text: ORA-15042: ASM disk "disk_name" is missing

This error occurs when ASM (Automatic Storage Management) cannot find a disk that is supposed to be part of a diskgroup. The disk may have failed, been removed, or become inaccessible due to various reasons. This error indicates a potential risk to data redundancy and requires immediate attention to prevent data loss.

ASM Disk Lifecycle States
├── CANDIDATE - Available for ASM use
├── MEMBER - Part of a diskgroup
├── FORMER - Was part of a diskgroup
├── PROVISIONED - Prepared but not used
├── CONFLICT - Header conflicts
└── FOREIGN - Contains non-ASM data
ASM Disk Discovery
├── Read ASM_DISKSTRING paths
├── Open and read disk headers
├── Validate ASM metadata
├── Check disk membership
└── Update v$asm_disk view
  • Physical disk failure
  • Controller failure
  • Cable disconnection
  • Power supply issues
  • Storage array problems
Terminal window
# Path changes
# Multipathing issues
# Permission changes
# Disk partition changes
# Device naming changes
  • Device driver problems
  • Kernel module not loaded
  • UDEV rules misconfigured
  • Filesystem mounted over ASM disk
  • SELinux/permissions blocking access
  • SAN connectivity issues
  • iSCSI target problems
  • Fiber channel path failures
  • Network timeout issues
-- Connect to ASM instance
sqlplus / as sysasm
-- Find missing disk details
SELECT dg.name as diskgroup_name,
d.name as disk_name,
d.path,
d.header_status,
d.mount_status,
d.state
FROM v$asm_disk d, v$asm_diskgroup dg
WHERE d.group_number = dg.group_number(+)
AND (d.mount_status = 'MISSING' OR d.header_status = 'FORMER')
ORDER BY dg.name, d.name;
-- Check specific diskgroup for missing disks
SELECT disk_number, name, path, mount_status, header_status, state
FROM v$asm_disk
WHERE group_number = (SELECT group_number FROM v$asm_diskgroup WHERE name = 'DATA')
AND mount_status = 'MISSING';
Terminal window
# List all available disks
ls -la /dev/oracleasm/disks/
lsblk
fdisk -l
# Check specific disk
ls -la /dev/oracleasm/disks/DISK1
file /dev/oracleasm/disks/DISK1
# Check disk accessibility
dd if=/dev/oracleasm/disks/DISK1 of=/dev/null bs=1M count=1
# Check multipath status
multipath -ll
multipath -v3 -ll | grep -A5 -B5 "DISK1"
Terminal window
# Check system messages
dmesg | grep -i "error\|fail\|offline"
tail -100 /var/log/messages | grep -i "disk\|scsi\|error"
# Check ASM logs
tail -500 $ORACLE_BASE/diag/asm/+asm/+ASM/trace/alert_+ASM.log | grep -i "disk\|missing\|offline"
# Check disk events
journalctl -u oracleasm -n 100
Terminal window
# For Oracle ASM disks
oracleasm status
oracleasm scandisks
oracleasm listdisks
# Query specific disk
oracleasm querydisk DISK1
# Check disk header
kfed read /dev/oracleasm/disks/DISK1 | head -20
-- Clear and reset discovery string
ALTER SYSTEM SET asm_diskstring = '' SCOPE=MEMORY;
ALTER SYSTEM SET asm_diskstring = '/dev/oracleasm/disks/*' SCOPE=MEMORY;
-- Check if disk reappears
SELECT path, header_status, mount_status, state
FROM v$asm_disk
WHERE path LIKE '%DISK1%';
-- Force specific path discovery
ALTER SYSTEM SET asm_diskstring = '/dev/oracleasm/disks/DISK1' SCOPE=MEMORY;
ALTER SYSTEM SET asm_diskstring = '/dev/oracleasm/disks/*' SCOPE=MEMORY;
Terminal window
# Rescan SCSI devices
for host in /sys/class/scsi_host/*; do
echo "- - -" > $host/scan
done
# Rescan Oracle ASM disks
oracleasm scandisks
# Restart Oracle ASM
oracleasm stop
oracleasm start
oracleasm scandisks
Terminal window
# Check and fix permissions
ls -la /dev/oracleasm/disks/
chown grid:asmadmin /dev/oracleasm/disks/DISK1
chmod 660 /dev/oracleasm/disks/DISK1
# For raw devices
chown grid:asmadmin /dev/sdb1
chmod 660 /dev/sdb1
# Update UDEV rules if needed
vi /etc/udev/rules.d/99-oracle-asmdevices.rules
udevadm control --reload-rules
udevadm trigger
Terminal window
# Check multipath configuration
cat /etc/multipath.conf
# Reload multipath
multipath -r
# Check specific device
multipath -ll /dev/sdb
# Add device to multipath
multipath -a /dev/sdb
-- Attempt to online the disk
ALTER DISKGROUP data ONLINE DISK data_0001;
-- Force online
ALTER DISKGROUP data ONLINE DISK data_0001 FORCE;
-- Online by path
ALTER DISKGROUP data ONLINE DISK '/dev/oracleasm/disks/DISK1';
-- Online all missing disks
ALTER DISKGROUP data ONLINE DISKS IN FAILGROUP failure_group_1;
-- Drop missing disk and add replacement
ALTER DISKGROUP data
DROP DISK data_0001 FORCE
ADD DISK '/dev/oracleasm/disks/NEWDISK1' NAME data_0001_new
REBALANCE POWER 10;
-- Monitor rebalance
SELECT * FROM v$asm_operation;
-- Check disk status after rebalance
SELECT name, path, mount_status, header_status, state
FROM v$asm_disk
WHERE group_number = (SELECT group_number FROM v$asm_diskgroup WHERE name = 'DATA');
Terminal window
# Backup disk header before repair attempts
dd if=/dev/oracleasm/disks/DISK1 of=/backup/disk1_header.bak bs=4M count=1
# Analyze disk header
kfed read /dev/oracleasm/disks/DISK1 | grep -E "grpname|dskname|dsknum|grptyp"
# Clear disk header if corrupted (WARNING: Destructive)
dd if=/dev/zero of=/dev/oracleasm/disks/DISK1 bs=4M count=1
# Re-add disk to ASM
oracleasm createdisk DISK1 /dev/sdb1
-- Mount diskgroup despite missing disks
ALTER DISKGROUP data MOUNT FORCE;
-- Check redundancy status
SELECT file_number, redundancy_lowered, mirror_lowered, needs_resilver
FROM v$asm_file
WHERE group_number = (SELECT group_number FROM v$asm_diskgroup WHERE name = 'DATA')
AND (redundancy_lowered = 'Y' OR mirror_lowered = 'Y');
-- Drop missing disks after force mount
ALTER DISKGROUP data DROP DISK data_0001 FORCE;
Terminal window
# Use AMDU to extract files
amdu -diskstring '/dev/oracleasm/disks/*' -extract 'DATA.256' -output /recovery/
# Extract all files from diskgroup
amdu -diskstring '/dev/oracleasm/disks/*' -dump 'DATA' -output /recovery/dump/
#!/bin/bash
# Monitor for missing ASM disks
ORACLE_HOME=/u01/app/19.0.0/grid
ORACLE_SID=+ASM
export ORACLE_HOME ORACLE_SID
check_missing_disks() {
MISSING=$($ORACLE_HOME/bin/sqlplus -s / as sysasm << EOF
SET PAGESIZE 0 FEEDBACK OFF HEADING OFF
SELECT COUNT(*)
FROM v\$asm_disk
WHERE mount_status = 'MISSING' OR header_status = 'FORMER';
EOF
)
if [ "$MISSING" -gt 0 ]; then
echo "ALERT: $MISSING missing ASM disks detected"
# Get details
$ORACLE_HOME/bin/sqlplus -s / as sysasm << EOF
SET LINESIZE 200
COL diskgroup_name FORMAT A15
COL disk_name FORMAT A15
COL path FORMAT A30
SELECT dg.name as diskgroup_name,
d.name as disk_name,
d.path,
d.mount_status
FROM v\$asm_disk d, v\$asm_diskgroup dg
WHERE d.group_number = dg.group_number(+)
AND (d.mount_status = 'MISSING' OR d.header_status = 'FORMER');
EOF
# Send alert
echo "Missing ASM disks detected" | mail -s "ASM Disk Alert" [email protected]
else
echo "All ASM disks are present"
fi
}
# Run check
check_missing_disks
-- Create disk monitoring table
CREATE TABLE asm_disk_monitor (
check_time TIMESTAMP,
path VARCHAR2(256),
diskgroup_name VARCHAR2(30),
mount_status VARCHAR2(20),
header_status VARCHAR2(20),
state VARCHAR2(20),
read_errors NUMBER,
write_errors NUMBER
);
-- Monitoring procedure
CREATE OR REPLACE PROCEDURE monitor_asm_disk_health AS
BEGIN
-- Log disk status
INSERT INTO asm_disk_monitor
SELECT
SYSTIMESTAMP,
d.path,
dg.name,
d.mount_status,
d.header_status,
d.state,
d.read_errs,
d.write_errs
FROM v$asm_disk d, v$asm_diskgroup dg
WHERE d.group_number = dg.group_number(+);
-- Alert on issues
FOR rec IN (
SELECT path, mount_status, read_errs, write_errs
FROM v$asm_disk
WHERE mount_status != 'CACHED'
OR read_errs > 0
OR write_errs > 0
) LOOP
DBMS_OUTPUT.PUT_LINE('Disk issue: ' || rec.path ||
' Status: ' || rec.mount_status ||
' Read Errors: ' || rec.read_errs ||
' Write Errors: ' || rec.write_errs);
END LOOP;
COMMIT;
END;
/
-- Schedule regular monitoring
BEGIN
DBMS_SCHEDULER.CREATE_JOB(
job_name => 'ASM_DISK_HEALTH_CHECK',
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN monitor_asm_disk_health; END;',
start_date => SYSTIMESTAMP,
repeat_interval => 'FREQ=HOURLY',
enabled => TRUE
);
END;
/
#!/bin/bash
# Automated disk recovery script
ORACLE_HOME=/u01/app/19.0.0/grid
ORACLE_SID=+ASM
export ORACLE_HOME ORACLE_SID
recover_missing_disk() {
local disk_path=$1
local disk_name=$2
local diskgroup=$3
echo "Attempting to recover disk $disk_name at $disk_path"
# Step 1: Check OS level
if [ ! -e "$disk_path" ]; then
echo "Disk path does not exist, scanning for new devices..."
oracleasm scandisks
sleep 5
fi
# Step 2: Check permissions
if [ -e "$disk_path" ]; then
chown grid:asmadmin "$disk_path"
chmod 660 "$disk_path"
fi
# Step 3: Force rediscovery
$ORACLE_HOME/bin/sqlplus -s / as sysasm << EOF
ALTER SYSTEM SET asm_diskstring = '$disk_path' SCOPE=MEMORY;
ALTER SYSTEM SET asm_diskstring = '/dev/oracleasm/disks/*' SCOPE=MEMORY;
EOF
# Step 4: Try to online disk
$ORACLE_HOME/bin/sqlplus -s / as sysasm << EOF
ALTER DISKGROUP $diskgroup ONLINE DISK '$disk_name';
EOF
# Check result
RESULT=$($ORACLE_HOME/bin/sqlplus -s / as sysasm << EOF
SET PAGESIZE 0 FEEDBACK OFF HEADING OFF
SELECT mount_status FROM v\$asm_disk WHERE name = '$disk_name';
EOF
)
if [ "$RESULT" = "CACHED" ]; then
echo "Disk $disk_name successfully recovered"
return 0
else
echo "Failed to recover disk $disk_name"
return 1
fi
}
# Main recovery loop
$ORACLE_HOME/bin/sqlplus -s / as sysasm << EOF > /tmp/missing_disks.txt
SET PAGESIZE 0 FEEDBACK OFF HEADING OFF
SELECT d.path || '|' || d.name || '|' || dg.name
FROM v\$asm_disk d, v\$asm_diskgroup dg
WHERE d.group_number = dg.group_number(+)
AND d.mount_status = 'MISSING';
EOF
while IFS='|' read -r path name diskgroup; do
recover_missing_disk "$path" "$name" "$diskgroup"
done < /tmp/missing_disks.txt
-- Emergency script for critical diskgroups
DECLARE
v_critical_dg VARCHAR2(30) := 'DATA';
v_missing_count NUMBER;
BEGIN
-- Count missing disks
SELECT COUNT(*) INTO v_missing_count
FROM v$asm_disk
WHERE group_number = (SELECT group_number FROM v$asm_diskgroup WHERE name = v_critical_dg)
AND mount_status = 'MISSING';
IF v_missing_count > 0 THEN
DBMS_OUTPUT.PUT_LINE('CRITICAL: ' || v_missing_count || ' disks missing from ' || v_critical_dg);
-- Attempt force mount
BEGIN
EXECUTE IMMEDIATE 'ALTER DISKGROUP ' || v_critical_dg || ' MOUNT FORCE';
DBMS_OUTPUT.PUT_LINE('Force mount successful');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Force mount failed: ' || SQLERRM);
END;
-- Drop missing disks
FOR disk IN (
SELECT name FROM v$asm_disk
WHERE group_number = (SELECT group_number FROM v$asm_diskgroup WHERE name = v_critical_dg)
AND mount_status = 'MISSING'
) LOOP
BEGIN
EXECUTE IMMEDIATE 'ALTER DISKGROUP ' || v_critical_dg ||
' DROP DISK ' || disk.name || ' FORCE';
DBMS_OUTPUT.PUT_LINE('Dropped missing disk: ' || disk.name);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Failed to drop ' || disk.name || ': ' || SQLERRM);
END;
END LOOP;
END IF;
END;
/
  1. Monitor disk health continuously
  2. Configure proper disk discovery strings
  3. Maintain consistent device naming
  4. Use ASM disk labels for easy identification
  5. Implement redundancy appropriate to SLA
  6. Regular disk path and permission audits
  7. Automate disk recovery procedures
  • ORA-15001: Diskgroup does not exist or is not mounted
  • ORA-15017: Diskgroup cannot be mounted
  • ORA-15040: Diskgroup is incomplete
  • ORA-15063: ASM discovered an insufficient number of disks
  • Identify missing disk name and path
  • Check disk existence at OS level
  • Verify disk permissions and ownership
  • Scan for new/changed disk devices
  • Check multipath configuration
  • Force ASM disk rediscovery
  • Attempt to online the disk
  • Consider disk replacement if unrecoverable