ディスクパーティションとファイルシステムの拡張

# 背景
突然ですが個人的にパーティションが嫌いです（ディスクのパーティションのことであってDBのパーティション表とかではありません）。

# 20190313追記
+ `fdisk`ではなく`parted`ならオンラインのパーティションテーブル書き換えが可能
+ `parted /dev/sda`でツール起動
+ `unit s`で単位をセクタに変更
+ `resizepart 2 -1s`で2個目のパーティション、つまり/dev/sda2をディスクの最終セクタまで拡張
+ `q`で終了

`fdisk`と異なり、一旦メモリ上に情報を記憶して`w`で書き込むのではなく、コマンドを実行するとすぐに反映されることに注意が必要。

```bash
parted /dev/sda
(parted) unit s
(parted) resizepart 2 -1s
(parted) q
```



##### 嫌いになった経緯
+ VMware上で稼働するLinuxの既存環境があった
+ ブートデバイスディスクを除く全てのディスクで、まるごと1つのパーティションが切られていた
+ PVはそのパーティションデバイスを指定してあった
+ そのうちのいくつかのファイルシステム領域拡張を依頼された
+ PVは増やせないと言われた（理由は不明、というか多分ないのだが、とにかく仮想ディスクのエクステント追加でよろしく、と）

`fdisk`でパーティションテーブル書き換えますと言ったら、「なんとなく不安」という意見がその場を支配しはじめ（これもよくわからない）、なぜかVGから再作成（当然中身のデータはバックアップしてあとでリストア）と相成ったというほろ苦い思い出があるからであります（その現場には超短期間ヘルプで入っていたので、意思決定者に直接タッチできなかったということもほろ苦さを増していますが）。
***仮想化やLVMによる柔軟性ってなんだっけ？***と誰にも聞こえないように問うた記憶がまだ生々しく残っております。

それはそれとしても、ブートディスクでパーティションテーブルがないと起動できない、とかいう制約がある部分ならまだしも、仮想化技術で小さいものから大きなものまで、まさに柔軟にサーバへディスクを割り当てることが簡単になった現在、ちまちまパーティション分割するメリットがよくわからないのです（昔の癖で、と言われたらある程度納得はしますが）。

前置きが長くなりましたが、今回はいろいろな条件下でファイルシステムを拡張する手順の覚書程度のまとめです（`fdisk`なんてもう何年も使ってない。。。）。

# 前提環境
+ ハイパーバイザ：VMware Fusion
+ ゲストOS：Red Hat Enterprise Linux Server 7.3 (Maipo)

|#| パーティション使用 | LVM使用 | デバイス | VG/LVOL名 |
|:--:|:--:|:--:|:--:|:--:|
|1| なし | なし | /dev/sdc | - |
|2| なし | あり | /dev/sdd | vgA/lvol1 |
|3| １つ | なし | /dev/sde1 | - |
|4| １つ | あり | /dev/sdf1 | vgB/lvol1 |
|5| ２つ | なし | /dev/sdg2 | - |
|6| ２つ | あり | /dev/sdh2 | vgC/lvol1 |

# 環境構築
まずはVMから各5 GBの仮想ディスクを6個割り当ててOSを起動する。ファイルシステムを作りながらディスクのサイズがどうなっているか注視する。

## 初期状態

```bash
$ fdisk -l /dev/sd[c-h]
```

```text:出力抜粋
Disk /dev/sdc: 5368 MB, 5368709120 bytes, 10485760 sectors
Disk /dev/sdd: 5368 MB, 5368709120 bytes, 10485760 sectors
Disk /dev/sde: 5368 MB, 5368709120 bytes, 10485760 sectors
Disk /dev/sdf: 5368 MB, 5368709120 bytes, 10485760 sectors
Disk /dev/sdg: 5368 MB, 5368709120 bytes, 10485760 sectors
Disk /dev/sdh: 5368 MB, 5368709120 bytes, 10485760 sectors
Units = sectors of 1 * 512 = 512 bytes
```

セクターサイズ512 byteのブロックデバイスとして認識されている。

## パーティション作成
`fdisk`でパーティションを作成する。

```bash
$ fdisk /dev/sdf
コマンド (m でヘルプ): p
```

```
Disk /dev/sdf: 5368 MB, 5368709120 bytes, 10485760 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0x42ab3b0b

デバイス ブート      始点        終点     ブロック   Id  システム
```

まっさらなディスクなのでパーティションテーブルはまだない。

```bash
コマンド (m でヘルプ): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): 
Using default response p
パーティション番号 (1-4, default 1): 
最初 sector (2048-10485759, 初期値 2048): 
初期値 2048 を使います
Last sector, +sectors or +size{K,M,G} (2048-10485759, 初期値 10485759): 
初期値 10485759 を使います
Partition 1 of type Linux and of size 5 GiB is set
```

`n`で新しいパーティションを作成、`p`でプライマリパーティション、番号・開始セクタ・終了セクタはデフォルトで、これでディスクのフル領域が1番パーティションとなる。再び`p`でパーティションテーブルを確認する。

```
コマンド (m でヘルプ): p

Disk /dev/sdf: 5368 MB, 5368709120 bytes, 10485760 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0x42ab3b0b

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sdf1            2048    10485759     5241856   83  Linux
```
最後に`w`でパーティションテーブルを書き込んで終了。

同様の手順でパーティションを作成していった結果。

```bash
$ fdisk -l /dev/sd[c-h]
```

```text:出力抜粋
Disk /dev/sdc: 5368 MB, 5368709120 bytes, 10485760 sectors
Disk /dev/sdd: 5368 MB, 5368709120 bytes, 10485760 sectors
Disk /dev/sde: 5368 MB, 5368709120 bytes, 10485760 sectors
デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sde1            2048    10485759     5241856   83  Linux
Disk /dev/sdf: 5368 MB, 5368709120 bytes, 10485760 sectors
デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sdf1            2048    10485759     5241856   83  Linux
Disk /dev/sdg: 5368 MB, 5368709120 bytes, 10485760 sectors
デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sdg1            2048       22527       10240   83  Linux
/dev/sdg2           22528    10485759     5231616   83  Linux
Disk /dev/sdh: 5368 MB, 5368709120 bytes, 10485760 sectors
デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sdh1            2048       22527       10240   83  Linux
/dev/sdh2           22528    10485759     5231616   83  Linux
```

## LVM構成
`pvcreate`、`vgcreate`、`lvcreate`の順に実行する。

```bash:出力は適宜省略
$ pvcreate /dev/sdd
$ pvcreate /dev/sdf1
$ pvcreate /dev/sdh2
$ pvdisplay /dev/sdd /dev/sdf1 /dev/sdh2
$ vgcreate vgA /dev/sdd
$ vgcreate vgB /dev/sdf1
$ vgcreate vgC /dev/sdh2
$ vgdisplay -v vgA vgB vgC
$ lvcreate -l 100%free -n lvol1 vgA
$ lvcreate -l 100%free -n lvol1 vgB
$ lvcreate -l 100%free -n lvol1 vgC
$ lvdisplay -v /dev/vg[A-C]/lvol1
```

```
  --- Logical volume ---
  LV Path                /dev/vgA/lvol1
  LV Name                lvol1
  VG Name                vgA
  LV UUID                H0ttAb-8Pq5-Z3q7-qjiX-Gqop-YyVt-Ac7HYx
  LV Write Access        read/write
  LV Creation host, time rhel2, 2018-10-20 10:10:15 +0900
  LV Status              available
  # open                 0
  LV Size                5.00 GiB
  Current LE             1279
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:3
   
  --- Logical volume ---
  LV Path                /dev/vgB/lvol1
  LV Name                lvol1
  VG Name                vgB
  LV UUID                GcodIs-clkk-OmI9-mV9f-rFKT-7SKu-T1tBsO
  LV Write Access        read/write
  LV Creation host, time rhel2, 2018-10-20 10:10:20 +0900
  LV Status              available
  # open                 0
  LV Size                5.00 GiB
  Current LE             1279
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:4
   
  --- Logical volume ---
  LV Path                /dev/vgC/lvol1
  LV Name                lvol1
  VG Name                vgC
  LV UUID                ZrKMyB-JSWH-sUVh-itu6-eoPj-guhS-LNef2x
  LV Write Access        read/write
  LV Creation host, time rhel2, 2018-10-20 10:10:22 +0900
  LV Status              available
  # open                 0
  LV Size                4.99 GiB
  Current LE             1277
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:5
```

## ファイルシステム作成
あとは前述のデバイス、LVOLにファイルシステム（今回はext4）を作成する。

```bash
$ mkfs.ext4 /dev/sdc
$ mkfs.ext4 /dev/vgA/lvol1
$ mkfs.ext4 /dev/sde1
$ mkfs.ext4 /dev/vgB/lvol1
$ mkfs.ext4 /dev/sdg2
$ mkfs.ext4 /dev/vgC/lvol1
```

コマンドの出力としてファイルシステムのブロック数がレポートされるので、ここで一旦サイズをまとめる。

| # | device | PV | # of sectors | fs blocks（4096Byte） | df（1K）    |
|:--:|:--:|:--:|:--:|:--:|:--:|
| 1 | /dev/sdc | - | 10,485,760 | 1,310,720 | 5,029,504 |
| 2 | /dev/vgA/lvol1 | /dev/sdd | 10,485,760 | 1,309,696（-4 MiB）*2 | 5,025,408 |
| 3 | /dev/sde1 | - | 10,483,712（-1 MiB）*1 | 1,310,464（-1 MiB） | 5,028,480 |
| 4 | /dev/vgB/lvol1 | /dev/sdf1 | 10,483,712（-1 MiB）*1 | 1,309,696（-4 MiB）*3 | 5,025,408 |
| 5 | /dev/sdg2 | - | 10,463,231 | 1,307,904 | 5,018,400 |
| 6 | /dev/vgC/lvol1 | /dev/sdh2 | 10,463,231 | 1,307,648 | 5,017,376 |

カッコ内は、#1と比べたサイズの差分（#5,#6はそもそもサイズが異なるので記載なし）
### *1：ディスクセクター数の差異について
ディスク全体を一つのパーティションにした場合（#3）、パーティションメタデータ（いわゆるパーティションテーブル）がディスクの先頭2048セクター（2048 x 512 = 1 MiB）に書かれ、その分データディスクとして使用できる領域も少なくなる。
ディスク全体をフォーマットした場合（#1）と比較して、ファイルシステムブロック数の差分も"256"ブロック、つまり1 MiBになる。当然ながらファイルシステムレベルでも同様に1 MiBだけ少ない。

### *2：LVMを使用した際のファイルシステムブロック数
ディスク全体をファイルシステムとしてフォーマットした場合（#1）と、ディスク全体をPVにした場合（#2）とで比べると、ファイルシステムブロックサイズが4 MiB少ない。これはLVMのメタデータ分。

### *3：パーティション領域のLVとディスク全体のLVとでファイルシステムサイズが同じ
不思議なのはディスクを丸ごとPVにした場合（#2）と、ディスク全体を一つのパーティションにしてPVにした場合（#4）とで、ファイルシステムブロックサイズに差異がないこと。パーティション作成した時点でOSから認識できるディスクのセクターが1 MiB少ないはずなので、#1と比べると-5 MiBになってもよさそうなものである。

とりあえず`dd`でPVの先頭4 MBをファイル出力して中身を見てみる。

```bash
$ dd if=/dev/sdd  bs=1048576 count=4 of=/tmp/sdd.dat
$ dd if=/dev/sdf1 bs=1048576 count=4 of=/tmp/sdf1.dat

$ strings /tmp/sdd.dat
$ strings /tmp/sdf1.dat
```

出力結果は省略するが、ちゃんとデバイスサイズ（device_size）はfdiskで見たときのセクタ数と一致している。
うーん、と悩んだところでPE数（pe_count）が同じ1279であることに気づいた。PEサイズ（extent_size）が8192セクタ（つまり8192 x 512 = 4 MiB）なので、この単位で繰り上がって、実デバイスサイズは1 MiB少ない（足りない）にもかかわらず、同じPE数を確保した、と思われる（**この程度の話であればわざわざディスクの中身を見ずとも`pvdisplay`した時点で気づけたがあとの祭り**）。

ということは、ディスクをフルに使って、たまたま最後のPEに3 MiBより大きなオブジェクトを書き込もうとした、などというレアケースが発生した場合は、ディスクレイヤからエラーが返ることになる（これが問題になることはまずあり得ないが、、、）。
それにしても、足りないんだったら確保するPEを少なくした方がいいんじゃね？という人と、いやいや勿体無いから大きく見せとけ、どうせ最後のPEをフルに使うことなんて超レアだし、そもそもそんな枯渇寸前の状態自体のがより問題だろう、なんて議論があったかないかは知る由もない。

# ディスク拡張
さて、ここからが本題で、これらのファイルシステムを拡張するとなった場合、どうするのかそれぞれやってみる。
本来LVMのメリットは、別のPVを追加してLVを拡張できるという点にもあるわけだが、前提となっているお話の通り、ここはOSから見てPVが物理的に拡張された、というストーリーでやっていく。

VMのレイヤで各ディスクに対し、1 GiB拡張（VMレイヤのエクステンと追加）したところからスタート。

```bash
fdisk -l /dev/sd[c-h]
```

```text:出力抜粋
Disk /dev/sdc: 6442 MB, 6442450944 bytes, 12582912 sectors
Disk /dev/sdd: 6442 MB, 6442450944 bytes, 12582912 sectors
Disk /dev/sde: 6442 MB, 6442450944 bytes, 12582912 sectors
デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sde1            2048    10485759     5241856   83  Linux
Disk /dev/sdf: 6442 MB, 6442450944 bytes, 12582912 sectors
デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sdf1            2048    10485759     5241856   83  Linux
Disk /dev/sdg: 6442 MB, 6442450944 bytes, 12582912 sectors
デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sdg1            2048       22527       10240   83  Linux
/dev/sdg2           22528    10485759     5231616   83  Linux
Disk /dev/sdh: 6442 MB, 6442450944 bytes, 12582912 sectors
デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sdh1            2048       22527       10240   83  Linux
/dev/sdh2           22528    10485759     5231616   83  Linux
```

ディスクの総セクター数は増えたが、当然パーティションサイズはそのまま。

## パターン1：ディスク丸ごとファイルシステムの場合
手順はシンプル。`e2fsck`してから`resize2fs`するだけ。

```bash
$ e2fsck -f /dev/sdc
e2fsck 1.42.9 (28-Dec-2013)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/sdc: 11/327680 files (0.0% non-contiguous), 58462/1310720 blocks

$ resize2fs /dev/sdc
resize2fs 1.42.9 (28-Dec-2013)
Resizing the filesystem on /dev/sdc to 1572864 (4k) blocks.
The filesystem on /dev/sdc is now 1572864 blocks long.
```

## パターン2：ディスク丸ごとPVにした場合
LVMレイヤの拡張手順（`pvresize`、`lvextend`）を踏んだのち、ファイルシステムを拡張する。

```bash
$ pvdisplay /dev/sdd
  --- Physical volume ---
  PV Name               /dev/sdd
  VG Name               vgA
  PV Size               5.00 GiB / not usable 4.00 MiB
  Allocatable           yes (but full)
  PE Size               4.00 MiB
  Total PE              1279
  Free PE               0
  Allocated PE          1279
  PV UUID               MqYsdP-vjaP-p5ZA-I09m-Qj4q-tDTZ-fQW2os
   
$ pvresize /dev/sdd
  Physical volume "/dev/sdd" changed
  1 physical volume(s) resized / 0 physical volume(s) not resized
$ pvdisplay /dev/sdd
  --- Physical volume ---
  PV Name               /dev/sdd
  VG Name               vgA
  PV Size               6.00 GiB / not usable 3.00 MiB
  Allocatable           yes 
  PE Size               4.00 MiB
  Total PE              1535
  Free PE               256
  Allocated PE          1279
  PV UUID               MqYsdP-vjaP-p5ZA-I09m-Qj4q-tDTZ-fQW2os

$ lvextend -l +100%free /dev/vgA/lvol1
  Size of logical volume vgA/lvol1 changed from 5.00 GiB (1279 extents) to 6.00 GiB (1535 extents).
  Logical volume vgA/lvol1 successfully resized.

$ e2fsck -f /dev/vgA/lvol1 
e2fsck 1.42.9 (28-Dec-2013)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/vgA/lvol1: 11/327680 files (0.0% non-contiguous), 58462/1309696 blocks
$ resize2fs /dev/vgA/lvol1
resize2fs 1.42.9 (28-Dec-2013)
Resizing the filesystem on /dev/vgA/lvol1 to 1571840 (4k) blocks.
The filesystem on /dev/vgA/lvol1 is now 1571840 blocks long.
```

## パターン3：パーティション拡張
パーティションテーブルを書き換える必要があるため、一度パーティションを削除して再作成する必要がある。あとはパターン1と同じ。

```bash
$ fdisk /dev/sde
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


コマンド (m でヘルプ): p

Disk /dev/sde: 6442 MB, 6442450944 bytes, 12582912 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0xf22e3ca1

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sde1            2048    10485759     5241856   83  Linux

コマンド (m でヘルプ): d
Selected partition 1
Partition 1 is deleted

コマンド (m でヘルプ): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): 
Using default response p
パーティション番号 (1-4, default 1): 
最初 sector (2048-12582911, 初期値 2048): 
初期値 2048 を使います
Last sector, +sectors or +size{K,M,G} (2048-12582911, 初期値 12582911): 
初期値 12582911 を使います
Partition 1 of type Linux and of size 6 GiB is set

コマンド (m でヘルプ): p

Disk /dev/sde: 6442 MB, 6442450944 bytes, 12582912 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0xf22e3ca1

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sde1            2048    12582911     6290432   83  Linux

コマンド (m でヘルプ): w
パーティションテーブルは変更されました！

ioctl() を呼び出してパーティションテーブルを再読込みします。
ディスクを同期しています。
$ e2fsck -f /dev/sde1
e2fsck 1.42.9 (28-Dec-2013)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/sde1: 11/327680 files (0.0% non-contiguous), 58462/1310464 blocks
$ resize2fs /dev/sde1
resize2fs 1.42.9 (28-Dec-2013)
Resizing the filesystem on /dev/sde1 to 1572608 (4k) blocks.
The filesystem on /dev/sde1 is now 1572608 blocks long.
```

よくいわれる注意事項だが、パーティションテーブルを書き換える際、開始・終了位置をセクター単位で間違える（変更する）と、既存のファイルシステムなりメタデータ領域にアクセスできなくなる。パーティションテーブルの情報（セクタ単位のアドレス）と、実際のアドレスにあるデータが不整合となるため至極当然だが、これこそが一般的にこの作業が嫌がられる、そして顧客も嫌がる、ベンダーもサポートしたくない、みんな不幸になる可能性がある一番の理由だと思われる（ミッションクリティカルなシステムでなくてもこんなリスクがあることはしたくない）。対象のパーティションが一つで、全部使うならまだいいけど。。。

## パターン4：パーティション上にLVM
パターン3と同様、パーティションテーブルを書き換える必要があるため、一度パーティションを削除して再作成し、さらにPVとLVを拡張する（パターン2と同様）。

```bash
$ fdisk /dev/sdf
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


コマンド (m でヘルプ): p

Disk /dev/sdf: 6442 MB, 6442450944 bytes, 12582912 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0x42ab3b0b

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sdf1            2048    10485759     5241856   83  Linux

コマンド (m でヘルプ): d
Selected partition 1
Partition 1 is deleted

コマンド (m でヘルプ): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p):  
Using default response p
パーティション番号 (1-4, default 1): 
最初 sector (2048-12582911, 初期値 2048): 
初期値 2048 を使います
Last sector, +sectors or +size{K,M,G} (2048-12582911, 初期値 12582911): 
初期値 12582911 を使います
Partition 1 of type Linux and of size 6 GiB is set

コマンド (m でヘルプ): p

Disk /dev/sdf: 6442 MB, 6442450944 bytes, 12582912 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0x42ab3b0b

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sdf1            2048    12582911     6290432   83  Linux

コマンド (m でヘルプ): w
パーティションテーブルは変更されました！

ioctl() を呼び出してパーティションテーブルを再読込みします。
ディスクを同期しています。
$ pvdisplay /dev/sdf1
  --- Physical volume ---
  PV Name               /dev/sdf1
  VG Name               vgB
  PV Size               5.00 GiB / not usable 3.00 MiB
  Allocatable           yes (but full)
  PE Size               4.00 MiB
  Total PE              1279
  Free PE               0
  Allocated PE          1279
  PV UUID               zhcNGA-5snn-xgmX-KO1v-GxIM-LBPA-mNk4eb
   
$ pvresize /dev/sdf1
  Physical volume "/dev/sdf1" changed
  1 physical volume(s) resized / 0 physical volume(s) not resized
$ pvdisplay /dev/sdf1
  --- Physical volume ---
  PV Name               /dev/sdf1
  VG Name               vgB
  PV Size               6.00 GiB / not usable 2.00 MiB
  Allocatable           yes 
  PE Size               4.00 MiB
  Total PE              1535
  Free PE               256
  Allocated PE          1279
  PV UUID               zhcNGA-5snn-xgmX-KO1v-GxIM-LBPA-mNk4eb
   
$ lvextend -l +100%free /dev/vgB/lvol1
  Size of logical volume vgB/lvol1 changed from 5.00 GiB (1279 extents) to 6.00 GiB (1535 extents).
  Logical volume vgB/lvol1 successfully resized.
$ vgchange -a y /dev/vgB
  1 logical volume(s) in volume group "vgB" now active
$ e2fsck -f /dev/vgB/lvol1
e2fsck 1.42.9 (28-Dec-2013)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/vgB/lvol1: 11/327680 files (0.0% non-contiguous), 58462/1309696 blocks
$ resize2fs /dev/vgB/lvol1
resize2fs 1.42.9 (28-Dec-2013)
Resizing the filesystem on /dev/vgB/lvol1 to 1571840 (4k) blocks.
The filesystem on /dev/vgB/lvol1 is now 1571840 blocks long.
```

## パターン5：パーティションの２番目の領域を拡張
基本的な手順は全体を一つのパーティションとした場合と同様だが、開始セクターを間違えるリスクが高いのがこのパターン。

```bash
$ fdisk /dev/sdg
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


コマンド (m でヘルプ): p

Disk /dev/sdg: 6442 MB, 6442450944 bytes, 12582912 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0xedc9e041

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sdg1            2048       22527       10240   83  Linux
/dev/sdg2           22528    10485759     5231616   83  Linux

コマンド (m でヘルプ): d
パーティション番号 (1,2, default 2): 
Partition 2 is deleted

コマンド (m でヘルプ): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): 
Using default response p
パーティション番号 (2-4, default 2): 
最初 sector (22528-12582911, 初期値 22528): 
初期値 22528 を使います
Last sector, +sectors or +size{K,M,G} (22528-12582911, 初期値 12582911): 
初期値 12582911 を使います
Partition 2 of type Linux and of size 6 GiB is set

コマンド (m でヘルプ): p

Disk /dev/sdg: 6442 MB, 6442450944 bytes, 12582912 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0xedc9e041

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sdg1            2048       22527       10240   83  Linux
/dev/sdg2           22528    12582911     6280192   83  Linux

コマンド (m でヘルプ): w
パーティションテーブルは変更されました！

ioctl() を呼び出してパーティションテーブルを再読込みします。
ディスクを同期しています。
$ e2fsck -f /dev/sdg2
e2fsck 1.42.9 (28-Dec-2013)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/sdg2: 11/327040 files (0.0% non-contiguous), 58414/1307904 blocks
$ resize2fs /dev/sdg2
resize2fs 1.42.9 (28-Dec-2013)
Resizing the filesystem on /dev/sdg2 to 1570048 (4k) blocks.
The filesystem on /dev/sdg2 is now 1570048 blocks long.
```

## パターン6：パーティション2番目のLVM領域を拡張
これまでの手順の組み合わせ。

```bash
$ fdisk /dev/sdh
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


コマンド (m でヘルプ): p

Disk /dev/sdh: 6442 MB, 6442450944 bytes, 12582912 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0x7d9e9df0

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sdh1            2048       22527       10240   83  Linux
/dev/sdh2           22528    10485759     5231616   83  Linux

コマンド (m でヘルプ): d
パーティション番号 (1,2, default 2): 
Partition 2 is deleted

コマンド (m でヘルプ): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): 
Using default response p
パーティション番号 (2-4, default 2): 
最初 sector (22528-12582911, 初期値 22528): 
初期値 22528 を使います
Last sector, +sectors or +size{K,M,G} (22528-12582911, 初期値 12582911): 
初期値 12582911 を使います
Partition 2 of type Linux and of size 6 GiB is set

コマンド (m でヘルプ): p

Disk /dev/sdh: 6442 MB, 6442450944 bytes, 12582912 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0x7d9e9df0

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sdh1            2048       22527       10240   83  Linux
/dev/sdh2           22528    12582911     6280192   83  Linux

コマンド (m でヘルプ): w
パーティションテーブルは変更されました！

ioctl() を呼び出してパーティションテーブルを再読込みします。
ディスクを同期しています。
$ pvdisplay /dev/sdh2
  --- Physical volume ---
  PV Name               /dev/sdh2
  VG Name               vgC
  PV Size               4.99 GiB / not usable 0   
  Allocatable           yes (but full)
  PE Size               4.00 MiB
  Total PE              1277
  Free PE               0
  Allocated PE          1277
  PV UUID               hoazp1-6YMK-9jvt-lonT-CxHE-kgoM-2DauuF
   
$ pvresize /dev/sdh2
  Physical volume "/dev/sdh2" changed
  1 physical volume(s) resized / 0 physical volume(s) not resized
$ pvdisplay /dev/sdh2
  --- Physical volume ---
  PV Name               /dev/sdh2
  VG Name               vgC
  PV Size               5.99 GiB / not usable 1.00 MiB
  Allocatable           yes 
  PE Size               4.00 MiB
  Total PE              1533
  Free PE               256
  Allocated PE          1277
  PV UUID               hoazp1-6YMK-9jvt-lonT-CxHE-kgoM-2DauuF
   
$ vgchange -a y vgC
  1 logical volume(s) in volume group "vgC" now active
$ lvextend -l +100%free /dev/vgC/lvol1
  Size of logical volume vgC/lvol1 changed from 4.99 GiB (1277 extents) to 5.99 GiB (1533 extents).
  Logical volume vgC/lvol1 successfully resized.
$ e2fsck -f /dev/vgC/lvol1 
e2fsck 1.42.9 (28-Dec-2013)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/vgC/lvol1: 11/327040 files (0.0% non-contiguous), 58414/1307648 blocks
$ resize2fs /dev/vgC/lvol1 
resize2fs 1.42.9 (28-Dec-2013)
Resizing the filesystem on /dev/vgC/lvol1 to 1569792 (4k) blocks.
The filesystem on /dev/vgC/lvol1 is now 1569792 blocks long.
```

# オンライン拡張
これまでの手順は基本的にオフライン（当該ディスクアンマウント、VGは非活性）前提だったが、オンライン拡張してくれとなると話が違ってくる。`fdisk`によるパーティション変更は、対象デバイスがオフラインでないとできない。
オンライン拡張（マウントしたままファイルシステム拡張）が可能なのは、

* ディスクを丸ごとファイルシステムにする（パターン1）
* ディスクを丸ごとPVにする（パターン2）
* LVMなら素直にPVを追加する

ということになる。

## パターン1：ディスク丸ごと
`resize2fs`するだけ。至極簡単。

```bash
$ mount /dev/sdc /mnt/1
$ df /dev/sdc
ファイルシス    1K-ブロック    使用   使用可 使用% マウント位置
/dev/sd            6061632   20472  5710204    1% /mnt/1
$ resize2fs /dev/sdc
resize2fs 1.42.9 (28-Dec-2013)
Filesystem at /dev/sdc is mounted on /mnt/1; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 1
The filesystem on /dev/sdc is now 1835008 blocks long.

$ df /dev/sdc
ファイルシス   1K-ブロック  使用  使用可 使用% マウント位置
/dev/sdc           7093752 23028 6697828    1% /mnt/1
```

## パターン2：ディスク丸ごとPV
オフラインでのときと同様、LVMレイヤの操作（`pvresize`、`lvextend`）が増える。

```bash
$ mount /dev/vgA/lvol1 /mnt/2
$ df /mnt/2
ファイルシス          1K-ブロック  使用  使用可 使用% マウント位置
/dev/mapper/vgA-lvol1     6057536 20472 5706316    1% /mnt/2
$ pvresize /dev/sdd
  Physical volume "/dev/sdd" changed
  1 physical volume(s) resized / 0 physical volume(s) not resized
$ lvextend -l +100%free /dev/vgA/lvol1
  Size of logical volume vgA/lvol1 changed from 6.00 GiB (1535 extents) to 7.00 GiB (1791 extents).
  Logical volume vgA/lvol1 successfully resized.
$ resize2fs /dev/vgA/lvol1
resize2fs 1.42.9 (28-Dec-2013)
Filesystem at /dev/vgA/lvol1 is mounted on /mnt/2; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 1
The filesystem on /dev/vgA/lvol1 is now 1833984 blocks long.

$ df /mnt/2
ファイルシス          1K-ブロック  使用  使用可 使用% マウント位置
/dev/mapper/vgA-lvol1     7089656 23028 6694104    1% /mnt/2
```

## パターン3：素直にディスク追加
従来のやり方（`pvcreate`、`vgextend`、`lvextend`）でLVを拡張してファイルシステムのリサイズ。

```bash
$ df /mnt/2
ファイルシス          1K-ブロック  使用  使用可 使用% マウント位置
/dev/mapper/vgA-lvol1     7089656 23028 6694104    1% /mnt/2
$ pvcreate /dev/sdc
  Physical volume "/dev/sdc" successfully created.
$ vgextend vgA /dev/sdc
  Volume group "vgA" successfully extended
$ lvextend -l +100%free /dev/vgA/lvol1
  Size of logical volume vgA/lvol1 changed from 7.00 GiB (1791 extents) to 13.99 GiB (3582 extents).
  Logical volume vgA/lvol1 successfully resized.
$ resize2fs /dev/vgA/lvol1
resize2fs 1.42.9 (28-Dec-2013)
Filesystem at /dev/vgA/lvol1 is mounted on /mnt/2; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 2
The filesystem on /dev/vgA/lvol1 is now 3667968 blocks long.

$ df /mnt/2
ファイルシス          1K-ブロック  使用   使用可 使用% マウント位置
/dev/mapper/vgA-lvol1    14310408 25544 13619076    1% /mnt/2
```

# まとめ
覚書のみで実機検証はしないが、[AWS公式マニュアル](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/recognize-expanded-volume-linux.html)に記載があって、EBSではオンライン（OS起動中）の領域拡張が可能で、しかもLinux用には`growpart`というコマンドが提供されており、オンラインでパーティションを拡張してくれる。
これなら***ダウンタイムゼロでディスクの拡張ができる***。やりたいかどうか、あるいは政治的な判断で本当にオンラインでやるかどうかは別として、、、

こうなるとLVMによる領域拡張の柔軟性にはほとんど意義がないので、LVMスナップショットとかのイロモノ（？）機能を使いたいとか、CPUには余裕があるのでソフトウェアRAIDでストライピングしてしまおうとか、EBSでさらにLVMミラー構成という変態技を使いたいとかいう以外に、LVMを使用するメリットはほとんどなさそう（複数EBSでVGを構成したらEBSスナップショットをとるときに気を使わないといけないし）。
IO負荷分散するにしても、それってLVMのレイヤでするべきことかどうかはよくよく考える必要がありそう。

そもそもの本題だった領域拡張について、技術的にはパーティション有無、LVM使用有無に関わらず、ファイルシステムの拡張は可能だが（もちろんパーティション拡張の場合は対象がパーティションの最後というのが大前提）、一番シンプルなのはLVMも使わずディスクを丸ごとファイルシステムにしてしまうやりかたとなる（なにせ仮想化レイヤでエクステント追加してもらったらOS側では`resize2fs`するだけ）。
ただし、その先にあるはずの物理領域（ストレージ本体）がどのように領域を確保するのかは要注意。気の利いた環境であれば、物理ディスク（RAIDのデータディスク）は適切にIO負荷分散され、領域追加を見越したアーキテクチャになっている（はず）。

もしそうでない、あるいは一つのディスクにIOが集中することで、OSのIOスケジューラあたりでキューイングされてしまう可能性がある、大きなファイルシステムであれば、LVMで複数ディスクを束ねることにも意義があるかもしれないが、おそらくそのような要件が生じるのはDBがほとんどと思われるので、そうであればRDBMSの機能でデータ領域を分散させる方がよいかもしれない（ファイルサーバだったら？とか考えるとけっこう寝られなくなる問題ですね）。