はじめに
今回、私達が管理しているオンプレミスサーバの容量が逼迫している問題が発生していました。
問題となっていたサーバはCentOS 7がプリインストールされており、これをそのまま運用していました。
このサーバのストレージ構成は
- /dev/sda (システム用 128 GB)
- /dev/sdb (データ保存用 6 TB)
となっています。プリインストールでの設定では
- /dev/sda1 (50 GB)にマウントポイント
/
- /dev/sdb1 (6 TB) にマウントポイント
/home
となっていて、DBなどが入っている/var
や/opt
が徐々に太っていき/dev/sda1
を逼迫させ、サーバエラーが起こるようになってしまいました。
また/home
はWebページのソースや個人のデータが入っているのですが、これは高々1 TBも使われておらず、ここが急激に増えるということはなさそうです。
そこで、/var
, /opt
を/dev/sda
から/dev/sdb
へお引越ししようということになりました。
その際に
-
/dev/sdb1
を3 TBに縮め - パーティションを切って
/dev/sdb2
を1 TB,/dev/sdb3
を2 TB分作り -
/var
,/opt
のデータを移し - マウントポイント
/var
を/dev/sdb3
,/opt
を/dev/sdb2
に設定する
という手順で移行を行います。また、大容量ストレージを扱うために/dev/sdb
はGPT形式でフォーマットされています。MBR形式と若干手順が異なるかもしれません。具体的には
-
gdisk
ではなくfdisk
を使う - GPTの場合、パーティションを切ったあと手でファイルシステム(フォーマット)をしなければならない
などがあります。
※ 本稿の通りにやってデータが失われてしまっても筆者は責任を負いません。必ず完全バックアップを取ってから行ってください。また、テスト環境でテストしてから行うことを推奨します。
SELinuxについて
マウントポイントを変更する作業を行うのですが、その際にSELinuxのラベリングを正しく設定しないといけないようです。
私はSELinuxに明るくなく、disable
した環境で行っておりますことをご了承ください。
パーティションを縮める
最初に/dev/sdb1
のパーティションを縮めます。
まずは/dev/sdb1
をアンマウントします。
# umount /dev/sdb1
次にファイルシステムのリサイズをします。
# e2fsck -f /dev/sdb1
# resize2fs /dev/sdb1 3000G
resize2fs 1.42.9 (28-Dec-2013)
Resizing the filesystem on /dev/sdb1 to 786432000 (4k) blocks.
resize2fs
はファイルシステムのサイズを変更するコマンドです。このコマンドではパーティションの操作は行いません。
これでパーティション内に散らばったデータをデフラグし、スーパーブロックの情報を変更します。これが結構時間かかります。
(参考: https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/storage_administration_guide/ext4grow)
ここで、出力されたリサイズ後のブロックサイズから、何バイト分の容量があるかを計算しておきます。
この例では1 block = 4 kB = 4096 Bですので、容量は
786432000 * 4096 = 3,221,225,472,000 B
となります。
次に、パーティションを縮めます。必ず/dev/sdb
がマウントされていないか確認し、parted
の対話モードを使ってパーティションのリサイズをします。
# parted /dev/sdb
(parted) unit b # 出力単位をByteにします
(parted) p # 現在の情報を出力
Model: ASR8405 RAID1-data (scsi)
Disk /dev/sdb: 5996837601280B
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1048576B 5996836552703B 5996835504128B ext4
ここで、/dev/sdb1
のスタートが1048576 Bであるので、先程出したサイズ(Byte)にスタートのオフセットを足して、Endの位置を計算します。
1,048,576 + 3,221,225,472,000 = 3,221,226,520,576 B
parted
の対話コンソールの続きです。
(parted) resizepart
Partition number? 1
End? [5996836552192B]? 3221226520576B
Warning: Shrinking a partition can cause data loss, are you sure you want to continue?
Yes/No? Yes # 前にファイルシステムのリサイズをしているので大丈夫
(parted) p
# 略
Disk Flags:
Number Start End Size File system Name Flags
1 1048576B 3221226521087B 3221225472512B ext4
(parted) q # サイズが正しく変更できたのを確認できたので、partedを終了
これで/dev/sdb1
が正しく縮まったことが確認できました。
新たにパーティションを切る
次は/dev/sdb2
を作ります。この作業にはgdisk
を使うことにします。parted
でも新しいパーティションを作れるのですが、Alignmentがうまく出来ませんでした。gdisk
はシームレスにAlignmentもやってくれるので、パーティション切りのときはこちらを使うことにしました。逆に、パーティションのリサイズはparted
でやるのが手っ取り早いです。
ここでは/dev/sdb2
をopt
として1 TB, /dev/sdb3
を/var
として2 TBあげることとします。
gdisk
の対話コマンドはHelpを参照してください。ここで使うコマンドはそれぞれ
-
n
: 新規パーティションを作成 -
c
: パーティション名の変更 -
p
: パーティションテーブルのプリント -
w
: パーティションの書き込み
で、w
を実行するまでは変更は書き込まれません。
# gdisk /dev/sdb
GPT fdisk (gdisk) version 0.8.10
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present
Found valid GPT with protective MBR; using GPT.
Command (? for help): n
Partition number (2-128, default 2): 2
First sector (34-11712573406, default = 6291460096) or {+-}size{KMGTP}:
Last sector (6291460096-11712573406, default = 11712573406) or {+-}size{KMGTP}: +1T
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300):
Changed type of partition to 'Linux filesystem'
Command (? for help): n
Partition number (3-128, default 3): 3
First sector (34-11712573406, default = 8438943744) or {+-}size{KMGTP}:
Last sector (8438943744-11712573406, default = 11712573406) or {+-}size{KMGTP}:
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300):
Changed type of partition to 'Linux filesystem'
Command (? for help): c
Partition number (1-3): 2
Enter name: opt
Command (? for help): c
Partition number (1-3): 3
Enter name: var
Command (? for help): p
Disk /dev/sdb: 11712573440 sectors, 5.5 TiB
Logical sector size: 512 bytes
Disk identifier (GUID): BE239631-679B-474D-B43A-305F9146AE5D
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 11712573406
Partitions will be aligned on 2048-sector boundaries
Total free space is 4061 sectors (2.0 MiB)
Number Start (sector) End (sector) Size Code Name
1 2048 6291458048 2.9 TiB 0700
2 6291460096 8438943743 1024.0 GiB 8300 opt
3 8438943744 11712573406 1.5 TiB 8300 var
Command (? for help): w
Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!
Do you want to proceed? (Y/N): Y
OK; writing new GUID partition table (GPT) to /dev/sdb.
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot.
The operation has completed successfully.
パーティションが切られましたので再起動し、デバイスを認識させます。
新たなパーティションのフォーマットをする
次に、新たに切ったパーティションをそれぞれext4
でフォーマットします。ext4
でフォーマットするのにはmkfs.ext4
コマンドを使用します。
# mkfs.ext4 /dev/sdb2
mke2fs 1.42.9 (28-Dec-2013)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
67108864 inodes, 268435456 blocks
13421772 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=2415919104
8192 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
102400000, 214990848
Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
# mkfs.ext4 /dev/sdb3
mke2fs 1.42.9 (28-Dec-2013)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
102301696 inodes, 409203707 blocks
20460185 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=2558525440
12488 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
102400000, 214990848
Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
これでフォーマットも完了です。
/var
, /opt
を新たに切ったパーティションに移す
データのコピー
まず、既存の(/dev/sda1
にある) /var
,/opt
にアクセスしているserviceがあると移行作業が行えないので、single user modeに入ります。
# init 1
今回の作業ではサーバを直で操作ではなく、ログ取りの関係上ssh経由で行っていたため、この作業のみ本体を直接触ってnetwork
,sshd
を起動させました。
# systemctl start network.service
# systemctl start sshd.service
次に、/dev/sdb2
,/dev/sdb3
を仮マウントして、現在の/opt
,/var
の中身をそれぞれコピーします。
# cd /mnt
# mkdir opt_new var_new
# mount /dev/sdb2 opt_new/
# mount /dev/sdb3 var_new/
# rsync -au /opt/* opt_new/
# rsync -au /var/* var_new/
これにて/dev/sda1
にあった/opt
が/dev/sdb2
に、 /dev/sda1
にあった/var
が/dev/sdb3
にコピーされました。
アンマウントし、念の為fsck
させます。
# umount /dev/sdb2
# umount /dev/sdb3
# e2fsck -f /dev/sdb2
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/sdb2: 312692/67108864 files (0.2% non-contiguous), 9517164/268435456 blocks
# e2fsck -f /dev/sdb3
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/sdb3: 231758/102301696 files (0.2% non-contiguous), 11135325/409203707 blocks
OKです。
マウント先のディレクトリを作成
次に、今の/opt
, /var
をそれぞれ/opt.org
, /var.org
に変更し、マウント先のディレクトリ/opt
,/var
を作ります。
# cd /
# mv opt opt.org
# mv var var.org
# mkdir opt var
/etc/fstab
の編集
次に/etc/fstab
を編集します。その前に、デバイスのUUIDの確認をします。簡単のため、UUIDは適当に分かりやすく変えていますので、適宜読み替えてください。
# ls -l /dev/disk/by-uuid/
total 0
lrwxrwxrwx 1 root root 10 Jul 2 14:51 33333333-3333-3333-3333-333333333333 -> ../../sdb3
lrwxrwxrwx 1 root root 10 Jul 2 14:51 22222222-2222-2222-2222-222222222222 -> ../../sdb2
lrwxrwxrwx 1 root root 10 Jul 2 14:23 11111111-1111-1111-1111-111111111111 -> ../../sdb1
確認が出来ましたら/etc/fstab
を編集して、/dev/sdb2
をマウントポイント/opt
に、/dev/sdb3
をマウントポイント/var
に指定します。
UUID=11111111-1111-1111-1111-111111111111 /home ext4 defaults 1 2
UUID=22222222-2222-2222-2222-222222222222 /opt ext4 defaults 1 2
UUID=33333333-3333-3333-3333-333333333333 /var ext4 defaults 1 2
これで再起動をかけます。
確認
起動したあとにdf
で確認です(関係あるところのみ抜粋)。
# df -Th
Filesystem Type Size Used Avail Use% Mounted on
/dev/sdb1 ext4 2.9T 676G 2.1T 25% /home
/dev/sdb2 ext4 1008G 21G 937G 3% /opt
/dev/sdb3 ext4 1.6T 18G 1.5T 2% /var
正常にマウントされております。
また、/opt
,/var
を使うサービス類も正しく動作出来ていることが確認できました。
最後に
この時代、クラウドでストレージも可変に組めるのであまりこういった危険な作業をすることも少なくなっているとは思いますが、やる機会がありましたらご参考ください。くれぐれもバックアップを忘れずに取って、ご安全に。