ASMディスクグループの空き領域の考え方について

標準冗長性や高冗長性の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 は、全ての障害グループでディスクが一つずつ壊れても、残ったディスクの中で冗長性を回復させるために必要な容量が計算されている(と思われる)。したがって、高冗長性の場合はディスク三台分の容量が表示されている(と思われる)。これについてはマニュアルの書かれ方が非常に難解でちょっと何言っているかわからない状態なので、実際にそうなっているという事実からの判断である。

類似のケースとして、一つの障害グループに5GBのディスクを三台ずつ設定した標準冗長性のディスクグループで見てみると、REQUIRED_MIRROR_FREE_MB はディスク二台分の容量 = 10GB になることがわかる。

create diskgroup NRMLDG normal redundancy
    failgroup FG1 disk 'AFD:NEW1', 'AFD:NEW2', 'AFD:NEW3'
    failgroup FG2 disk 'AFD:NEW4', '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 = '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       5088           0           32
NRMLDG NEW2                 1 ONLINE     FG1         5120       5090           0           30
NRMLDG NEW3                 2 ONLINE     FG1         5120       5089           0           31
NRMLDG NEW4                 3 ONLINE     FG2         5120       5089           0           31
NRMLDG NEW5                 4 ONLINE     FG2         5120       5091           0           29
NRMLDG NEW6                 5 ONLINE     FG2         5120       5087           0           33

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          30720      30534           0          186                   10240          10147             0

そして、この時のディスクグループの空きは以下のように計算できる。

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が発生し失敗する。もう一度ディスクを追加すればこの状態は解消できる。

コメント