I was never 100% clear to me you could remove a disk from a diskgroup wtih EXTERNAL redundancy without having data loss, so let’s to a test.

We are going to do it on Oracle GI 19c, but I don’t see why it should not work on older versions. But please always try to replicate the same on a lab before doing it on a live DB.

1:- Add a new disk for the test:

[root@olinux8 ~]# asmcmd afd_label DATA2 /dev/sdc
[root@olinux8 ~]# asmcmd afd_lslbl
--------------------------------------------------------------------------------
Label                     Duplicate  Path
================================================================================
DATA                                  /dev/sda
DATA2                                 /dev/sdc  <<------
FRA                                   /dev/sdb
[root@olinux8 ~]#


[oracle@olinux8 ~]$ asmcmd lsdsk --candidate -p
Group_Num  Disk_Num      Incarn  Mount_Stat  Header_Stat  Mode_Stat  State   Path
        0         0           0  CLOSED      PROVISIONED  ONLINE     NORMAL  AFD:DATA2
[oracle@olinux8 ~]$


SQL> alter diskgroup DATA add disk 'AFD:DATA2';
Diskgroup altered.



set linesize 190
column "Diskgroup" format A20
column "Imbalance" format 99.9 Heading "Percent|Imbalance"
column "Variance" format 99.9 Heading "Percent|Disk Size|Variance"
column "MinFree" format 99.9 Heading "Minimum|Percent|Free"
column "DiskCnt" format 9999 Heading "Disk|Count"
column "Type" format A10 Heading "Diskgroup|Redundancy"
SELECT g.group_number, g.name "Diskgroup",
100*(max((d.total_mb-d.free_mb)/d.total_mb)-min((d.total_mb-d.free_mb)/d.total_mb))/max((d.total_mb-d.free_mb)/d.total_mb) "Imbalance",
100*(max(d.total_mb)-min(d.total_mb))/max(d.total_mb) "Variance",
100*(min(d.free_mb/d.total_mb)) "MinFree",
count(*) "DiskCnt",
g.type "Type"
FROM v$asm_disk d, v$asm_diskgroup g
WHERE d.group_number = g.group_number and
d.group_number <> 0 and
d.state = 'NORMAL' and
d.mount_status = 'CACHED'
GROUP BY g.group_number,g.name, g.type;


					      Percent Minimum
				    Percent Disk Size Percent  Disk Diskgroup
GROUP_NUMBER Diskgroup		  Imbalance  Variance	 Free Count Redundancy
------------ -------------------- --------- --------- ------- ----- ----------
	   1 DATA			1.0	   .0	 97.6	  2 EXTERN
	   2 FRA			 .0	   .0	 96.4	  1 EXTERN

SQL>


col PATH format a20
set linesize 190
col FREE_MB
set pagesize 50
select group_number, path, header_status, total_mb, free_mb from v$asm_disk order by 1,2;


GROUP_NUMBER PATH		  HEADER_STATU	 TOTAL_MB    FREE_MB
------------ -------------------- ------------ ---------- ----------
	   1 AFD:DATA		  MEMBER	    51200      49952
	   1 AFD:DATA2		  MEMBER	    51200      49964
	   2 AFD:FRA		  MEMBER	    30720      29606

SQL>

2:- Add a new datafile to see if space from both disks are used:

SQL> alter tablespace USERS add datafile size  10G autoextend on NEXT 1073741824 maxsize 32767M;
Tablespace altered.


SQL> select group_number, path, header_status, total_mb, free_mb from v$asm_disk order by 1,2;

GROUP_NUMBER PATH		  HEADER_STATU	 TOTAL_MB    FREE_MB
------------ -------------------- ------------ ---------- ----------
	   1 AFD:DATA		  MEMBER	    51200      44828
	   1 AFD:DATA2		  MEMBER	    51200      44840   <--- space added across both disks
	   2 AFD:FRA		  MEMBER	    30720      29606

SQL> select name,total_mb,free_mb,total_mb-free_mb used_mb, (free_mb/total_mb)*100 as "% Free space" from V$ASM_DISKGROUP;

NAME	          TOTAL_MB    FREE_MB	USED_MB % Free space
--------------- ---------- ---------- ---------- ------------
DATA		   102400      89668	  12732   87.5664063
FRA	 	    30720      29606	   1114   96.3736979

3:- Create a new table and populate (not needed on a real enviroment as it would be already populated)

SQL> CREATE TABLE testtable
( dept_id number(10) NOT NULL,
dept_name varchar2(50) NOT NULL)  tablespace USERS;  2    3

Table created.

SQL>

BEGIN  
FOR loop_counter IN 1..1000000 LOOP 
INSERT INTO sys.testtable (dept_id, dept_name) 
VALUES (loop_counter, 'Depart Name'); 
END LOOP; 
COMMIT; 
END;
/


SQL> select count(*) from sys.testtable;

  COUNT(*)
----------
   2201000

SQL> select * from sys.testtable;
   DEPT_ID DEPT_NAME
---------- --------------------------------------------------
....
    971316 Depart Name
    971317 Depart Name
    971318 Depart Name
    971319 Depart Name
    971320 Depart Name
    971321 Depart Name
    971322 Depart Name
    971323 Depart Name
    971324 Depart Name
    971325 Depart Name

2201000 rows selected.

SQL>

4:- Check asm status before the drop:

SQL> select name,total_mb,free_mb,total_mb-free_mb used_mb, (free_mb/total_mb)*100 as "% Free space" from V$ASM_DISKGROUP;

NAME		       TOTAL_MB    FREE_MB    USED_MB % Free space
-------------------- ---------- ---------- ---------- ------------
DATA			 102400      89668	12732	87.5664063
FRA			  30720      28946	 1774	94.2252604

SQL>

SQL> select group_number, disk_number, mode_status, header_status, state, name, path from v$asm_disk;

GROUP_NUMBER DISK_NUMBER MODE_ST HEADER_STATU STATE    NAME		    PATH
------------ ----------- ------- ------------ -------- -------------------- --------------------
	   1	       0 ONLINE  MEMBER       NORMAL   DATA		    AFD:DATA
	   2	       0 ONLINE  MEMBER       NORMAL   FRA		    AFD:FRA
	   1	       1 ONLINE  MEMBER       NORMAL   DATA2		    AFD:DATA2

SQL>

5:- Drop disk and monitor rebalance:

SQL> alter diskgroup DATA drop disk 'DATA2';
Diskgroup altered.
SQL>

SQL> select * from v$asm_operation;

GROUP_NUMBER OPERA PASS      STAT  POWER  ACTUAL  SOFAR   EST_WORK	EST_RATE EST_MINUTES ERROR_CODE  CON_ID
------------ ----- --------- ---- ------ -------- ------ ---------- ---------- ----------- ---------- -------
	   1 	 REBAL COMPACT   WAIT	   1	    1 	 0	        0	       0	       0				  0
	   1 	 REBAL REBALANCE RUN	   1	    1    906	   1587	   31541	       0				  0
	   1 	 REBAL REBUILD   DONE	   1	    1 	 0	       0	       0	       0				  0	  0
SQL> /
no rows selected
SQL>

6:- Check asm status post drop:

SQL> select name,total_mb,free_mb,total_mb-free_mb used_mb, (free_mb/total_mb)*100 as "% Free space" from V$ASM_DISKGROUP;

NAME		       TOTAL_MB    FREE_MB    USED_MB % Free space
-------------------- ---------- ---------- ---------- ------------
DATA			  51200      38480	12720	  75.15625  <<-- about the same usage
FRA			  30720      28946	 1774	94.2252604

SQL>

7:- Validate if you can still access DB data without errors/corruption:

SQL> select * from sys.testtable;
   DEPT_ID DEPT_NAME
---------- --------------------------------------------------
....
    971316 Depart Name
    971317 Depart Name
    971318 Depart Name
    971319 Depart Name
    971320 Depart Name
    971321 Depart Name
    971322 Depart Name
    971323 Depart Name
    971324 Depart Name
    971325 Depart Name

2201000 rows selected.

SQL>

That’s it!

Last modified: 14 March 2025

Author

Comments

Write a Reply or Comment

Your email address will not be published.