環境

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と表示されるので把握しておく。

  • 新HDDの不良セクタのチェック
# 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の途中で止めてもいいと思う

  • 新HDDをLVMの管理対象に
# 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取り外し (ダウンタイム)

  • sshでrootログインできるようにする
# vim /etc/ssh/sshd_config
  PermitRootLogin yes
# service sshd restart
  • シングルユーザーモードに入る (ここだけサーバのコンソールで直接作業)
# systemctl rescue
# systemctl start sshd.service
    • この後はrootのみsshでログインできる

  • /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

  • 旧HDDを切り離す
# lvchange --available n vg_scraper2/lv_home
    • シャットダウン
    • HDDを物理的に取り外す

  • 普通は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のレストアである程度元に戻りそう。