標準冗長性や高冗長性のASMディスクグループは、空き領域の考え方がややこしいので自分なりにまとめてみた。
一つの障害グループにディスクが一台だけ存在する場合
5GBのディスク二台を使って標準冗長性のディスクグループを作ることを考える。
create diskgroup NRMLDG normal redundancy
failgroup FG1 disk 'AFD:NEW1'
failgroup FG2 disk 'AFD:NEW2'
attribute
'COMPATIBLE.ASM'='19.0.0.0.0','COMPATIBLE.RDBMS'='19.0.0.0.0';
select b.name,label,disk_number,mode_status,failgroup,os_mb,a.free_mb,a.hot_used_mb,a.cold_used_mb
from v$asm_disk a left join v$asm_diskgroup b
on a.group_number = b.group_number where b.name = 'NRMLDG' order by disk_number;
NAME LABEL DISK_NUMBER MODE_STATU FAILG OS_MB FREE_MB HOT_USED_MB COLD_USED_MB
------ ---------- ----------- ---------- ----- ---------- ---------- ----------- ------------
NRMLDG NEW1 0 ONLINE FG1 5120 5041 0 79
NRMLDG NEW2 1 ONLINE FG2 5120 5041 0 79
select name,type,total_mb,free_mb,hot_used_mb,cold_used_mb,required_mirror_free_mb,usable_file_mb,offline_disks
from v$asm_diskgroup where name='NRMLDG';
NAME TYPE TOTAL_MB FREE_MB HOT_USED_MB COLD_USED_MB REQUIRED_MIRROR_FREE_MB USABLE_FILE_MB OFFLINE_DISKS
------ ---------- ---------- ---------- ----------- ------------ ----------------------- -------------- -------------
NRMLDG NORMAL 10240 10082 0 158 0 5041 0
この時のディスクグループの空きは以下のように計算できる。
TOTAL_MB = 5GB * 2 = 10GB
FREE_MB = TOTAL_MB – HOT_USED_MB – COLD_USED_MB = 10082 MB
USABLE_FILE_MB = FREE_MB / 冗長度 = 5041 MB
計算式は感覚的にもわかりやすく、 FREE_MB を冗長度で割った値が、ミラーリングを考慮したときの空き領域としてそのまま USABLE_FILE_MB に出てくる。実際、USABLE_FILE_MB を超える領域は使えない。
一つの障害グループに複数のディスクが存在する場合
障害グループごとにディスクが一台しかない場合はそれ自体が障害グループの全損につながるが、複数台で構成されている場合はそうとは限らない。
ASMは、障害グループを構成するディスクのうち一つが故障した際に、残っているディスクの中で冗長性を回復させようとする。
例えばある障害グループが二台のディスクで構成されている場合、破損したディスクに入っていたデータは、同じ障害グループの残ったディスクにコピーされ、残ったディスクの中で冗長性が回復する。v$asm_diskgroup の REQUIRED_MIRROR_FREE_MB が表しているのはこのためのディスク容量である。
5GBのディスク六台で構成される高冗長性のディスクグループを作ることを考える。
create diskgroup HIGHDG high redundancy
failgroup FG1 disk 'AFD:NEW1', 'AFD:NEW2'
failgroup FG2 disk 'AFD:NEW3', 'AFD:NEW4'
failgroup FG3 disk 'AFD:NEW5', 'AFD:NEW6'
attribute
'COMPATIBLE.ASM'='19.0.0.0.0','COMPATIBLE.RDBMS'='19.0.0.0.0';
select b.name,label,disk_number,mode_status,failgroup,os_mb,a.free_mb,a.hot_used_mb,a.cold_used_mb
from v$asm_disk a left join v$asm_diskgroup b
on a.group_number = b.group_number where b.name = 'HIGHDG' order by disk_number;
NAME LABEL DISK_NUMBER MODE_STATU FAILG OS_MB FREE_MB HOT_USED_MB COLD_USED_MB
------ ---------- ----------- ---------- ----- ---------- ---------- ----------- ------------
HIGHDG NEW1 0 ONLINE FG1 5120 5077 0 43
HIGHDG NEW2 1 ONLINE FG1 5120 5073 0 47
HIGHDG NEW3 2 ONLINE FG2 5120 5075 0 45
HIGHDG NEW4 3 ONLINE FG2 5120 5075 0 45
HIGHDG NEW5 4 ONLINE FG3 5120 5076 0 44
HIGHDG NEW6 5 ONLINE FG3 5120 5074 0 46
select name,type,total_mb,free_mb,hot_used_mb,cold_used_mb,required_mirror_free_mb,usable_file_mb,offline_disks
from v$asm_diskgroup where name='HIGHDG';
NAME TYPE TOTAL_MB FREE_MB HOT_USED_MB COLD_USED_MB REQUIRED_MIRROR_FREE_MB USABLE_FILE_MB OFFLINE_DISKS
------ ---------- ---------- ---------- ----------- ------------ ----------------------- -------------- -------------
HIGHDG HIGH 30720 30450 0 270 15360 5030 0
TOTAL_MB = 5GB * 6 = 30GB
REQUIRED_MIRROR_FREE_MB = 5GB * 3 = 15GB
REQUIRED_MIRROR_FREE_MB は、全ての障害グループでディスクが一つずつ壊れても、残ったディスクの中で冗長性を回復させるために必要な容量が計算されている(と思われる)。したがって、高冗長性の場合はディスク三台分の容量が表示されている(と思われる)。これについてはマニュアルの書かれ方が非常に難解でちょっと何言っているかわからない状態なので、実際にそうなっているという事実からの判断である。
そして、この時のディスクグループの空きは以下のように計算できる。
FREE_MB = TOTAL_MB – HOT_USED_MB – COLD_USED_MB = 30450 MB
USABLE_FILE_MB = (FREE_MB – REQUIRED_MIRROR_FREE_MB) / 冗長度 = 5030 MB
見ての通り、USABLE_FILE_MB は REQUIRED_MIRROR_FREE_MB を差し引いた上でさらに冗長度で割られるため、相当少なく見える。
では、この状態で 6GBの表領域をディスクグループ上に作成するとどうなるか、というと実は作成自体はできてしまう。
SQL> create tablespace testtbs datafile '+HIGHDG' size 6G;
表領域が作成されました。
一つの障害グループあたり物理的には10GBあるため、REQUIRED_MIRROR_FREE_MB を考慮しなければデータが入り切るからである。しかし、USABLE_FILE_MB はマイナスになってしまう。
select b.name,label,disk_number,mode_status,failgroup,os_mb,a.free_mb,a.hot_used_mb,a.cold_used_mb
from v$asm_disk a left join v$asm_diskgroup b
on a.group_number = b.group_number where b.name = 'HIGHDG' order by disk_number;
NAME LABEL DISK_NUMBER MODE_STATU FAILG OS_MB FREE_MB HOT_USED_MB COLD_USED_MB
------ ---------- ----------- ---------- ----- ---------- ---------- ----------- ------------
HIGHDG NEW1 0 ONLINE FG1 5120 2002 0 3118
HIGHDG NEW2 1 ONLINE FG1 5120 2001 0 3119
HIGHDG NEW3 2 ONLINE FG2 5120 2002 0 3118
HIGHDG NEW4 3 ONLINE FG2 5120 2001 0 3119
HIGHDG NEW5 4 ONLINE FG3 5120 2002 0 3118
HIGHDG NEW6 5 ONLINE FG3 5120 2001 0 3119
select name,type,total_mb,free_mb,hot_used_mb,cold_used_mb,required_mirror_free_mb,usable_file_mb,offline_disks
from v$asm_diskgroup where name='HIGHDG';
NAME TYPE TOTAL_MB FREE_MB HOT_USED_MB COLD_USED_MB REQUIRED_MIRROR_FREE_MB USABLE_FILE_MB OFFLINE_DISKS
------ ---------- ---------- ---------- ----------- ------------ ----------------------- -------------- -------------
HIGHDG HIGH 30720 12009 0 18711 15360 -1117 0
この状態から、障害グループ FG1 の NEW1 というディスクが一台故障するとどうなるか。NEW1 の COLD_USED_MB である 3118 MBは、同じ障害グループ FG1 の NEW2 というディスクには入りきらないため、障害グループ内での冗長性の回復は物理的に不可能。ディスクを強制的に drop した際のリバランスの状態を見るとそれがわかる。
SQL> alter diskgroup highdg drop disk NEW1 force;
Diskgroup altered.
SQL> select group_number, operation, pass, state, error_code from v$asm_operation;
GROUP_NUMBER OPERATION PASS STATE ERROR_CODE
------------ --------------- --------------------------- ------------ ------------------------------
5 REBAL COMPACT WAIT
5 REBAL REBALANCE ERRS ORA-15041
5 REBAL REBUILD WAIT
5 REBAL RESYNC WAIT
障害グループ内で冗長性を回復するためのリバランスは途中まで走る。が、ORA-15041が発生し失敗する。もう一度ディスクを追加すればこの状態は解消できる。
コメント