環境

Fedora Core 17 + LVM。だいぶ古いので今はいろいろ変わってるかも
調査

$ dmesg | grep 'I/O error'
[6521704.184690] end_request: I/O error, dev sda, sector 786585316
[6521720.970194] end_request: I/O error, dev sda, sector 786585316
[6608118.470251] end_request: I/O error, dev sda, sector 811570694
[6608137.233774] end_request: I/O error, dev sda, sector 811570694
sdaの調子が悪そうだ
sdaに乗っているパーティションは
$ sudo pvdisplay -m
--- Physical volume ---
PV Name /dev/sdb2
VG Name vg_scraper2
PV Size 67.88 GiB / not usable 2.00 MiB
Allocatable yes (but full)
PE Size 32.00 MiB
Total PE 2172
Free PE 0
Allocated PE 2172
PV UUID y0SqXG-zK9P-2iI9-LO8c-MyWS-pHhv-Yq3e3c
--- Physical Segments ---
Physical extent 0 to 125:
Logical volume /dev/vg_scraper2/lv_swap
Logical extents 0 to 125
Physical extent 126 to 807:
Logical volume /dev/vg_scraper2/lv_home
Logical extents 0 to 681
Physical extent 808 to 2171:
Logical volume /dev/vg_scraper2/lv_root
Logical extents 0 to 1363
--- Physical volume ---
PV Name /dev/sda
VG Name vg_scraper2
PV Size 698.64 GiB / not usable 12.87 MiB
Allocatable yes
PE Size 32.00 MiB
Total PE 22356
Free PE 6226
Allocated PE 16130
PV UUID DPYlxx-y8oe-YSMb-ReXI-lt6G-46al-NU2EB5
--- Physical Segments ---
Physical extent 0 to 15999:
Logical volume /dev/vg_scraper2/lv_home
Logical extents 682 to 16681
Physical extent 16000 to 16129:
Logical volume /dev/vg_scraper2/lv_swap
Logical extents 126 to 255
Physical extent 16130 to 22355:
FREE
なので、/homeとswap。
初期対応

スワップ領域で不良セクタが出るとOSが落ちそうなので、スワップを切る
$ sudo swapoff -v -a
swapoff on /dev/mapper/vg_scraper2-lv_swap
HDDに負荷をかけないように、定期バックアップは止める。
$ sudo crontab -e
/home以下を手元に軽くバックアップ -> q:\_scraper_backup
メンテナンス手順

HDDを増設 (ダウンタイム)

- 増設スペースがないので、ケースを開けっ放しの状態でやる
- 一応、養生テープで固定くらいはした
- 接続したポートをBIOSで有効にした
HDD交換準備 (サービス動かしながら)

- 最初にディスクIDの確認。HDDのモデル名・シリアル番号を元に探す。
$ ls -l /dev/disk/by-id
...
lrwxrwxrwx 1 root root 9 Sep 9 11:35 ata-ST1000DM003-9YN162_W1D06SMB -> ../../sdb
...
- 今回は/dev/sdbに割り当てられている。以降のコマンドで/dev/sdbと表示されるので把握しておく。
# badblocks -s -v -w /dev/disk/by-id/ata-ST1000DM003-9YN162_W1D06SMB
Checking for bad blocks in read-write mode
From block 0 to 976762583
Testing with pattern 0xaa: done
Reading and comparing: done
Testing with pattern 0x55: done
Reading and comparing: done
Testing with pattern 0xff: done
Reading and comparing: done
Testing with pattern 0x00: done
Reading and comparing: done
Pass completed, 0 bad blocks found. (0/0/0 errors)
- 長時間かかるので帰宅前に実行
- 4重チェックなので、pattern 0x55の途中で止めてもいいと思う
# pvcreate /dev/disk/by-id/ata-ST1000DM003-9YN162_W1D06SMB
# vgextend vg_scraper2 /dev/disk/by-id/ata-ST1000DM003-9YN162_W1D06SMB
# 確認
# pvdisplay
# vgdisplay -v vg_scraper2
- LV(lv_home_2)を新規作成。故障したHDDの領域を使わないように注意。確保元のPVを明示的に指定する
# lvcreate -L 500G -n lv_home_2 vg_scraper2 /dev/disk/by-id/ata-ST1000DM003-9YN162_W1D06SMB
# lv_home_2が確保された場所を確認
# lvdisplay -m vg_scraper2/lv_home_2
- swapは既存のを消して同じ名前で新しいディスクに作成
# swapoff /dev/vg_scraper2/lv_swap
# lvremove vg_scraper2/lv_swap
# lvcreate -L 8G -n lv_swap vg_scraper2 /dev/disk/by-id/ata-ST1000DM003-9YN162_W1D06SMB
# mkswap /dev/vg_scraper2/lv_swap
# swapon /dev/vg_scraper2/lv_swap
# swapの確保場所と、有効になったことを確認
# lvdisplay -m vg_scraper2/lv_swap
# cat /proc/swaps
- ファイルシステムを作成、/home_newにマウント
# mkfs.ext4 /dev/mapper/vg_scraper2-lv_home_2
# vim /etc/fstab
/dev/mapper/vg_scraper2-lv_home_2 /home_new ext4 defaults 1 2
# mkdir /home_new
# mount /home_new
データコピー・旧HDD取り外し (ダウンタイム)

# vim /etc/ssh/sshd_config
PermitRootLogin yes
# service sshd restart
- シングルユーザーモードに入る (ここだけサーバのコンソールで直接作業)
# systemctl rescue
# systemctl start sshd.service
- /home を新しいボリュームにコピー。オーナーやパーミッションを維持
- でかくて不要なものは削除
- 小さくて重要なものは優先でコピー
- 残りを全てコピー
# nohup cp --archive /home/* /home_new &> /home_new/cp.log &
- /etc/fstabを書き換え、新しい方の/homeを使うように変更
# /dev/mapper/vg_scraper2-lv_home /home ext4 defaults 1 2
/dev/mapper/vg_scraper2-lv_home_2 /home ext4 defaults 1 2
# lvchange --available n vg_scraper2/lv_home
- 普通はlvremove, pvremoveするようだけど、何かあったときに旧HDDを再接続して中身を見られるようにしたいのでやらない
- うまくいくかは不明。再接続したら認識してくれるかな?
おまけ: ルートパーティションのバックアップを取っておいた

# lvcreate -L 43G -n lv_root_backup vg_scraper2 /dev/disk/by-id/ata-ST1000DM003-9YN162_W1D06SMB
# mount -o remount,ro /dev/vg_scraper2/lv_root
# dd if=/dev/vg_scraper2/lv_root of=/dev/vg_scraper2/lv_root_backup bs=16M &
# disown
あまり更新しないサーバなので、古いバックアップでもセットアップの手間は省けそう。
これとDBのレストアである程度元に戻りそう。