ORA-15063 ASM Discovered Insufficient Number of Disks - Disk Discovery Fix
ORA-15063: ASM Discovered an Insufficient Number of Disks for Diskgroup
Section titled “ORA-15063: ASM Discovered an Insufficient Number of Disks for Diskgroup”Error Overview
Section titled “Error Overview”Error Text: ORA-15063: ASM discovered an insufficient number of disks for diskgroup "diskgroup_name"
This error occurs when ASM (Automatic Storage Management) cannot discover enough disks to create or mount a diskgroup according to its redundancy requirements. The error typically appears during diskgroup creation, mount operations, or after system changes that affect disk visibility.
Understanding ASM Disk Requirements
Section titled “Understanding ASM Disk Requirements”Minimum Disk Requirements by Redundancy
Section titled “Minimum Disk Requirements by Redundancy”Redundancy Requirements├── EXTERNAL REDUNDANCY│ ├── Minimum: 1 disk│ ├── No ASM mirroring│ └── Relies on external protection├── NORMAL REDUNDANCY│ ├── Minimum: 2 disks (2 failure groups)│ ├── Recommended: 3+ disks│ └── 2-way mirroring└── HIGH REDUNDANCY ├── Minimum: 3 disks (3 failure groups) ├── Recommended: 5+ disks └── 3-way mirroring
Disk Discovery Process
Section titled “Disk Discovery Process”-- ASM discovers disks based on:-- 1. ASM_DISKSTRING parameter paths-- 2. Disk header validation-- 3. Permissions and accessibility-- 4. Disk state (CANDIDATE, MEMBER, etc.)
Common Causes
Section titled “Common Causes”Discovery Configuration Issues
Section titled “Discovery Configuration Issues”- Incorrect ASM_DISKSTRING parameter
- Disk paths not included in discovery string
- Wildcard patterns not matching disks
- Case sensitivity in path names
Disk Accessibility Problems
Section titled “Disk Accessibility Problems”# Permission issues# Ownership problems# SELinux blocking access# Disk not visible to ASM instance
Storage Configuration Issues
Section titled “Storage Configuration Issues”- Disks not properly provisioned
- Multipath configuration incomplete
- Storage array mapping issues
- SAN zoning problems
Operating System Issues
Section titled “Operating System Issues”- Device drivers not loaded
- UDEV rules misconfigured
- Disk devices not created
- Kernel module problems
Diagnostic Steps
Section titled “Diagnostic Steps”Check Disk Discovery Configuration
Section titled “Check Disk Discovery Configuration”-- Connect to ASM instancesqlplus / as sysasm
-- Check current discovery stringSHOW PARAMETER asm_diskstring;
-- List all discovered disksSELECT path, header_status, state, total_mbFROM v$asm_diskORDER BY path;
-- Count available disks by statusSELECT header_status, COUNT(*) as disk_countFROM v$asm_diskGROUP BY header_statusORDER BY header_status;
Verify Disk Availability at OS Level
Section titled “Verify Disk Availability at OS Level”# List block deviceslsblkls -la /dev/sd*ls -la /dev/mapper/*
# Check Oracle ASM disksoracleasm listdisksls -la /dev/oracleasm/disks/
# Check multipath devicesmultipath -ll
# Verify disk accessibilityfor disk in /dev/oracleasm/disks/*; do echo "Checking $disk" dd if=$disk of=/dev/null bs=1M count=1 2>&1 | grep -v recordsdone
Analyze Disk Headers
Section titled “Analyze Disk Headers”# Check disk headers for ASM membershipfor disk in /dev/oracleasm/disks/*; do echo "=== Disk: $disk ===" kfed read $disk | grep -E "grptyp|dskname|grpname|provstr"done
# Check specific diskkfed read /dev/oracleasm/disks/DISK1 | head -50
Review System Configuration
Section titled “Review System Configuration”# Check loaded kernel moduleslsmod | grep oracle
# Check UDEV rulescat /etc/udev/rules.d/*asm*.rules
# Check SELinux statusgetenforcels -Z /dev/oracleasm/disks/
# Check disk permissionsls -la /dev/oracleasm/disks/
Resolution Steps
Section titled “Resolution Steps”1. Fix Discovery String Configuration
Section titled “1. Fix Discovery String Configuration”Update ASM_DISKSTRING Parameter
Section titled “Update ASM_DISKSTRING Parameter”-- Add all possible disk locationsALTER SYSTEM SET asm_diskstring = '/dev/oracleasm/disks/*','/dev/sd*','/dev/mapper/*' SCOPE=BOTH;
-- For specific pathsALTER SYSTEM SET asm_diskstring = '/dev/oracleasm/disks/DISK*' SCOPE=BOTH;
-- Force re-discoveryALTER SYSTEM SET asm_diskstring = '' SCOPE=MEMORY;ALTER SYSTEM SET asm_diskstring = '/dev/oracleasm/disks/*' SCOPE=MEMORY;
-- Verify discoverySELECT path, header_status FROM v$asm_disk ORDER BY path;
Test Discovery Patterns
Section titled “Test Discovery Patterns”-- Test specific patternALTER SYSTEM SET asm_diskstring = '/dev/oracleasm/disks/DATA*' SCOPE=MEMORY;SELECT COUNT(*) FROM v$asm_disk WHERE header_status = 'CANDIDATE';
-- Test multiple patternsALTER SYSTEM SET asm_diskstring = '/dev/oracleasm/disks/*','/dev/raw/*' SCOPE=MEMORY;SELECT path, header_status FROM v$asm_disk WHERE header_status IN ('CANDIDATE', 'MEMBER');
2. Create and Configure Disks
Section titled “2. Create and Configure Disks”Create Oracle ASM Disks
Section titled “Create Oracle ASM Disks”# Create ASM disk from partitionoracleasm createdisk DISK1 /dev/sdb1oracleasm createdisk DISK2 /dev/sdc1oracleasm createdisk DISK3 /dev/sdd1
# Scan for new disksoracleasm scandisksoracleasm listdisks
# Verify disk creationls -la /dev/oracleasm/disks/
Configure Multipath Devices
Section titled “Configure Multipath Devices”# Check multipath configurationcat /etc/multipath.conf
# Add ASM devices to multipathmultipath -a /dev/sdbmultipath -a /dev/sdc
# Reload multipathmultipath -rmultipath -ll
# Create ASM disks on multipath devicesoracleasm createdisk DISK1 /dev/mapper/mpatha
3. Fix Permission Issues
Section titled “3. Fix Permission Issues”Set Correct Ownership
Section titled “Set Correct Ownership”# Oracle ASM diskschown grid:asmadmin /dev/oracleasm/disks/*chmod 660 /dev/oracleasm/disks/*
# Raw deviceschown grid:asmadmin /dev/sd[b-z]*chmod 660 /dev/sd[b-z]*
# Multipath deviceschown grid:asmadmin /dev/mapper/asm*chmod 660 /dev/mapper/asm*
Configure UDEV Rules
Section titled “Configure UDEV Rules”# Create UDEV rule for ASM diskscat > /etc/udev/rules.d/99-oracle-asmdevices.rules << EOF# ASM disk rulesKERNEL=="sd*", SUBSYSTEM=="block", PROGRAM=="/usr/lib/udev/scsi_id -g -u -d /dev/\$name", \ RESULT=="360000000000000000000000000000001", OWNER="grid", GROUP="asmadmin", MODE="0660"EOF
# Reload UDEV rulesudevadm control --reload-rulesudevadm trigger --type=devices --action=change
4. Provision Additional Disks
Section titled “4. Provision Additional Disks”Add New Disks to System
Section titled “Add New Disks to System”# Scan for new SCSI devicesfor host in /sys/class/scsi_host/*; do echo "- - -" > $host/scandone
# Check for new devicesdmesg | tail -20lsblk
# Partition new diskfdisk /dev/sde# Create primary partition using full disk
# Create ASM diskoracleasm createdisk DISK4 /dev/sde1
Verify Sufficient Disks
Section titled “Verify Sufficient Disks”-- Check available disks for diskgroup creationSELECT COUNT(*) as candidate_disksFROM v$asm_diskWHERE header_status = 'CANDIDATE';
-- List candidate disksSELECT path, total_mbFROM v$asm_diskWHERE header_status = 'CANDIDATE'ORDER BY path;
-- Create diskgroup with available disksCREATE DISKGROUP data NORMAL REDUNDANCYDISK '/dev/oracleasm/disks/DISK1', '/dev/oracleasm/disks/DISK2', '/dev/oracleasm/disks/DISK3';
Advanced Solutions
Section titled “Advanced Solutions”Force Discovery with Specific Permissions
Section titled “Force Discovery with Specific Permissions”#!/bin/bash# Force disk discovery with permission fix
# Set ASM environmentexport ORACLE_HOME=/u01/app/19.0.0/gridexport ORACLE_SID=+ASM
# Fix permissions on all potential ASM disksfor dev in /dev/sd[b-z]*; do if [ -b "$dev" ]; then chown grid:asmadmin "$dev" chmod 660 "$dev" fidone
# Clear ASM disk cache$ORACLE_HOME/bin/sqlplus -s / as sysasm << EOFALTER SYSTEM SET asm_diskstring = '' SCOPE=MEMORY;ALTER SYSTEM SET asm_diskstring = '/dev/sd*' SCOPE=MEMORY;EOF
# List discovered disks$ORACLE_HOME/bin/sqlplus -s / as sysasm << EOFCOL path FORMAT A30SELECT path, header_status, total_mbFROM v\$asm_diskWHERE header_status IN ('CANDIDATE', 'MEMBER')ORDER BY path;EOF
Troubleshoot Discovery Issues
Section titled “Troubleshoot Discovery Issues”-- Create discovery diagnostic procedureCREATE OR REPLACE PROCEDURE diagnose_disk_discovery AS v_diskstring VARCHAR2(4000); v_count NUMBER;BEGIN -- Get current diskstring SELECT value INTO v_diskstring FROM v$parameter WHERE name = 'asm_diskstring';
DBMS_OUTPUT.PUT_LINE('Current ASM_DISKSTRING: ' || v_diskstring); DBMS_OUTPUT.PUT_LINE('==================================');
-- Count disks by status FOR rec IN ( SELECT header_status, COUNT(*) as cnt FROM v$asm_disk GROUP BY header_status ) LOOP DBMS_OUTPUT.PUT_LINE(rec.header_status || ': ' || rec.cnt || ' disks'); END LOOP;
-- Check for specific issues SELECT COUNT(*) INTO v_count FROM v$asm_disk WHERE header_status = 'CANDIDATE';
IF v_count = 0 THEN DBMS_OUTPUT.PUT_LINE('WARNING: No candidate disks found!'); DBMS_OUTPUT.PUT_LINE('Check:'); DBMS_OUTPUT.PUT_LINE('1. Disk permissions'); DBMS_OUTPUT.PUT_LINE('2. ASM_DISKSTRING parameter'); DBMS_OUTPUT.PUT_LINE('3. Disk provisioning'); END IF;
-- List problematic disks DBMS_OUTPUT.PUT_LINE('=================================='); DBMS_OUTPUT.PUT_LINE('Problematic disks:'); FOR rec IN ( SELECT path, header_status FROM v$asm_disk WHERE header_status NOT IN ('MEMBER', 'CANDIDATE') ) LOOP DBMS_OUTPUT.PUT_LINE(rec.path || ' - ' || rec.header_status); END LOOP;END;/
-- Execute diagnosticSET SERVEROUTPUT ONEXEC diagnose_disk_discovery;
Clear and Reinitialize Disks
Section titled “Clear and Reinitialize Disks”#!/bin/bash# Clear and reinitialize ASM disks
# WARNING: This destroys data!read -p "This will destroy all data on ASM disks. Continue? (yes/no): " confirmif [ "$confirm" != "yes" ]; then echo "Aborted." exit 1fi
# Stop ASMcrsctl stop resource ora.asm -f
# Clear disk headersfor disk in /dev/oracleasm/disks/*; do echo "Clearing $disk..." dd if=/dev/zero of=$disk bs=1M count=100done
# Delete and recreate ASM disksoracleasm deletedisk DISK1oracleasm deletedisk DISK2oracleasm deletedisk DISK3
# Recreate disksoracleasm createdisk DISK1 /dev/sdb1oracleasm createdisk DISK2 /dev/sdc1oracleasm createdisk DISK3 /dev/sdd1
# Start ASMcrsctl start resource ora.asm
Monitoring and Prevention
Section titled “Monitoring and Prevention”Disk Discovery Monitoring
Section titled “Disk Discovery Monitoring”#!/bin/bash# Monitor ASM disk discovery
LOG_FILE="/var/log/asm_discovery_monitor.log"
monitor_discovery() { timestamp=$(date '+%Y-%m-%d %H:%M:%S')
# Get disk counts TOTAL=$(/u01/app/19.0.0/grid/bin/sqlplus -s / as sysasm << EOF SET PAGESIZE 0 FEEDBACK OFF HEADING OFF SELECT COUNT(*) FROM v\$asm_disk;EOF )
CANDIDATE=$(/u01/app/19.0.0/grid/bin/sqlplus -s / as sysasm << EOF SET PAGESIZE 0 FEEDBACK OFF HEADING OFF SELECT COUNT(*) FROM v\$asm_disk WHERE header_status = 'CANDIDATE';EOF )
MEMBER=$(/u01/app/19.0.0/grid/bin/sqlplus -s / as sysasm << EOF SET PAGESIZE 0 FEEDBACK OFF HEADING OFF SELECT COUNT(*) FROM v\$asm_disk WHERE header_status = 'MEMBER';EOF )
echo "$timestamp: Total=$TOTAL, Candidate=$CANDIDATE, Member=$MEMBER" >> $LOG_FILE
# Alert if no candidate disks if [ "$CANDIDATE" -eq 0 ] && [ "$MEMBER" -eq 0 ]; then fi}
# Run monitoringmonitor_discovery
Automated Discovery Testing
Section titled “Automated Discovery Testing”-- Create automated discovery testCREATE OR REPLACE PROCEDURE test_disk_discovery( p_min_disks NUMBER DEFAULT 3) AS v_candidate_count NUMBER; v_member_count NUMBER; v_total_count NUMBER;BEGIN -- Count disks by type SELECT COUNT(*) INTO v_candidate_count FROM v$asm_disk WHERE header_status = 'CANDIDATE';
SELECT COUNT(*) INTO v_member_count FROM v$asm_disk WHERE header_status = 'MEMBER';
v_total_count := v_candidate_count + v_member_count;
-- Log results INSERT INTO asm_discovery_log VALUES ( SYSTIMESTAMP, v_total_count, v_candidate_count, v_member_count );
-- Check minimum requirements IF v_total_count < p_min_disks THEN RAISE_APPLICATION_ERROR(-20001, 'Insufficient disks discovered: ' || v_total_count || ' (minimum: ' || p_min_disks || ')'); END IF;
COMMIT;END;/
-- Schedule regular testingBEGIN DBMS_SCHEDULER.CREATE_JOB( job_name => 'TEST_ASM_DISCOVERY', job_type => 'PLSQL_BLOCK', job_action => 'BEGIN test_disk_discovery(3); END;', start_date => SYSTIMESTAMP, repeat_interval => 'FREQ=DAILY', enabled => TRUE );END;/
Emergency Procedures
Section titled “Emergency Procedures”Emergency Disk Discovery
Section titled “Emergency Disk Discovery”#!/bin/bash# Emergency disk discovery script
echo "Starting emergency ASM disk discovery..."
# 1. Stop and start ASM disk serviceoracleasm stoporacleasm start
# 2. Scan all possible locationsoracleasm scandisks
# 3. Force permission resetfind /dev -name "sd[b-z]*" -exec chown grid:asmadmin {} \;find /dev -name "sd[b-z]*" -exec chmod 660 {} \;
# 4. Try multiple discovery stringssu - grid << 'EOF'sqlplus / as sysasm << SQL-- Try different discovery patternsALTER SYSTEM SET asm_diskstring = '/dev/sd*' SCOPE=MEMORY;SELECT COUNT(*) as found_disks FROM v$asm_disk;
ALTER SYSTEM SET asm_diskstring = '/dev/oracleasm/disks/*' SCOPE=MEMORY;SELECT COUNT(*) as found_disks FROM v$asm_disk;
ALTER SYSTEM SET asm_diskstring = '/dev/mapper/*' SCOPE=MEMORY;SELECT COUNT(*) as found_disks FROM v$asm_disk;
-- Set final discovery stringALTER SYSTEM SET asm_diskstring = '/dev/oracleasm/disks/*','/dev/sd*' SCOPE=BOTH;SQLEOF
echo "Emergency discovery completed"
Minimal Diskgroup Creation
Section titled “Minimal Diskgroup Creation”-- Create diskgroup with minimum disksDECLARE v_disk_count NUMBER; v_disk_list VARCHAR2(4000);BEGIN -- Find available disks SELECT COUNT(*) INTO v_disk_count FROM v$asm_disk WHERE header_status = 'CANDIDATE';
IF v_disk_count = 0 THEN RAISE_APPLICATION_ERROR(-20001, 'No candidate disks available'); ELSIF v_disk_count = 1 THEN -- External redundancy with 1 disk SELECT path INTO v_disk_list FROM v$asm_disk WHERE header_status = 'CANDIDATE' AND ROWNUM = 1;
EXECUTE IMMEDIATE 'CREATE DISKGROUP emergency EXTERNAL REDUNDANCY DISK ''' || v_disk_list || ''''; ELSE -- Normal redundancy with available disks SELECT LISTAGG('''' || path || '''', ',') WITHIN GROUP (ORDER BY path) INTO v_disk_list FROM ( SELECT path FROM v$asm_disk WHERE header_status = 'CANDIDATE' AND ROWNUM <= 3 );
EXECUTE IMMEDIATE 'CREATE DISKGROUP emergency NORMAL REDUNDANCY DISK ' || v_disk_list; END IF;
DBMS_OUTPUT.PUT_LINE('Emergency diskgroup created with ' || v_disk_count || ' disks');END;/
Best Practices
Section titled “Best Practices”- Configure comprehensive ASM_DISKSTRING patterns
- Standardize disk naming conventions
- Document disk-to-device mappings
- Regular discovery validation tests
- Monitor disk visibility continuously
- Implement automated discovery troubleshooting
- Maintain disk inventory documentation
Related Errors
Section titled “Related Errors”- ORA-15001: Diskgroup does not exist or is not mounted
- ORA-15018: Diskgroup cannot be created
- ORA-15020: Discovered duplicate ASM disk
- ORA-15025: Could not open disk
Troubleshooting Checklist
Section titled “Troubleshooting Checklist”- Verify ASM_DISKSTRING includes all disk paths
- Check disk existence at OS level
- Confirm disk permissions (grid:asmadmin)
- Test disk accessibility with dd command
- Verify UDEV rules are correct
- Check for SELinux/AppArmor restrictions
- Scan for new disks at OS level
- Review ASM alert log for discovery errors