今回は GEOM によるディスクのミラーリング (RAID1) について纏めてみたいと思います.
ミラーリングは複数のディスクに対して同じデータを格納し、ディスク障害が発生してもデータの損失を防ぐ技術です.コンカチやストライピングと違いディスク容量は増えません.
- GEOM に関するお話
- FreeBSD GEOM 再々学習
- GEOM CONCAT (ディスクの連結) を使ってみる
- GEOM STRIPE (ストライプ/RAID0) を使ってみる
- GEOM MIRROR (ミラーリング/RAID1) を使ってみる (1)
- GEOM MIRROR (ミラーリング/RAID1) を使ってみる (2)
- GEOM STRIPE + MIRROR で RAID10 を構成してみる
- GEOM RAID3を使ってみる
- GEOM CACHE を使ってみる
- GEOM GVIRSTORを使ってみる
- GEOM GATE を使ってみる
- GEOM LABEL で名前による管理を行う
- GEOM PART でディスクパーティションの管理を行う
- GEOM MULTIPATH でマルチパスを構成する (1)
- GEOM MULTIPATH でマルチパスを構成する (2)
GEOM MIRROR のイメージ
ミラーリングのイメージはこのような形です.ディスクが2本の場合,3本の場合を表しています.
GEOM MIRROR の利用・管理
GEOM MIRROR は gmirror というコマンドを通じて利用・管理を行います.簡単に触れますが,詳細はコマンドのオプションの詳細は FreeBSD の マニュアル「gmirror」を見てください.
# gmirror usage: gmirror activate [-v] name prov ... gmirror clear [-v] prov ... gmirror configure [-adfFhnv] [-b balance] [-s slice] name gmirror configure [-v] -p priority name prov gmirror create [-Fnv] [-b balance] [-s slice] name prov ... gmirror deactivate [-v] name prov ... gmirror destroy [-fv] name ... gmirror dump prov ... gmirror forget name ... gmirror label [-Fhnv] [-b balance] [-s slice] name prov ... gmirror insert [-hiv] [-p priority] name prov ... gmirror rebuild [-v] name prov ... gmirror remove [-v] name prov ... gmirror resize [-s size] [-v] name gmirror stop [-fv] name ... gmirror help gmirror list [-a] [name ...] gmirror status [-ags] [name ...] gmirror load [-v] gmirror unload [-v]
GEOM 関連のコマンドは gconcat の際にも触れましたが create と label の両方があり分かりづらいのですが,create は一時的,label は恒久的と覚えるのがよいです.
create で作った場合はどうなるのか?
create で作成してマウント,再起動を行うとどのようになるのかを以下に一連の流れを記載します.
gmirror create コマンドで ディスク da1 と da2 をミラーリングして mirror0 を作成します.
# kldload geom_mirror # gmirror create mirror0 da1 da2
gconcat や gstripe の場合はコマンド実行時に自動でカーネルモジュールがロードされるのですが,gmirror は「gmirror: Class not found: “MIRROR”」というエラーが出力されてしまいます.
ですのでコマンド実行前に明示的にモジュールをロードさせてから gmirror コマンドを実行しています.
# kldstat Id Refs Address Size Name 1 10 0xffffffff80200000 1f3e2d0 kernel 2 1 0xffffffff82319000 3218 intpm.ko 3 1 0xffffffff8231d000 2180 smbus.ko 4 1 0xffffffff82320000 7490 vmci.ko 5 1 0xffffffff82328000 fef0 geom_mirror.ko
また,再起動時に必ず有効になるように明示的にロードさせる必要があります.
# cat /boot/loader.conf geom_mirror_load="YES"
gmirror status コマンドでステータスを表示できます.
以下は mirror0 のステータスです.da1, da2 がコンポーネントとして含まれており,ステータスが COMPLETE の状態です.
COMPLETE の状態とは,このミラーリングで指定しているディスクの同期が取れている状態となります.
# gmirror status Name Status Components mirror/mirror0 COMPLETE da1 (ACTIVE) da2 (ACTIVE)
gmirror list コマンドで詳細を表示する事ができます.
da1, da2 が 100GB のディスクでこれを RAID1 でミラーリングしている為,mirror0 は 100G となっています.
# gmirror list Geom name: mirror0 State: COMPLETE Components: 2 Balance: load Slice: 4096 Flags: NONE GenID: 0 SyncID: 1 ID: 2029918663 Type: MANUAL Providers: 1. Name: mirror/mirror0 Mediasize: 107374182400 (100G) Sectorsize: 512 Mode: r0w0e0 Consumers: 1. Name: da1 Mediasize: 107374182400 (100G) Sectorsize: 512 Mode: r1w1e1 State: ACTIVE Priority: 0 Flags: NONE GenID: 0 SyncID: 1 ID: 3804043814 2. Name: da2 Mediasize: 107374182400 (100G) Sectorsize: 512 Mode: r1w1e1 State: ACTIVE Priority: 1 Flags: NONE GenID: 0 SyncID: 1 ID: 3614838224
newfs でファイルシステムを作成します.指定するデバイスは GEOM MIRROR の場合は /dev/mirror 以下に指定した名前のデバイスファイルが作成されますので,これを指定します.
今回は create の際に mirror0 を名前としたため,/dev/mirror/mirror0 がデバイスファイルとなります.
# newfs /dev/mirror/mirror0 /dev/mirror/mirror0: 102400.0MB (209715200 sectors) block size 32768, fragment size 4096 using 164 cylinder groups of 625.22MB, 20007 blks, 80128 inodes. super-block backups (for fsck_ffs -b #) at: 192, 1280640, 2561088, 3841536, 5121984, 6402432, 7682880, 8963328, 10243776, 11524224, 12804672, 14085120, 15365568, 16646016, 17926464, 19206912, 20487360, 21767808, 23048256, 24328704, 25609152, 26889600, 28170048, 29450496, 30730944, 32011392, 33291840, 34572288, 35852736, 37133184, 38413632, 39694080, 40974528, 42254976, 43535424, 44815872, 46096320, ....
マウントおよびマウントの結果です./mnt にマウントをしています.
これを /etc/fstab に記載した状態で再起動を行ってみます.
# mount /dev/mirror/mirror0 /mnt # df Filesystem 1K-blocks Used Avail Capacity Mounted on /dev/da0p2 19279260 2590868 15146052 15% / devfs 1 1 0 100% /dev /dev/mirror/mirror0 101561756 8 93436808 0% /mnt # cat /etc/fstab # Device Mountpoint FStype Options Dump Pass# /dev/da0p2 / ufs rw 1 1 /dev/da0p3 none swap sw 0 0 /dev/mirror/mirror0 /mnt ufs rw 1 1
残念な事に (想定どおりです),デバイスが無く起動途中に失敗してしまっています.
これは create で作成した為,ディスクに GEOM MIRROR の情報が記録されてい為作成したデバイスが存在しておらず,この状態となります.
恒久的に使う場合は label を利用しよう
先ほどと変わって create ではなく label で mirror0 を作成しました.
# gmirror label mirror0 da1 da2
同じディスクを同じように指定している為,status および list の結果は先ほどと変わりません.
また,create で作成した際に newfs していますが,再作成の際にディスク連結順番に変更を入れていませんのでファイルシステムとしては正しく生成された状態となっていますのでこのままマウントさせる事も可能です.
# gmirror status mirror0 Name Status Components mirror/mirror0 COMPLETE da1 (ACTIVE) da2 (ACTIVE) # gmirror status mirror0 Name Status Components mirror/mirror0 COMPLETE da1 (ACTIVE) da2 (ACTIVE) root@bsd13:~ # gmirror list mirror0 Geom name: mirror0 State: COMPLETE Components: 2 Balance: load Slice: 4096 Flags: NONE GenID: 0 SyncID: 1 ID: 4078222260 Type: AUTOMATIC Providers: 1. Name: mirror/mirror0 Mediasize: 107374181888 (100G) Sectorsize: 512 Mode: r0w0e0 Consumers: 1. Name: da1 Mediasize: 107374182400 (100G) Sectorsize: 512 Mode: r1w1e1 State: ACTIVE Priority: 0 Flags: NONE GenID: 0 SyncID: 1 ID: 3192641748 2. Name: da2 Mediasize: 107374182400 (100G) Sectorsize: 512 Mode: r1w1e1 State: ACTIVE Priority: 1 Flags: NONE GenID: 0 SyncID: 1 ID: 159192916
ですので,create と label を間違った… という場合でも正しくコマンドを発行してあげる事で今までの状態を復元できますので,データがなくなってしまった.という事は起きませんので安心してください.
いずれにせよ… label で作成しましょう.が教訓となりますが…
# mount /dev/mirror/mirror0 /mnt # df Filesystem 1K-blocks Used Avail Capacity Mounted on /dev/da0p2 19279260 2590884 15146036 15% / devfs 1 1 0 100% /dev /dev/mirror/mirror0 101561756 8 93436808 0% /mnt
IOについて確認してみる
ミラーリングですので,ミラーしているディスク全てに同じデータが書き込まれます.実際にどの様な IO が発生しているのかを確認してみます.
dd でランダムデータを生成,random.img としてファイル書き込みの IO を発生させました.
見て頂くと分かる通り da1 と da2 の両方に IO がかかっています.
このことから,分散してのディスクの読み書きが行われる事が分かります.
# dd if=/dev/random of=/mnt/random.img # iostat 2 tty da0 da1 da2 cpu tin tout KB/t tps MB/s KB/t tps MB/s KB/t tps MB/s us ni sy in id 0 4 17.7 0 0.0 223 0 0.0 230 0 0.0 0 0 0 0 100 0 231 32.0 0 0.0 256 45 11.2 256 53 13.2 1 0 4 0 96 0 159 0.0 0 0.0 256 34 8.6 256 39 9.8 0 0 4 0 96 0 81 0.0 0 0.0 255 156 38.8 254 142 35.3 1 0 16 0 83 0 79 0.0 0 0.0 256 116 29.1 256 114 28.6 1 0 11 0 88 # ls /mnt .snap random.img
イメージとしてはこのような形ですね.
GEOM RAID MIRROR デバイスを管理する
ミラーデバイスを追加する
ミラー先を追加,取り外しを行う事でのバックアップ運用が可能です.2つ以上のディスクをローテーションして管理する事で複数世代のバックアップも可能です.
もちろん,オペミスだったり,取り外したディスクの管理 (静電袋に入れてエアキャップ保存とか) は重要になります.
ミラーの追加は insert サブコマンドを使用して行う事が可能です.
追加後のステータスを確認すると DEGRADED 状態となり,追加したデバイスが SYNCHRONIZING として同期中である事を確認できます.
# gmirror insert mirror0 da3 # gmirror status mirror0 Name Status Components mirror/mirror0 DEGRADED da1 (ACTIVE) da2 (ACTIVE) da3 (SYNCHRONIZING, 3%)
ミラーデバイスを取り外す
同期が完了したら取り外す事が可能です.
取り外しは remove サブコマンドを使用して行う事が可能です.
まずはステータスが COMPLETE である事を確認します.
その次に remove でディスクをミラーから切り離します.その後,切り離しが完了した事を確認します.
この場合は da3 を切り離しを行っており,status で表示されない状態になっていればディスク本体の取り外しが可能な状態となります.
# gmirror status mirror0 Name Status Components mirror/mirror0 COMPLETE da1 (ACTIVE) da2 (ACTIVE) da3 (ACTIVE) # gmirror remove mirror0 da3 # gmirror status mirror0 Name Status Components mirror/mirror0 COMPLETE da1 (ACTIVE) da2 (ACTIVE)
ディスクを拡張する
ディスク というか,ファイルシステムを拡張する事が可能です.
今回説明するシチュエーションとしては,da1, da2 を玉突きで大きいディスクに置き換えていく.というシチュエーションを想定して説明します.
このようなイメージで da1 を取り外し,大きなディスクに交換の上ミラーに組み込み.
da2 を取り外し,大きなディスクに交換の上ミラーに組み込み.という流れとなります.
まずは remove でディスクを取り外します.
# gmirror status Name Status Components mirror/mirror0 COMPLETE da1 (ACTIVE) da2 (ACTIVE) # gmirror remove mirror0 da1 # gmirror status Name Status Components mirror/mirror0 COMPLETE da2 (ACTIVE)
次に容量の大きいディスクと交換し insert サブコマンドを実行して mirror0 に組み込みます.
status サブコマンドで確認するとリビルド処理が走っている事が確認できます.
また,list サブコマンドで確認すると da1 が 150GB である事が確認できます.
# gmirror insert mirror0 da1 # gmirror status Name Status Components mirror/mirror0 DEGRADED da2 (ACTIVE) da1 (SYNCHRONIZING, 0%) # gmirror list Geom name: mirror0 State: DEGRADED Components: 2 Balance: load Slice: 4096 Flags: NONE GenID: 0 SyncID: 1 ID: 3318650467 Type: AUTOMATIC Providers: 1. Name: mirror/mirror0 Mediasize: 107374181888 (100G) Sectorsize: 512 Mode: r2w1e1 Consumers: 1. Name: da2 Mediasize: 107374182400 (100G) Sectorsize: 512 Mode: r1w1e1 State: ACTIVE Priority: 1 Flags: NONE GenID: 0 SyncID: 1 ID: 3061855275 2. Name: da1 Mediasize: 161061273600 (150G) Sectorsize: 512 Mode: r1w1e1 State: SYNCHRONIZING Priority: 0 Flags: DIRTY, SYNCHRONIZING GenID: 0 SyncID: 1 BytesSynced: 1282408448 Synchronized: 1% ID: 1348065949
status サブコマンドで COMPLETE である事を確認し,remove サブコマンドで da2 の切り離しを行います.
その後容量の大きいディスクに入れ替えて insert サブコマンドで mirror0 に組み込みます.
status サブコマンドでリビルド処理が行われている事を確認します.
# gmirror status Name Status Components mirror/mirror0 COMPLETE da2 (ACTIVE) da1 (ACTIVE) # gmirror remove mirror0 da2 # gmirror status Name Status Components mirror/mirror0 COMPLETE da1 (ACTIVE) # gmirror insert mirror0 da2 # gmirror status mirror0 Name Status Components mirror/mirror0 DEGRADED da1 (ACTIVE) da2 (SYNCHRONIZING, 0%)
この際,list サブコマンドで確認すると,da1,da2 の両方が 150GB ですが,mirror0 は 100GB のままとなっています.
この点についてはリビルドが完了したら拡張を行う流れになります.
# gmirror list mirror0 Geom name: mirror0 State: DEGRADED Components: 2 Balance: load Slice: 4096 Flags: NONE GenID: 0 SyncID: 1 ID: 3318650467 Type: AUTOMATIC Providers: 1. Name: mirror/mirror0 Mediasize: 107374181888 (100G) Sectorsize: 512 Mode: r2w1e1 Consumers: 1. Name: da1 Mediasize: 161061273600 (150G) Sectorsize: 512 Mode: r1w1e1 State: ACTIVE Priority: 0 Flags: NONE GenID: 0 SyncID: 1 ID: 1348065949 2. Name: da2 Mediasize: 161061273600 (150G) Sectorsize: 512 Mode: r1w1e1 State: SYNCHRONIZING Priority: 0 Flags: DIRTY, SYNCHRONIZING GenID: 0 SyncID: 1 BytesSynced: 9633267712 Synchronized: 8% ID: 2184573350
リビルドが完了したら,resize サブコマンドを実行して mirror0 の拡張を行います.
その後 list サブコマンドで mirror0 の容量が増えている事を確認します.
# gmirror status mirror0 Name Status Components mirror/mirror0 COMPLETE da1 (ACTIVE) da2 (ACTIVE) # gmirror resize mirror0 # gmirror list Geom name: mirror0 State: COMPLETE Components: 2 Balance: load Slice: 4096 Flags: NONE GenID: 0 SyncID: 1 ID: 3318650467 Type: AUTOMATIC Providers: 1. Name: mirror/mirror0 Mediasize: 161061273088 (150G) Sectorsize: 512 Mode: r1w1e1 Consumers: 1. Name: da1 Mediasize: 161061273600 (150G) Sectorsize: 512 Mode: r1w1e1 State: ACTIVE Priority: 0 Flags: NONE GenID: 0 SyncID: 1 ID: 1348065949 2. Name: da2 Mediasize: 161061273600 (150G) Sectorsize: 512 Mode: r1w1e1 State: ACTIVE Priority: 0 Flags: NONE GenID: 0 SyncID: 1 ID: 2184573350
ただし,まだこの時点ではファイルシステムは現状のままですので growfs でファイルシステムを拡張する必要があります.
growfs はオンライン (マウントした状態) で実施可能です.growfs 実施前後の df の結果を見ると正しく拡張されている事が確認できます.
# df Filesystem 1K-blocks Used Avail Capacity Mounted on /dev/da0p2 19279260 2590916 15146004 15% / devfs 1 1 0 100% /dev /dev/mirror/mirror0 101561752 89608 93347204 0% /mnt # growfs /dev/mirror/mirror0 Device is mounted read-write; resizing will result in temporary write suspension for /mnt. It's strongly recommended to make a backup before growing the file system. OK to grow filesystem on /dev/mirror/mirror0, mounted on /mnt, from 100GB to 150GB? [yes/no] yes super-block backups (for fsck_ffs -b #) at: 209993664, 211274112, 212554560, 213835008, 215115456, 216395904, 217676352, 218956800, 220237248, 221517696, 222798144, 224078592, 225359040, 226639488, 227919936, 229200384, 230480832, 231761280, 233041728, 234322176, 235602624, 236883072, 238163520, 239443968, 240724416, 242004864, 243285312, 244565760, 245846208, 247126656, 248407104, 249687552, 250968000, 252248448, 253528896, 254809344, 256089792, 257370240, 258650688, 259931136, 261211584, 262492032, 263772480, 265052928, ... # df Filesystem 1K-blocks Used Avail Capacity Mounted on /dev/da0p2 19279260 2590916 15146004 15% / devfs 1 1 0 100% /dev /dev/mirror/mirror0 152342680 89608 140065660 0% /mnt
GEOM MIRROR デバイスを終了 (破壊) する
ファイルシステムとして用済みになった.であったり,別用途に転用する為に初期化したい場合を説明します.
当然ながら,ファイルシステムはアンマウントする必要があります.
また,完全に終了 (停止・破壊) する場合は stop ではなく destroy を利用します.
# umount /mnt # gmirror destroy mirror0 # gmirror list
もし間違って destory を実行してしまった場合ですが,これだけのオペレーションの場合だと label 情報がなくなっただけなので,再度 label を同じ引数で渡すことで復活させる事が可能です.
やらかしてしまった… という事案の場合は慌てずにそっと元に戻しましょう.
# gmirror label mirror0 da1 da2 # mount /dev/mirror/mirror0 /mnt # df Filesystem 1K-blocks Used Avail Capacity Mounted on /dev/da0p2 19279260 2590920 15146000 15% / devfs 1 1 0 100% /dev /dev/mirror/mirror0 152342680 89608 140065660 0% /mnt # ls /mnt .snap random.img
以上で~ と終わりたい所ではあるのですが,拡張については他の手法もありますので次回はそれについて触れていきたいと思います.
コメント