pvmoveでデータを移動する

pvmoveコマンドで異なるパーティションにデータを移動する

先日の記事で論理ボリュームを使うという内容を記載しましたが、論理ボリュームを使うことにより、パーティションサイズの増減を行うことができるようになります。論理ボリュームを使う環境では、物理ディスクの入れ替えに伴う作業が簡単にできることが判りました。それが今回のpvmoveコマンドです。

pvmoveとは

pvmoveコマンドは、異なるPhysical Volume間でデータを移動することができるコマンドです。pvmoveはオンライン状態でデータの移動ができるため、コンピュータを使用している状態でデータの移動を行うことができます。また、複数のPhysical Volumeを1つのPhysical Volumeにまとめることもできます。従って、これまで複数のディスクで使用してきた環境で、容量の大きなディスクを購入して、1つにまとめるということがコンピュータを使いながら行えます。
新しいディスクを接続して、データをコピーすれば同じことも可能ですが、データ移動後に元のデータの削除、マウント先やPathを変更しなくてはいけない場合もあり、使いながら、変わらずに移動するというイメージとは少し違ってしまいます。
pvmoveはデータ自体の移動ではなく、データを含むPhysical Volumeを移動します。

pvmoveを使用するための要件

pvmoveを使用するにはいくつかの要件があります。

  • 論理ボリュームを使用している
  • 移動元、移動先のPhysical Volumeは同じVolume Groupに属している
  • 移動先のPhysical Volumeサイズは移動元のPhysical Volumeサイズよりも大きいこと

※今回使用しているディストリビューションはCentOS7です。

pvremoveコマンドでPhysical Volumeを移動する

検証環境では、拡張ディスクを2つのパーティションに切っています。2つのパーティションは同じVolume Groupに所属しています。

作業前の状態を確認します

[root@7-122 ~]# pvs
  PV         VG  Fmt  Attr PSize PFree
  /dev/sda2  cl  lvm2 a--  5.80g    0
  /dev/sdb1  vg1 lvm2 a--  5.00g    0
  /dev/sdb2  vg1 lvm2 a--  5.00g    0
[root@7-122 ~]# vgs
  VG  #PV #LV #SN Attr   VSize VFree
  cl    1   1   0 wz--n- 5.80g    0
  vg1   2   1   0 wz--n- 9.99g    0
[root@7-122 ~]# lvdisplay
  --- Logical volume ---
  LV Path                /dev/cl/root
  LV Name                root
  VG Name                cl
  LV UUID                32VRkg-cWJx-wuDE-o8Nn-TS73-G3qu-ZCRua4
  LV Write Access        read/write
  LV Creation host, time 7-122, 2017-09-22 13:46:12 +0900
  LV Status              available
  # open                 1
  LV Size                5.80 GiB
  Current LE             1485
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:0

  --- Logical volume ---
  LV Path                /dev/vg1/lv1
  LV Name                lv1
  VG Name                vg1
  LV UUID                FRGYwU-Hv2Y-wtUh-Y9hJ-NGpf-y7Js-YrmU23
  LV Write Access        read/write
  LV Creation host, time 7-122, 2017-09-22 17:05:38 +0900
  LV Status              available
  # open                 0
  LV Size                9.99 GiB
  Current LE             2558
  Segments               2
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:1

ディスクを追加します

[root@centos7-122 ~]# fdisk -l

Disk /dev/sda: 10.7 GB, 10737418240 bytes, 20971520 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0x000bc01a

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sda1   *        2048      411647      204800   83  Linux
/dev/sda2          411648    12582911     6085632   8e  Linux LVM
/dev/sda3        12582912    20971519     4194304   82  Linux swap / Solaris
WARNING: fdisk GPT support is currently new, and therefore in an experimental phase. Use at your own discretion.

Disk /dev/sdb: 10.7 GB, 10737418240 bytes, 20971520 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: gpt


#         Start          End    Size  Type            Name
 1           34     10485759      5G  Microsoft basic hdd1
 2     10485760     20969471      5G  Microsoft basic hdd2
WARNING: fdisk GPT support is currently new, and therefore in an experimental phase. Use at your own discretion.

Disk /dev/sdc: 8589 MB, 8589934592 bytes, 16777216 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: gpt


#         Start          End    Size  Type            Name
 1           34     16777182      8G  Microsoft basic exhdd

Disk /dev/mapper/cl-root: 6228 MB, 6228541440 bytes, 12165120 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト


Disk /dev/mapper/vg1-lv1: 10.7 GB, 10729029632 bytes, 20955136 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト

追加したディスクをVolume Groupに追加します

Volume Groupに追加するには、追加したディスクにPhysical Volumeを作成する必要があります。
pvcreateコマンドでPhysical Volumeを作成して、vgextendコマンドでVolume Groupに追加します。

[root@centos7-122 ~]# pvcreate /dev/sdc1
  Physical volume "/dev/sdc1" successfully created.
[root@centos7-122 ~]# pvs
  PV         VG  Fmt  Attr PSize PFree
  /dev/sda2  cl  lvm2 a--  5.80g    0
  /dev/sdb1  vg1 lvm2 a--  5.00g    0
  /dev/sdb2  vg1 lvm2 a--  5.00g    0
  /dev/sdc1      lvm2 ---  8.00g 8.00g
[root@centos7-122 ~]# vgextend vg1 /dev/sdc1
  Volume group "vg1" successfully extended
[root@centos7-122 ~]# vgs
  VG  #PV #LV #SN Attr   VSize  VFree
  cl    1   1   0 wz--n-  5.80g    0
  vg1   3   1   0 wz--n- 17.99g 8.00g

Physical Volumeを移動します

pvmoveコマンドでPhysial Volumeを移動します。pvmoveコマンドは、移動元のPhysical Volumeのデータをテンポラリの領域にコピーして、移動先のPhysical Volumeにコピーします。例えば、途中でサーバがダウンするなどが発生しても再度継続できます。オンラインで実行可能なコマンドで移動中に移動元のデータが更新されても、最終的に反映されます(なハズです)

pvmove 移動元のデバイス 移動先のデバイス
[root@centos7-122 ~]# pvs
  PV         VG  Fmt  Attr PSize PFree
  /dev/sda2  cl  lvm2 a--  5.80g    0
  /dev/sdb1  vg1 lvm2 a--  5.00g    0
  /dev/sdb2  vg1 lvm2 a--  5.00g    0
  /dev/sdc1  vg1 lvm2 a--  8.00g 8.00g
[root@centos7-122 ~]# pvmove /dev/sdb2 /dev/sdc1
  /dev/sdb2: Moved: 0.08%
  /dev/sdb2: Moved: 100.00%
[root@centos7-122 ~]# pvs
  PV         VG  Fmt  Attr PSize PFree
  /dev/sda2  cl  lvm2 a--  5.80g    0
  /dev/sdb1  vg1 lvm2 a--  5.00g    0
  /dev/sdb2  vg1 lvm2 a--  5.00g 5.00g
  /dev/sdc1  vg1 lvm2 a--  8.00g 3.00g

/dev/sdb2のPFreeが0から5.00gになっていることで、/dev/sdb2が空き領域になり、/dev/sdc1のPFreeが8.00gから3.00gになったことで、5.00g分の領域が移動したことが判ります。
サンプルは小さいサイズのPhysical Volumeを移動しているため、短時間で完了しますが、Physical Volumeのサイズに比例して実行時間が長くなります。pvmoveは時間が掛かると想定しておいてください。

複数のPhysical Volumeを1つのPhysical Volumeに移動する

pvmoveはPhysical Volumeのサイズが足りていれば、複数のPhysical Volumeを1つのPhysical Volumeに移動することができます。

サンプルでは、20GBのディスクを追加して、同じVolume Groupに登録しています。

[root@centos7-122 ~]# vgs
  VG  #PV #LV #SN Attr   VSize  VFree
  cl    1   1   0 wz--n-  5.80g    0
  vg1   3   1   0 wz--n- 17.99g 8.00g
[root@centos7-122 ~]# lvs
  LV   VG  Attr       LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  root cl  -wi-ao---- 5.80g
  lv1  vg1 -wi-ao---- 9.99g
[root@centos7-122 ~]# pvs
  PV         VG  Fmt  Attr PSize  PFree
  /dev/sda2  cl  lvm2 a--   5.80g     0
  /dev/sdb1  vg1 lvm2 a--   5.00g     0
  /dev/sdb2  vg1 lvm2 a--   5.00g     0
  /dev/sdc1  vg1 lvm2 a--   8.00g  8.00g
  /dev/sdd1  vg1 lvm2 a--  20.00g 20.00g

/dev/sdd1に/dev/sdb1と/dev/sdb2のPhysical Volumeを移動します

[root@centos7-122 ~]# pvmove /dev/sdb1 /dev/sdd1
  /dev/sdb1: Moved: 0.08%
  /dev/sdb1: Moved: 100.00%
[root@centos7-122 ~]# pvs
  PV         VG  Fmt  Attr PSize  PFree
  /dev/sda2  cl  lvm2 a--   5.80g     0
  /dev/sdb1  vg1 lvm2 a--   5.00g  5.00g
  /dev/sdb2  vg1 lvm2 a--   5.00g     0
  /dev/sdc1  vg1 lvm2 a--   8.00g  8.00g
  /dev/sdd1  vg1 lvm2 a--  20.00g 15.00g
[root@centos7-122 ~]# pvmove /dev/sdb2 /dev/sdd1
  /dev/sdb2: Moved: 0.78%
  /dev/sdb2: Moved: 100.00%
[root@centos7-122 ~]# pvs
  PV         VG  Fmt  Attr PSize  PFree
  /dev/sda2  cl  lvm2 a--   5.80g     0
  /dev/sdb1  vg1 lvm2 a--   5.00g  5.00g
  /dev/sdb2  vg1 lvm2 a--   5.00g  5.00g
  /dev/sdc1  vg1 lvm2 a--   8.00g  8.00g
  /dev/sdd1  vg1 lvm2 a--  20.00g 10.00g

PFreeの数値が変わっていることが確認できます。pvmoveによってsdb1とsdb2は空き状態になり、データがsdd1に移動しています。
pvemoveの実行後、sdb1とsdb2は未使用の状態になりますので、この状態でディスクsdbは取り外すことができます。

不要なディスクの取り外し

今回の記事では、ディスクの交換をイメージしています。pvemoveを実施してデータを移動して不要なディスクを取り外します。
不要なディスクを取り外すには、vgredueコマンドでVolume Groupから削除して、pvremoveコマンドでPhysical Volumeを削除します。

[root@centos7-122 ~]# vgs
  VG  #PV #LV #SN Attr   VSize  VFree
  cl    1   1   0 wz--n-  5.80g     0
  vg1   4   1   0 wz--n- 37.98g 27.99g
[root@centos7-122 ~]# lvs
  LV   VG  Attr       LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  root cl  -wi-ao---- 5.80g
  lv1  vg1 -wi-ao---- 9.99g
[root@centos7-122 ~]# vgs
  VG  #PV #LV #SN Attr   VSize  VFree
  cl    1   1   0 wz--n-  5.80g     0
  vg1   4   1   0 wz--n- 37.98g 27.99g
[root@centos7-122 ~]# vgreduce vg1 /dev/sdb1
  Removed "/dev/sdb1" from volume group "vg1"
[root@centos7-122 ~]# vgreduce vg1 /dev/sdb2
  Removed "/dev/sdb2" from volume group "vg1"
[root@centos7-122 ~]# vgs
  VG  #PV #LV #SN Attr   VSize  VFree
  cl    1   1   0 wz--n-  5.80g     0
  vg1   2   1   0 wz--n- 27.99g 18.00g
[root@centos7-122 ~]# pvs
  PV         VG  Fmt  Attr PSize  PFree
  /dev/sda2  cl  lvm2 a--   5.80g     0
  /dev/sdb1      lvm2 ---   5.00g  5.00g
  /dev/sdb2      lvm2 ---   5.00g  5.00g
  /dev/sdc1  vg1 lvm2 a--   8.00g  8.00g
  /dev/sdd1  vg1 lvm2 a--  20.00g 10.00g
[root@centos7-122 ~]# pvremove /dev/sdb1
  Labels on physical volume "/dev/sdb1" successfully wiped.
[root@centos7-122 ~]# pvremove /dev/sdb2
  Labels on physical volume "/dev/sdb2" successfully wiped.
[root@centos7-122 ~]# pvs
  PV         VG  Fmt  Attr PSize  PFree
  /dev/sda2  cl  lvm2 a--   5.80g     0
  /dev/sdc1  vg1 lvm2 a--   8.00g  8.00g
  /dev/sdd1  vg1 lvm2 a--  20.00g 10.00g

ここまでの操作では、論理ボリュームのサイズは変更していません。従って、論理ボリュームに含まれるPhysical Volumeは変わってますが、使用できる論理ボリュームの大きさは変わっていません。

[root@centos7-122 ~]# lvs
  LV   VG  Attr       LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  root cl  -wi-ao---- 5.80g
  lv1  vg1 -wi-ao---- 9.99g

論理ボリュームを拡張する

追加したディスクが大きい場合、且つ、論理ボリュームサイズを拡張したい場合は、lvextendコマンドを使用して論理ボリュームサイズを拡張します。
サンプルでは、Volume Groupに存在するPhysical Volumeの空き領域を論理ボリュームに組み込みます。

[root@centos7-122 ~]# lvs
  LV   VG  Attr       LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  root cl  -wi-ao---- 5.80g
  lv1  vg1 -wi-ao---- 9.99g
[root@centos7-122 ~]# lvextend -l +100%FREE /dev/mapper/vg1/lv1
  Size of logical volume vg1/lv1 changed from 9.99 GiB (2558 extents) to 27.99 GiB (7166 extents).
  Logical volume vg1/lv1 successfully resized.
[root@centos7-122 ~]# pvs
  PV         VG  Fmt  Attr PSize  PFree
  /dev/sda2  cl  lvm2 a--   5.80g    0
  /dev/sdc1  vg1 lvm2 a--   8.00g    0
  /dev/sdd1  vg1 lvm2 a--  20.00g    0
[root@centos7-122 ~]# lvs
  LV   VG  Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  root cl  -wi-ao----  5.80g
  lv1  vg1 -wi-ao---- 27.99g

論理ボリュームのサイズが変更されました。

lvextendコマンドで論理ボリュームのサイズを変更後、resize2fsを実行します。
dfコマンドでサイズが変更されたことを確認します。

# resize2fs /dev/mapper/vg1/lv1
# df -h

領域が足りない場合のエラー

移動先の領域が不足している場合には、pvmoveコマンドがエラーになります。

[root@centos7-122 ~]# pvmove /dev/sdb1 /dev/sdc1
  Insufficient free space: 1279 extents needed, but only 768 available
  Unable to allocate mirror extents for pvmove0.
  Failed to convert pvmove LV to mirrored

確認

ここまでの操作は、すべて論理ボリュームをマウントした状態で実施しています。(下記、一部抜粋)
pvmoveの実施、不要ディスクの削除を実施しても状態が変わらないことを確認しています。

[root@centos7-122 ~]# mount
/dev/mapper/cl-root on / type xfs (rw,relatime,seclabel,attr2,inode64,noquota)
/dev/mapper/vg1-lv1 on /mnt/hdd type ext4 (rw,relatime,seclabel,data=ordered)

使用環境によって、接続したディスクをフォーマットしておく必要があります。