LVMボリュームグループからディスクを外す方法
LVMのディスクを先に切り離すとファイルシステムを失います。pvmoveでデータを移動し、vgreduce、pvremoveの順に実行して安全に取り外す方法を解説します。
LVM ボリュームグループからディスクを取り外す意味
LVM ボリュームグループからディスクを取り外すには、そのデータを別のデバイスへ移動し、空になったデバイスをグループから外し、LVM のラベルを消去してから、サーバーから切り離します。LVM(論理ボリュームマネージャー)は、グループ内の各ディスクから取得した小さなチャンク単位でストレージを割り当てます。そのため、「1 つのボリューム」と考えているファイルシステムの一部が、取り外そうとしているディスク上に存在することがあります。デフォルトでは、LVM はそのデータのコピーを別に保持しません。先にディスクを切り離すと、直前まで正常に動作していたファイルシステムを失うことになります。
ファイルシステムを維持したままディスクだけを取り外す場合、作業全体をオンラインで実行できます。pvmove は、ファイルシステムをマウントしてネットワークトラフィックを処理している状態でデータをコピーします。再起動もレスキューモードも必要ありません。危険なのは技術そのものではありません。重要なのは作業順序と、ここで使用するすべてのコマンドがデバイスパスを受け取り、確認を2回求めないことです。
物理ボリューム、ボリュームグループ、論理ボリュームの実体
これらは 1 つのスタックを構成する 3 つの層です。ディスクを「そのまま切り離せる」かどうかは、ディスクがどの層を担っているかで決まります。
- 物理ボリューム (PV)。 ディスクまたはパーティションの先頭に LVM ラベルを書き込んだものです。
pvcreateがこのラベルを書き込みます。その後ろの領域は、物理エクステントに分割されます。物理エクステントは固定サイズの単位で、デフォルトでは 4 MiB です。 - ボリュームグループ (VG)。 1 つ以上の PV から構成されるプールです。VG はすべてのエクステントをまとめて管理し、個々のエクステントがどのディスクに由来するかは認識しません。
- 論理ボリューム (LV)。 プールから割り当てられた領域です。ファイルシステムが配置されるブロックデバイスであり、
/dev/<vg>/<lv>または/dev/mapper/<vg>-<lv>として表示されます。 - 層の間のマッピングが問題の本質です。 1 つの LV のエクステントは、グループ内の任意の PV に配置できます。LVM は 1 つの LV を複数のディスクに分散できます。プールとは、そのための仕組みだからです。
最初に、取り外すディスクが何を保持しているかを確認します。状況は 4 つあり、それぞれ必要な作業が異なります。
- ディスクに LVM ラベルはあるものの、ボリュームグループには追加されていない。ディスクを参照するものはありません。
pvremoveを実行してから、切り離します。 - ディスクはボリュームグループのメンバーですが、割り当て済みのエクステントはありません。
vgreduceを実行し、続いてpvremoveを実行してから、切り離します。 - ディスクに、保持する論理ボリュームのエクステントがあります。まず別の PV にエクステントを移動する必要があります。そのために
pvmoveを使います。 - 論理ボリュームもディスクと一緒に削除する。まずアンマウントし、
lvremoveの前に/etc/fstabの行を削除します。そうしないと、次回のブート時に緊急プロンプトで停止します。
通常の LVM は、明示的にミラーまたは RAID 論理ボリュームを構成しない限り、何もミラーリングしません。そのため、ディスクをすでに切り離した状態での状況 3 は、ディスクの取り外し手順ではありません。バックアップからの復元が必要です。まだ変更を計画している段階であれば、この作業の逆にあたる ブロックストレージボリュームを接続してボリュームグループに追加する 手順を先に読み直してください。ディスクを追加した方法によって、取り外しに必要な作業量が決まるためです。
実行前にデバイスを特定する
まず、マシン上のデバイスを一覧表示し、そのうちどれを物理ボリュームとして認識しているかを LVM に確認させます。
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS
sudo pvs次に、パスをシェル変数へ一度だけ設定します。ほかの操作を実行する前に、引用符で囲まれたテキストを、上の一覧にある実際のパスへ置き換えてください。
VG="the volume group name from pvs"
OLD="the path of the disk that is leaving"
NEW="the path of the replacement disk"破壊的な操作を実行する前に、これらの変数を表示し、lsblk の一覧と照合して声に出して読み上げます。同じプロバイダーから提供された同じサイズのボリュームが 2 つある場合、それらを取り違えると深刻な結果になります。パスがどの物理デバイスを指しているか少しでも不確かな場合は、カーネルがデバイスを検出した順序を信頼せず、対象デバイスのモデルとシリアル番号を照合してください。
ほとんどの LVM コマンドはグローバルな dry run フラグ --test を受け付けます。このフラグを使うと、変更内容を計算して報告しますが、メタデータは書き込みません。実際に実行する前に、各破壊的操作をこのフラグ付きで試行してください。man pvmove、man vgreduce、man lvremove で、このフラグを自分のシステム上で確認してください。オプション一覧は lvm2 のリリースによって変わるためです。
ボリュームグループの定義もバックアップします。sudo vgcfgbackup は現在のレイアウトを /etc/lvm/backup/ に書き込み、vgcfgrestore で破損した定義を復元できます。復元されるのはメタデータだけです。そのため、ディスクが失われた場合にデータを復旧することはできません。
手順 1: この PV にエクステントが残っているか確認する
この確認結果が後続のすべてを決めます。数か月前に行った作業の記憶ではなく、ディスク自体に確認してください。
sudo pvs -o pv_name,vg_name,pv_size,pv_free,pv_used
sudo pvdisplay "$OLD"次の 2 点を確認します。まず、$OLD のパスにボリュームグループ名が表示されるかを確認します。グループ列が空なら、そのデバイスはどのグループにも割り当てられていない PV です。これは状況 1 に該当します。次に、どの程度使用されているかを確認します。空き容量が合計サイズと同じなら、このデバイスから何も割り当てられていません。その場合は手順 4 に進めます。何らかの領域が割り当てられている場合、このデバイス上に論理ボリュームのエクステントがあります。これらを移動する必要があります。pvdisplay では、同じ内容を PE (physical extent) 単位で確認できます。割り当て済みの数と空きの数が表示されます。
次に、関係する論理ボリュームと、グループの残りの領域でデータを収容できるかを確認します。
sudo lvs -a -o lv_name,vg_name,lv_size,seg_pe_ranges
sudo vgs -o vg_name,pv_count,vg_size,vg_freelvs の出力では、各 LV の各領域がどの PV 上にあるかがセグメント範囲に示されます。$OLD のパスを探し、その横にあるすべての LV 名を記録します。これらが、マウントされたままバックグラウンドで再配置されるボリュームです。vgs の出力では、グループの空き容量と $OLD に割り当てられている容量を比較します。グループ内の残りのディスクにその容量を収容できるだけの空きがすでにある場合、交換用デバイスは不要です。手順 3 に進めます。足りない場合は、手順 2 で対処します。
これらを行う前に、1 つ確認しておく価値があります。変更の理由がファイルシステムの容量不足なら、実際に容量が使用されていることを確認してください。df と du の結果が一致せず、ファイルシステムが満杯に見える場合 は、実行中のプロセスが削除済みファイルを開いたままにしていることが一般的な原因です。ストレージを移動しても、この問題は解決しません。
ステップ 2: 交換デバイスをボリュームグループに追加する
プロバイダー側で交換用ボリュームを接続し、割り当てられたパスを確認してから、ラベルを付けてボリュームグループに追加します。
sudo apt install lvm2 # Ubuntu and Debian ship the tools in this package
sudo pvcreate "$NEW"
sudo vgextend "$VG" "$NEW"
sudo vgs -o vg_name,pv_count,vg_size,vg_freepvcreate は LVM ラベルだけを書き込み、それ以外は変更しません。vgextend は、そのデバイスのエクステントをプールに追加します。どちらのコマンドも既存の論理ボリューム内のデータには触れません。割り当てが変わるのは、明示的に要求した場合だけです。
LVM は raw デバイス全体を受け付けるため、pvcreate /dev/sdb はそのまま動作します。ディスク全体に 1 つのパーティションを作成すると、追加の手順は 1 つだけで済み、他のツールも認識できるシグネチャが残ります。そのため、次に lsblk を実行する人は、ラベルのないディスクではなく用途を確認できます。2 TiB を超えて拡張する可能性があるものには、MBR ではなく GPT パーティションテーブルを使用してください。交換用デバイスには十分な余裕を持たせてサイズを決めてください。広告上のサイズとツールが報告するサイズは同じではなく、LVM のメタデータによっても使用可能領域が少し減るためです。書類上で元のデバイスと完全に同じサイズの交換用デバイスでも、エクステント数ではわずかに小さくなることがあります。
このブロックの最後のコマンドは、ステップ 3 に進めるかどうかを確認します。ボリュームグループの空きエクステント数は、$OLD に割り当てられているエクステント数を上回っているでしょうか。そうなるまでは、pvmove がデータを書き込む場所がないため、処理を実行できません。
手順 3: オンラインで再開可能な状態で extents を pvmove する
sudo pvmove --test "$OLD"
sudo pvmove -i 30 "$OLD"この処理の仕組みを理解すると、マウント済みのファイルシステム上でも安全な理由が分かります。移動が必要な各セグメントについて、pvmove は logical volume 内に一時的なミラーを作成し、extents を新しい場所へコピーします。両方のコピーが同期するまで待機した後、古い側を削除してグループのメタデータを書き換えます。これらはすべてファイルシステムの下にある device mapper 層で行われるため、ファイルシステムから見るとデータの空白は発生しません。アプリケーションは処理中も読み書きを継続できます。-i 30 flag は 30 秒ごとに進捗を表示します。LVM に宛先を選ばせず、自分で指定する場合は、宛先を指定します: sudo pvmove "$OLD" "$NEW"。
- 低速です。割り当て済みの各 extent を、遅い方のデバイスの速度でコピーするためです。ネットワーク接続された volume では、ネットワーク速度が上限になります。SSH セッションが切断されても処理が終了しないように、
tmuxまたはscreen内で実行してください。 - ワークロードとディスク I/O を奪い合います。サーバーの負荷が低い時間帯に開始するか、
sudo pvmove -n <lvname> "$OLD"で一度に 1 つの volume だけを移動し、複数の時間帯に負荷を分散してください。 - 再開できます。途中でマシンが再起動した場合やプロセスが終了した場合は、引数なしで
sudo pvmoveを実行すると、未完了の移動を続行できます。sudo pvmove --abortは逆に処理をキャンセルし、各 logical volume がデータの一貫したコピーを指す状態を維持します。 - 一部のレイアウトはインプレースでの移動に対応していません。cache 層または thin pool の下にあるデバイスや、古い lvm2 releases における特定の RAID セグメントタイプは対象外です。
pvmoveが拒否した場合は、表示された内容を読み、man pvmoveで制限事項を確認してください。--forceを追加しても、未対応のレイアウトには対応できません。
完了したら、手順 1 で確認した質問を、特に $OLD についてもう一度確認します。そのデバイスに、まだ割り当て済みのものが残っていますか。割り当て済みの extents が残っている場合は、処理がひそかに失敗したのではなく、移動が完了していないことを示します。引数なしで sudo pvmove を実行すると、その処理を続行できます。
ステップ 4: デバイスをグループから vgreduce する
sudo vgreduce --test "$VG" "$OLD"
sudo vgreduce "$VG" "$OLD"vgreduce はデバイスをグループのメンバー一覧から削除し、残りの PV にボリュームグループのメタデータを書き直します。デバイスに割り当て済みのエクステントが残っている間は実行できません。実行すると、使用中の論理ボリュームの一部を切り離すことになるためです。この拒否は安全機構が機能していることを示します。ステップ 3 に戻ってください。
この時点で vgreduce --removemissing を使用しないでください。このフラグは、グループのディスクがすでに消失した場合に使用するものです。--force と組み合わせると、消失したデバイス上にエクステントがあったすべての論理ボリュームを削除します。これは、すでに発生した障害を修復するためのツールです。
手順 5: pvremove でラベルを削除してからデタッチする
sudo pvremove "$OLD"
sudo wipefs -a "$OLD"
sudo lvmdevices --deldev "$OLD" # only on systems using /etc/lvm/devices/system.devicespvremove は LVM ラベルを消去し、デバイスを物理ボリュームではなくします。デバイスがまだボリュームグループに所属している間は実行できません。そのため、先に手順 4 を実施します。wipefs -a は残っているシグネチャを消去します。パーティションテーブルも対象です。これにより、次にスキャンするツールへディスクが不完全な識別情報を提示することを防ぎます。filter ではなく devices file を使用する lvm2 のリリースでは、そのファイルからもパスを削除してください。削除しないと、存在しないデバイスがファイルに記録されたままになります。
次に、プロバイダー側でボリュームをデタッチします。その後、lsblk と sudo pvs でパスが消え、グループに残りのメンバーだけが一覧表示されることを確認します。マシンからデバイスを削除する前にメタデータから削除しているため、次回のブート時にグループは警告なしで完全にアクティベートされます。先にデタッチすると逆の状態になります。グループは部分的にしかアクティベートされず、すべての LVM コマンドで警告が表示されます。また、失われたディスク上に extent がある論理ボリュームは、グループを修復するまで使用できません。
論理ボリュームを削除する場合は、最初に fstab を処理する
ディスク上のデータが不要になったため、そのディスクを取り外すことがあります。この場合は論理ボリュームを削除します。ここでは、このガイドの他のどの場面よりも手順の順序が重要です。アンマウントし、/etc/fstab 行を削除してから、lvremove を実行します。
sudo umount /path/to/mountpoint
sudo swapoff "/dev/$VG/<lvname>" # only if this LV was swap
sudo nano /etc/fstab # delete the line naming this LV
sudo systemctl daemon-reload
sudo lvremove "$VG/<lvname>"この順序にするのは、systemd が起動時にすべての /etc/fstab 行を mount unit に変換するためです。行をファイルに残したまま論理ボリュームを削除すると、存在しないデバイスを unit が待ち続けます。その結果、local-fs.target が失敗し、コンソールで root パスワードの入力を求める emergency prompt で起動が停止します。レンタルサーバーでは、サーバーに接続できるようになる前に、プロバイダーのコンソールを探す必要があります。fstab の編集後に systemctl daemon-reload を実行すると、systemd は生成済みの unit を直ちに破棄します。そのため、削除する前の数秒間にボリュームを再マウントしようとする処理は発生しません。
umount でファイルシステムが busy と報告された場合は、sudo fuser -vm /path/to/mountpoint または sudo lsof +f -- /path/to/mountpoint で使用中のプロセスを特定し、そのプロセスを適切に停止します。umount -l は使用しないでください。lazy unmount は、open file が使われ続けている間も mount を namespace から切り離します。そのため、何かが書き込み中のストレージを lvremove する可能性があります。パスを使用している、見落としやすい処理も確認します。/etc/exports の NFS export、cron の backup や rsync ジョブ、container storage などです。compose ファイルの bind mount はホスト上のパスを指すため、その下にある論理ボリュームを削除すると、気付かないうちに root filesystem が使用され始めます。
グループ内にデータを移動する空きがない場合
代替デバイスを追加できず、他の PV にも空きがない場合は、ディスクをグループから外す前にデータ量を減らす必要があります。これは LVM の作業である前に、ファイルシステムの作業です。実行できるかどうかはファイルシステムによって決まります。
- ext4 は縮小できますが、アンマウント中に限られます。ボリュームをアンマウントし、対象に対して
sudo e2fsck -fを実行し、続いてsudo resize2fs <lv> <new size>、sudo lvreduce -L <new size> "$VG/<lvname>"を実行します。sudo lvreduce --resizefs -L <new size> "$VG/<lvname>"はfsadmを通じて両方の処理を実行しますが、内部のルールは同じです。 - XFS は、どのバージョンでも縮小できません。バックアップを作成し、より小さい新しい論理ボリュームを作成して、そこへリストアする必要があります。
注意すべき原則は、論理ボリュームを、その上にあるファイルシステムより小さくしてはならないことです。先にファイルシステムを縮小し、その後でボリュームを縮小します。ボリュームは、ファイルシステムが要求したサイズより少し大きく残します。lvreduce が確認を求めるのは、順序を誤るとファイルシステムの末尾が切り捨てられ、その後でボリュームを拡張しても元に戻せないためです。ボリュームを小さくすると、解放されたエクステントがグループに戻り、step 3 でデータを移動する空きができます。
手順の一覧
pvs、pvdisplay、lvs -a -o lv_name,seg_pe_rangesを使用して、PV に何が格納されているかを確認します。- 交換用デバイスへ
vgextendするか、別の場所でエクステントを解放して、グループに空き容量を確保します。 - 退出するデバイスからエクステントを
pvmoveします。これはオンラインで実行でき、中断後に再開でき、--testで事前に確認できます。 - デバイスをグループから
vgreduceします。 - ラベルを
pvremoveし、残った内容をwipefsします。 - プロバイダー側でデタッチし、
lsblkとpvsで確認します。
論理ボリュームも削除する場合は、最初の4行を次のように変更します。アンマウント、/etc/fstabの編集、systemctl daemon-reload、lvremove。
FAQ
不要になったブロックボリュームは、そのまま切り離してもよいですか?
そのボリューム上のデータを他の処理が必要としていない場合に限ります。思い込みで判断せず、確認してください。pvs -o pv_name,pv_used,pv_free と pvdisplay で、その物理ボリュームに割り当て済みのエクステントが残っているか確認し、lvs -a -o lv_name,seg_pe_ranges でそのエクステントが属する論理ボリュームを確認します。別の論理ボリュームがそのディスク上に一部でも存在する場合、切り離すとそのボリュームが壊れます。通常の LVM は、エクステントのコピーを別の場所に保持しないためです。pvmove でエクステントを移動し、vgreduce でデバイスをボリュームグループから外し、pvremove でラベルを消去してから切り離せば、問題なく完了します。
ファイルシステムをマウントしたまま pvmove を実行できますか。途中で中断された場合はどうなりますか?
はい。そのために設計されています。pvmove はファイルシステムの下に一時的なミラーを作成してエクステントをコピーし、device mapper 内で論理ボリュームを新しい場所へ切り替えます。その間もアプリケーションは読み書きを続けられます。再起動やセッション切断によって中断された場合は、引数なしで sudo pvmove を実行すると未完了の移動を再開できます。sudo pvmove --abort を実行すると停止し、すべてのボリュームを一貫した単一コピーの状態に保ちます。割り当て済みのすべてのエクステントをコピーするため、ディスクにかかる時間と同程度の時間が必要です。tmux または screen 内で実行してください。
論理ボリュームを削除した後、サーバーが起動しなくなったのはなぜですか?
そのボリュームの /etc/fstab 行がファイルに残っていたためです。systemd は fstab の各エントリからマウントユニットを生成します。そのユニットは存在しなくなったデバイスを待機するため、local-fs.target が失敗し、コンソールの緊急プロンプトで起動が停止します。復旧するには、プロバイダーのコンソールまたはレスキューイメージにアクセスし、古い行を削除してから再起動します。これを防ぐには、アンマウントし、fstab の行を削除し、systemctl daemon-reload を実行してから、最後に lvremove を実行します。root 以外のデータマウントに対応する fstab の行へ nofail を追加しておくと、次回同じミスをしても起動を継続できます。
vgreduce でボリュームグループからディスクを削除できないのはなぜですか?
通常は、その物理ボリュームに割り当て済みのエクステントが残っているためです。削除すると、使用中の論理ボリュームの一部が失われます。対象デバイスに対して pvs -o pv_name,pv_used,pv_free と pvdisplay で確認し、pvmove を完了または再開してから、もう一度試してください。もう1つの一般的な原因は、別のグループに属するデバイスを指定するパスの入力ミスです。そのため、シェル変数にパスを設定し、各手順の前に値を表示して確認することをお勧めします。2秒程度の手間で、誤操作を防げます。