『Linux/debian』 zfsでトラブル poolのエラーでマシンが起動できなくなったときの対処法

昨日、ファイルサーバーのバックアップを走らせたまま寝て、本日起床したところ、サーバーマシンがおかしい。
BIOS画面が立ち上がる前の段階でリブートをくり返しているぽい。

このような場合は、CPUファンが問題なことが多いので確認してみたところ、ファンはきちんと動いているようだ。
それでもおかしいので、同じCPUとファンが残っていたため、それらに置き換えて再起動。
ここで無事に立ち上がったのだが、立ち上げシーケンス中にzfsサービスを起動するところで止まってしまう。

starting zfs subfilesystem swap

と出たところで止まる。
USBキーボードを抜き差ししたり、電源ボタンを押したりするとログが出るので、ハングアップはしていない。

起動デバイスのSSDを別マシンにつないで起動させてみたところ、起動した。
→SSDにトラブル発生では無い

ここで考えられるのは、snapshotの転送中に電源が落ちたため、poolが壊れて起動時にチェックシーケンスが走っていること。
と言うことは、しばらく放置しておけば起動しそうだが起動する気配が無いので対策を考えることに。

raidzを組んでいたため、Diskを1台または2台つないだ状態で起動させたら起動した。
色々組み合わせを変えても2台までなら起動するが、3台になると起動しない。

ぶっちゃけ、まだバックアップが作成されていない状況なのでおかしくなったバックアップ先のプールを削除して、一から作り直しても問題ない。
その様なときにどうやってpoolを削除するか。
つまりは、FAULTED状態でアクセス出来ないpoolの削除の仕方です。
答えは、export。

zpool export vol2

でOK。
このあと、Diskを3台つないで起動させたら無事に起動しました。

poolを再作成するときは、

zpool create vol2 -f raidz ada4 ada5 ada6

-fオプションが必要でした。

ファイルが沢山存在する状態など、poolを再作成できない場合ですが、Disk2台つないだ状態で起動させたら、resilver状態になったので、2台の状態でDiskの同期が終わったら3台目をつないで、再度resilverって手順で戻るのでは無いかと予想しています。

しかし、なぜ再起動を繰り返すようになったのかが解っていない。
ログも残っていないし。

『Linux/Debian』 zfsファイルシステムのsnapshotを取ったり適当に間引いたりするスクリプトを造った

運用をはじめたzfsなファイルサーバーですが、zfsの大きな特徴の一つにsnapshot機能があります。
詳しい説明はちゃんと開設したサイトで調べて欲しいところですが、私が理解しているところのメリットは
・ファイルを操作した履歴を残せる(解りやすく言えば、AppleのTimeMachineみたいなヤツ、削除したファイルを復活させたりできる)
・別Disk、別マシーンにバックアップを取るときにはsnapshot機能を使うと素敵な状態になる
です。

snapshotを使ってバックアップと言われるのは、履歴を残せることだと思っているのですが、同じDiskにバックアップを残してもそれはバックアップじゃないので、別にバックアップは取っておく必要はありますね。

snapshotを取る戦略として
1.1時間おきにsnapshotを取る
2.ファイルサーバーは24時間運用では無い。電源のON/OFFあり
2.翌日になったら、その日から見て直近のサーバーが動いていた日にちのsnapshotは、その日のうちの一番新しいsnapshotのみを残して削除する
3.毎週日曜日に、その週の前の日曜日を起点に古い分6日分のsnapshotを削除する
4.毎月1日に、先々月のsnapshotを一番新しいsnapshot以外削除する。
5.毎月1日に、8ヶ月前のsnapshotを削除する。
としました。

ファイルサーバーが動いていない日にちがある可能性を考えると、3,4の条件はもうちょっと細かくしてやらないとダメなのですが、そこはanacronを入れてやることでカバーできる部分はカバーしてもらって、あとは手動運用で何とかする方針です。
基本的には、1週間以上サーバーの電源を落とす事は希なはず(盆と正月くらい)って前提です。

この方針で、
・当日は1時間おきのsnapshotが作られる。
・前日より前の1週間分は、1日分のsnapshotが残る
・1~4週間分は日曜日時点のsnapshotが残る
・2~7ヶ月前の月末に近い日曜日のsnapshotが残る
ことになるので、誤ってファイルを消しちゃった場合のカバーはできるかなと。
ぶっちゃけ、個人ユースなら1時間おきのsnapshotを60こ位残しておけば十分だと思うんですがね

以上の方針でスクリプトを作りました。
本当は誰かが公開しているものをそのまま使おうと思ったのですが、自分にぴったりのモノがなかったので書きました。
それぞれ、/etc/cron.hourly、/etc/cron.daily、/etc/cron.weekly、/etc/cron.monthlyに放り込んでおきます。
/etc/cron.*ディレクトリに置いておくファイル名は、”.”を含んだファイルは実行されないんですね。
hogehoge.shって名前にしていてcronで実行されずにものすごく悩みました。

もしかしたら、似たような運用をしたい人が居るかもしれないので、スクリプトを公開しておきます。
rubyスクリプトです。
githubで公開するのが今時なんだと思いますが、アカウント持っていないので貼り付けます(汗

ちょっと冗長なところ等があったりしますが、何かの参考になれば。

/etc/cron.hourly/zfs_snapshot_hourly
[bash]
#!/bin/bash

zfs snapshot -r vol1/pub1@`date ‘+%Y%m%d-%H%M’`
zfs snapshot -r vol1/pub2@`date ‘+%Y%m%d-%H%M’`
[/bash]
これだけはbashスクリプトです。
他のDiskへバックアップを取るvol1/pub1とバックアップを取らないvol1/pub2に分けて、それぞれsnapshotを取ることにしています。

/etc/cron.daily/zfs_snapshot_daily
[ruby]
#!/usr/bin/ruby
#本日より前で最も近い日にちのsnapshotについて、
#その当日内で最も時間的に新しいsnapshoto以外を
#削除する

require “open3”

#zfs snapshot一覧を取得
stdin,stdout,stderr = Open3.capture2(‘zfs list -o name -S creation -t snapshot’)
snapshot_list = stdin.split(“n”)
snapshot_list.delete_at(0)

#処理対象のsnapshot listを作成
#処理対象日を絞り込む
require “date”
today = Date.today
beforeday = today – 1
beforeday_str = beforeday.strftime(“%Y%m%d”)

target_day_flag = false
while !target_day_flag do
snapshot_list.each do |s|
target_day_flag = target_day_flag | s.include?(beforeday_str)
end
if !target_day_flag then
beforeday = beforeday – 1
end
beforeday_str = beforeday.strftime(“%Y%m%d”)

end

#処理対象のリストをpub1とpub2でそれぞれ造る
def extract_target_snapshot_list(list, target_name)
l = Array.new
list.each do |s|
if s.include?(target_name) then
l.push(s)
end
end
return l
end

pub1_snapshot_list = Array.new
pub1_snapshot_list = extract_target_snapshot_list(snapshot_list,”vol1/pub1@”+beforeday_str)

pub2_snapshot_list = Array.new
pub2_snapshot_list = extract_target_snapshot_list(snapshot_list,”vol1/pub2@”+beforeday_str)

#リストを整理して、一番新しい時間だけを除く
pub1_snapshot_list.sort!
pub1_snapshot_list.pop
pub2_snapshot_list.sort!
pub2_snapshot_list.pop

#削除対象snapshotを削除する

if !pub1_snapshot_list.empty? then
pub1_snapshot_list.each do |s|
stdin,stdout,stderr = Open3.capture2(‘zfs destroy ‘+s)
end
end

if !pub2_snapshot_list.empty? then
pub2_snapshot_list.each do |s|
stdin,stdout,stderr = Open3.capture2(‘zfs destroy ‘+s)
end
end
[/ruby]

/etc/cron.weekly/zfs_snapshot_weekly
[ruby]
#!/usr/bin/ruby
# -*- coding: utf-8 -*-
#日曜日に実行されることが前提
#実行された日にちが含む週(日曜日始まり)の前の週の
#日曜日を基準に、その日から前の月曜日までの
#snapshotを削除する

require “open3”

#zfs snapshot一覧を取得
stdin,stdout,stderr = Open3.capture2(‘zfs list -o name -S creation -t snapshot’)
snapshot_list = stdin.split(“n”)
snapshot_list.delete_at(0)

#処理対象のsnapshot listを作成
#処理対象日を絞り込む
require “date”
this_week = Date.today

#直近の日曜日を探す
while !this_week.sunday? do
this_week = this_week -1
end

#処理開始の起点はその前の日曜日
last_week = this_week – 7

#処理対象のリストをpub1とpub2でそれぞれ造る
#volume_name 対象ファイルシステム、最後に@はつけない
def extract_target_snapshot_list(list, volume_name, startpoint)
l = Array.new
for i in 1..6 do
w_date = startpoint – i;
d_string = w_date.strftime(“%Y%m%d”)
list.each do |s|
if s.include?(volume_name+”@”+d_string) then
l.push(s)
end
end
end
return l
end

pub1_snapshot_list = Array.new
pub1_snapshot_list = extract_target_snapshot_list(snapshot_list,”vol1/pub1″, last_week)

pub2_snapshot_list = Array.new
pub2_snapshot_list = extract_target_snapshot_list(snapshot_list,”vol1/pub2″, last_week)

#削除対象snapshotを削除する

if !pub1_snapshot_list.empty? then
pub1_snapshot_list.each do |s|
stdin,stdout,stderr = Open3.capture2(‘zfs destroy ‘+s)
end
end

if !pub2_snapshot_list.empty? then
pub2_snapshot_list.each do |s|
stdin,stdout,stderr = Open3.capture2(‘zfs destroy ‘+s)
end
end
[/ruby]

/etc/cron.monthly/zfs_snapshot_monthly
[ruby]
#!/usr/bin/ruby
# -*- coding: utf-8 -*-
#毎月第1日に実行されることが前提
#実行された月の先々月のsnapshtについて、
#一番新しいもの以外削除する

#プラス
#6ヶ月分を残して、残りのスナップショットは削除する

require “open3”

#zfs snapshot一覧を取得
stdin,stdout,stderr = Open3.capture2(‘zfs list -o name -S creation -t snapshot’)
snapshot_list = stdin.split(“n”)
snapshot_list.delete_at(0)

#処理対象のsnapshot listを作成
#処理対象日を絞り込む
require “date”
today = Date.today

#先々月の日付を取得する
target_month = today << 2 target_month_str = target_month.strftime("%Y%m"); #処理対象のリストをpub1とpub2でそれぞれ造る #volume_name 対象ファイルシステム、最後に@はつけない def extract_target_snapshot_list(list, volume_name, start_point) l = Array.new list.each do |s| if s.include?(volume_name+"@"+start_point) then l.push(s) end end return l end pub1_snapshot_list = Array.new pub1_snapshot_list = extract_target_snapshot_list(snapshot_list,"vol1/pub1", target_month_str) pub2_snapshot_list = Array.new pub2_snapshot_list = extract_target_snapshot_list(snapshot_list,"vol1/pub2", target_month_str) #リストを整理して、一番新しい時間だけを除く pub1_snapshot_list.sort! pub1_snapshot_list.pop pub2_snapshot_list.sort! pub2_snapshot_list.pop #削除対象snapshotを削除する if !pub1_snapshot_list.empty? then pub1_snapshot_list.each do |s| stdin,stdout,stderr = Open3.capture2('zfs destroy '+s) end end if !pub2_snapshot_list.empty? then pub2_snapshot_list.each do |s| stdin,stdout,stderr = Open3.capture2('zfs destroy '+s) end end #8ヶ月前のsnapshotを削除する target_month = today << 8 target_month_str = target_month.strftime("%Y%m"); eight_month_ago__snapshot_list = Array.new snapshot_list.each do |s| if s.include?(target_month_str) then eight_month_ago__snapshot_list.push(s) end end if !eight_month_ago__snapshot_list.empty? then eight_month_ago__snapshot_list.each do |s| stdin,stdout,stderr = Open3.capture2('zfs destroy '+s) end end [/ruby]

『Linux/Debian』 3TBのHDDを3台購入して、zfsなファイルサーバーを作成した

今月頭から継続していましたが、zfsなファイルサーバーを構築して正式運用しました。

zfsなサーバーを構築する手段として、既存サーバーのHDDをやりくりして新サーバー用のHDDを捻出する方法もできたのですが、面倒くさすぎてしょうが無かったので、HDDを新規購入しました。

IMG_0330
Western DigitalのWD Red 3TBを3台購入しました。

zfsなサーバーの構築方法層のものは以前も書いたのでパスして、実際にサーバーを構築してみると、1台あたりの容量は2.7TB。
これ、1k=1000でサイズを表すか、1K=1024でサイズを表すかの違いからでいる話で、コンピュータ内部では1K=1024で処理するところをパッケージ表記ではマーケティング要因でサイズを大きく見せるために1k=1000で処理している為から来るギャップだと認識しています。
が、サイズが大きくなるにつれて益々ギャップが大きくなるため、どこかで治さないとダメだとともうんですよね。
普通はこんな事が解らないので、クレームが出る可能性も高いですし。

LinuxサーバーからFreeBSDサーバーへのデータ移動手段

で、サーバーを構築したあとにデータを移送する手段ですが2種類考えられて
1.LinuxのディスクをFreeBSDでマウントしてコピー
2.ネットワーク経由でコピー(rsyncやscpを使う)
のどちらかになると思われます。
#機材があればテープとかも・・・

1番の手段が一番シンプルかつ楽そうですが、以下の理由からこの手段は実行できませんでした
○ext4ファイルシステムをマウントできない
まず、ext4ファイルシステムをFreeBSDがサポートしていません。
ext4fuseってツールを入れたらマウントできるようなことが調べたら出てきたのですが、Debian/kFreeBSDだとaptでインストール出来なかったので、ソースからコンパイルして試しました。
が、ビルドはできるもののマウントさせてみたらエラーが出てマウントできず断念。

○ext2ファイルシステムのDISKを用意してマウントさせてみるものの、正常にファイルコピーできず断念
マウントはできたのですが、ファイルコピー時にIOエラーが出まくってコピーできなかったパターンと、
マウントをしようとしたら、「そんなデバイスはありません」って出てきて詰むパターンが発生して終了。
Debian/kFreeBSDだからアカンのか?

最終的には、rsyncを利用してデータ移動をしました。
4TB位のデータがあったのですが、3~4日間、夜間を利用してデータ移動できました。
かなりの時間が掛かるかと思ったので、ネットワーク経由を試すのは最終手段としたのですが、この程度で終わるなら初めからネットワーク経由で良かったなと思いましたよ。

WD 内蔵HDD Red 3TB 3.5inch SATA3.0 64MB IntelliPower WD30EFRX
Western Digital
売り上げランキング: 305

『Linux/debian』  Apache+PHP環境でなぜかユーザーディレクトリでPHPを実行できない

さくらVPSにDebianをインストールしてWebサーバーを立ち上げたのですが、ユーザーディレクトリでPHPが動かないという謎現象に悩まされました。

色々と調べた結果、デフォルトの状態ではユーザーディレクトリでPHPを動かないようにしているのでした。
Life is something else. - DebianにApache 2 + MySQL + PHPをインストール
こちらのページに書かれているとおり、
/etc/apache2/mods-available/php5.conf
を編集したところ、無事に動きました。

これで4時間くらいはまり込んでしまいました。

[linux/Debian] Debian/kFreeBSDでZFS メモリパラメータの設定

今まででZFSを使う準備はできているのですが、快適にというか、安全に使おうと思ったらもうちょっと設定が必要。

404 Blog Not Found 備忘録 – HP ProLiant MicroServer + FreeBSD + ZFS
にもあるように、ZFSが使うメモリサイズを指定しておきたい。
デフォルトの設定のままだと、メモリを使いすぎてカーネルごと落ちてしまうことがあるらしい。
メモリが溢れるまでの状態になるのは、ZFSの重複排除(dedup)を有効にした場合のようなので、普通に使っていると問題無さそうですが。

で、FreeBSDだと、/boot/loader.confを編集したら良いみたいですが、Debian/kFreeBSDだとそんなファイルはありません。

色々調べてみても全く情報が無い。
でも、全く情報が無いわけでは無く、探してみたら見つかりました。

/etc/grub.d/10_kfreebsdファイルで設定します。

設定前

# sysctl -a | grep arc_max
vfs.zfs.arc_max: 7229382656

/etc/grub.d/10_kfreebsdファイルの最後に
set kFreeBSD.vfs.zfs.arc_max=”4G”
を追加してやります。

# vim /etc/grub.d/10_kfreebsd
set kFreeBSD.vfs.zfs.arc_max=”4G”

必要なら他のパラメータも設定してやりましょう。

ファイル修正後、

# update-grub
# reboot

再起動した後に確認すると、

# sysctl -a | grep arc_max
vfs.zfs.arc_max: 4294967296

設定が変更されていることが解ります。

サンワサプライ 下L型シリアルATA3ケーブル 0.5m TK-SATA3-05SL
サンワサプライ
売り上げランキング: 95

[linux/Debian] 接続されているHDDの一覧と、シリアル番号を確認する方法

NASで沢山HDDを接続していると、いざDiskを交換するときにどれを交換したら良いのやらって事になります。
そこで、あらかじめそれぞれのHDDのシリアル番号と、HDDが接続されているポートをメモしておけば、交換するときに役に立ちます。

HDDのシリアル番号の確認方法は、HDDのラベルを直接見る方法が確実ですが、既に装着済みだったらどうするかって事になります。
その時は、smartctlを使いましょう。

# smartctl -a /dev/sda
smartctl 5.41 2011-06-09 r3365 [i686-linux-3.6.11] (local build)
Copyright (C) 2002-11 by Bruce Allen, http://smartmontools.sourceforge.net

=== START OF INFORMATION SECTION ===
Model Family: Kingston branded X25-V SSDs
Device Model: KINGSTON SSDNow 40GB
Serial Number: XXXXXXXXXXXXXX
LU WWN Device Id: 5 001517 9590d8db8
Firmware Version: 2CV102HA

といった感じで表示されます。FreeBSDなら、/dev/ada0とか指定してやります。
他に簡単に確認出来る方法はあるのかな?

次に、各HDDがどのデバイスに割り当たってるかの確認ですが、
Linuxの場合は、

cat /proc/scsi/scsi
Attached devices:
Host: scsi2 Channel: 00 Id: 00 Lun: 00
Vendor: ATA Model: KINGSTON SSDNow Rev: 2CV1
Type: Direct-Access ANSI SCSI revision: 05
Host: scsi3 Channel: 00 Id: 00 Lun: 00
Vendor: ATA Model: ST2000DM001-1ER1 Rev: CC43
Type: Direct-Access ANSI SCSI revision: 05
・・・・

と表示される前から順番に、sda、sdb・・・と割当たっているようです。
もっと、直接的に解る方法はないのかな。

FreeBSDだと、

# camcontrol devlist
<INTEL SSDSA2M080G2GC 2CV102HD> at scbus0 target 0 lun 0 (ada0,pass0)
<ST3320620AS 3.AAK> at scbus3 target 0 lun 0 (ada1,pass1)

camcontrolコマンドで直ぐ解るようになっています。

/dev/sdaがどのハードデスクで、シリアル番号まで解っていたら、いざ/dev/sdaが壊れた時に、どのHDDが壊れたかシリアル番号で確認出来て、それを基にHDD交換ができるので、確実になります。

サンワサプライ 下L型シリアルATA3ケーブル 0.5m TK-SATA3-05SL
サンワサプライ
売り上げランキング: 72

[linux/Debian] Debian/kFreeBSDでZFS お試し編 その2

ZFSをVirtualBoxに入れたDEbian/kFreeBSDで試してみるのその2です。
Diskが壊れた時の交換方法と、大きいDiskに交換していって、領域を確認する方法を確認します。

1GBのアレイが順番に壊れたり、交換していく想定で、交換するのは3GBのDiskです。

まずは1台交換してみる

いきなり抜くのでは無く、offlineにしてDiskを交換してみます。
これは、大きいHDDに交換するときの手順を想定しています。

# zpool offline vol1 ada1

# zpool status
pool: vol1
state: DEGRADED
status: One or more devices has been taken offline by the administrator.
Sufficient replicas exist for the pool to continue functioning in a
degraded state.
action: Online the device using ‘zpool online’ or replace the device with
‘zpool replace’.
scan: none requested
config:

NAME STATE READ WRITE CKSUM
vol1 DEGRADED 0 0 0
-0 DEGRADED 0 0 0
13334899667277329527 OFFLINE 0 0 0 was /dev/ada1
ada2 ONLINE 0 0 0
ada3 ONLINE 0 0 0
-1 ONLINE 0 0 0
ada4 ONLINE 0 0 0
ada5 ONLINE 0 0 0
ada6 ONLINE 0 0 0

errors: No known data errors

ada1がofflineになって、プールがDegradedになっているのが確認出来ます。

HDD付け替え

電源を落としてDiskを同じ所に付け替えます。
Diskのサイズは3GBです。

電源ONにしたあと、

# zpool online vol1 ada1
warning: device ‘ada1’ onlined, but remains in faulted state
use ‘zpool replace’ to replace devices that are no longer present
# zpool status
pool: vol1
state: DEGRADED
status: One or more devices could not be used because the label is missing or
invalid. Sufficient replicas exist for the pool to continue
functioning in a degraded state.
action: Replace the device using ‘zpool replace’.
see: http://www.sun.com/msg/ZFS-8000-4J
scan: scrub repaired 0 in 0h0m with 0 errors on Sun Aug 3 01:36:22 2014
config:

NAME STATE READ WRITE CKSUM
vol1 DEGRADED 0 0 0
-0 DEGRADED 0 0 0
13334899667277329527 UNAVAIL 0 0 0 was /dev/ada1
ada2 ONLINE 0 0 0
ada3 ONLINE 0 0 0
-1 ONLINE 0 0 0
ada4 ONLINE 0 0 0
ada5 ONLINE 0 0 0
ada6 ONLINE 0 0 0

errors: No known data errors

onleineにしただけでは、まだDegradedのままです。

# zpool replace vol1 ada1
# zpool status
pool: vol1
state: ONLINE
scan: resilvered 64.5K in 0h0m with 0 errors on Sun Aug 3 01:37:33 2014
config:

NAME STATE READ WRITE CKSUM
vol1 ONLINE 0 0 0
-0 ONLINE 0 0 0
ada1 ONLINE 0 0 0
ada2 ONLINE 0 0 0
ada3 ONLINE 0 0 0
-1 ONLINE 0 0 0
ada4 ONLINE 0 0 0
ada5 ONLINE 0 0 0
ada6 ONLINE 0 0 0

errors: No known data errors

# zpool list
NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT
vol1 8.95G 290K 8.95G 0% 1.00x ONLINE –

zpool replaceをしてはじめてプールが回復します。
1GBのRAID-Zアレイのうち、1台を3GBにしたままでは、まだサイズは増えていません。

2台目はいきなりHDDを交換してみる

今度は、Diskが壊れたことを想定して、いきなりHDDを交換します。
これも3GBのDiskに交換しました。

# zpool status
pool: vol1
state: DEGRADED
status: One or more devices could not be opened. Sufficient replicas exist for
the pool to continue functioning in a degraded state.
action: Attach the missing device and online it using ‘zpool online’.
see: http://www.sun.com/msg/ZFS-8000-2Q
scan: resilvered 64.5K in 0h0m with 0 errors on Sun Aug 3 01:37:33 2014
config:

NAME STATE READ WRITE CKSUM
vol1 DEGRADED 0 0 0
-0 DEGRADED 0 0 0
ada1 ONLINE 0 0 0
18306556529790232082 UNAVAIL 0 0 0 was /dev/ada2
ada3 ONLINE 0 0 0
-1 ONLINE 0 0 0
ada4 ONLINE 0 0 0
ada5 ONLINE 0 0 0
ada6 ONLINE 0 0 0

errors: No known data errors

# zpool replace vol1 ada2
root@debian:/home/bayashi# zpool status
pool: vol1
state: ONLINE
scan: resilvered 59.5K in 0h0m with 0 errors on Sun Aug 3 01:42:43 2014
config:

NAME STATE READ WRITE CKSUM
vol1 ONLINE 0 0 0
-0 ONLINE 0 0 0
ada1 ONLINE 0 0 0
ada2 ONLINE 0 0 0
ada3 ONLINE 0 0 0
-1 ONLINE 0 0 0
ada4 ONLINE 0 0 0
ada5 ONLINE 0 0 0
ada6 ONLINE 0 0 0

errors: No known data errors

特に問題は無いですね。

ファイルが無い状態でDisk交換していても実感が無いので、ファイルを作っておきます。

# dd if=/dev/zero of=/vol1/work.img bs=1M count=800
# zpool list
NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT
vol1 8.95G 1.17G 7.78G 13% 1.00x ONLINE –

800MBのファイルを作ったけれども、実際に使われているのは1.17GB。パリティ分もあわせたサイズになっています。

3台目も交換して、プールサイズを拡張する

3台目も交換します。

# zpool replace vol1 ada3
root@debian:/home/bayashi# zpool status
pool: vol1
state: ONLINE
scan: resilvered 182M in 0h0m with 0 errors on Sun Aug 3 01:50:23 2014
config:

NAME STATE READ WRITE CKSUM
vol1 ONLINE 0 0 0
-0 ONLINE 0 0 0
ada1 ONLINE 0 0 0
ada2 ONLINE 0 0 0
ada3 ONLINE 0 0 0
-1 ONLINE 0 0 0
ada4 ONLINE 0 0 0
ada5 ONLINE 0 0 0
ada6 ONLINE 0 0 0

errors: No known data errors

# zpool list
NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT
vol1 8.95G 1.17G 7.78G 13% 1.00x ONLINE –

1GBのDiskがすべて3GBになったのに、プールのサイズが増えていません。

# zpool online -e vol1 ada1
# zpool list
NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT
vol1 15.0G 1.17G 13.8G 7% 1.00x ONLINE –
# zpool status
pool: vol1
state: ONLINE
scan: resilvered 182M in 0h0m with 0 errors on Sun Aug 3 01:50:23 2014
config:

NAME STATE READ WRITE CKSUM
vol1 ONLINE 0 0 0
-0 ONLINE 0 0 0
ada1 ONLINE 0 0 0
ada2 ONLINE 0 0 0
ada3 ONLINE 0 0 0
-1 ONLINE 0 0 0
ada4 ONLINE 0 0 0
ada5 ONLINE 0 0 0
ada6 ONLINE 0 0 0

errors: No known data errors

zpool online -eを実行してはじめてサイズが拡張されます。
指定するDiskは、拡張するアレイに属しているならどれでも良いみたいです。

あらかじめ、autoexpandを有効にしておくと、3台目が置き換わった時点で自動的にサイズ拡張されるようです(未確認)。

# zpool set autoexpand=on vol1

あるいは、プール作成時に

zpool create -o autoexpand=on vol1 raidz ada1 ada2 ada3

としておけば良いみたいです(未確認)。

この状態でdfコマンドを打ってみると、

# df -h
ファイルシス サイズ 使用 残り 使用% マウント位置
/dev/ada0s1 7.4G 853M 6.0G 13% /
devfs 1.0K 1.0K 0 100% /dev
linprocfs 4.0K 4.0K 0 100% /proc
/sys 4.0K 4.0K 0 100% /sys
fdescfs 1.0K 1.0K 0 100% /dev/fd
tmpfs 8.0G 212K 8.0G 1% /run
tmpfs 5.0M 4.0K 5.0M 1% /run/lock
tmpfs 1.6M 4.0K 1.6M 1% /run/shm
vol1 9.9G 800M 9.1G 8% /vol1
vol1/visual 9.1G 40K 9.1G 1% /vol1/visual

このような感じに。
vol1とvol1/visualのサイズと残りサイズをみると、ちょっと混乱しますな。

まとめ

これで、NAS運用に必要最低限な事は一通り確認出来ました。
しっかり運用するためには、snapshotの設定と、必要最低限なファイルのバックアップ戦略を立てることですね
ほかに、ZFSが利用するメモリ容量を制限したいのですが、Debian/kFreeBSDだとどこで設定するのかが解らない。

[linux/Debian] Debian/kFreeBSDでZFS お試し編 その1

ZFSをVirtualBoxに入れたDEbian/kFreeBSDで試してみるのその1です。

必要なツールのインストール

apt-get install zfsutils

Diskの確認

dmes | grep ada

とやると、

ada0 at ata0 bus 0 scbus0 target 0 lun 0
ada0: ATA-6 device
ada0: 100.000MB/s transfers (UDMA5, PIO 65536bytes)
ada0: 8192MB (16777216 512 byte sectors: 16H 63S/T 16383C)
ada0: Previously was known as ad0

とか出てくるので、確認。

パーティションがあるHDDは

gpart destroy -F ada2

とする必要があるらしい(未確認)

RAID-Zでプールの作成

1GBの仮想ハードディスクを3台つないでやる。
それぞれのドライブが、ada1、ada2、ada3と認識されているので、フォーマットをすることも無く

zpool create vol1 raidz ada1 ada2 ada3

でプールを作成。この時点で2GBの領域を確保。

このプールは/vol1に自動的にマウントされているので、後はそこに好き勝手にファイルを置いたり、ディレクトリを作成したりすれば良いのですが、バックアップ戦略とかで更にプールを分けることもできる。

zfs create vol1/visual

Diskを追加してプールを拡張する

ZFSでは、一旦構築したRAIDアレイにHDDを追加することはできない仕組みになっている。
なので、追加のHDDはストライプ構成で追加される。
なので、RAID-Zでプールを作ったのなら、HDDを追加するときもRAID-Zで追加していかないと、冗長性を確保出来ないことに。

それを踏まえてvol1にHDDを追加してみます。
2GBのHDDを追加で3台つないだとして、

zpool add vol1 raidz ada4 ada5 ada6

ステータスを確認すると、

# zpool list
NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT
vol1 8.95G 380K 8.95G 0% 1.00x ONLINE –

# zpool status
pool: vol1
state: ONLINE
scan: none requested
config:

NAME STATE READ WRITE CKSUM
vol1 ONLINE 0 0 0
-0 ONLINE 0 0 0
ada1 ONLINE 0 0 0
ada2 ONLINE 0 0 0
ada3 ONLINE 0 0 0
-1 ONLINE 0 0 0
ada4 ONLINE 0 0 0
ada5 ONLINE 0 0 0
ada6 ONLINE 0 0 0

vol1がストライプ構成になってると確認できる。

zpool listで表示されるのは、HDDの総量みたい。
1GB×3+2GB×3=9GB
実際に使えるサイズはdf -hかzfs listで確認できる(ログを残していないのです)。

これで、NASを構築する手順は確認出来ました。あとは、samba設定するくらいですね。

WD Red 3.5inch IntelliPower 3.0TB 64MBキャッシュ SATA3.0 WD30EFRX
Western Digital
売り上げランキング: 322

[linux/Debian] Debian/kfreebsdでZFS 準備編

はじめに

そのうちに、自宅ファイルサーバーをZFSを使った構成にしたいなと思っています。
主に耐故障性を向上させるためにです。

ZFSを使うには、
1.Solarisを使う
2.FreeBSDを使う
上記はZFSがシステムに組み込まれているので、そのまま使うことができます。
他に、
3.LinuxとZFS on LinuxのZFSを組み合わせて使う
と言う手段もあります。

色々考えた結果、FreeBSDで使うのが確実だろうという結論に達しました。

でも、FreeBSDはよく解らないので、Debian/kFreeBSDを使うことにしました。
カーネル部分はFreeBSDだけど、それ以外はDebianなので、Debian/GNU Linuxを使っている人には扱いやすい、らしい。

VirtualBoxにインストールして色々確認するのを目的としています。
ただ、OSインストールだけは空いてるマシンと使っていない80GBのSSDがあったので、それに入れて準備だけしました。

インストール

netinstなイメージを持ってきてインストールするのがいちばんラクでお手軽。
VirtualBoxでお試しインストール。
特に迷うところは無いのですが、日本語インストールにはまだ対応していないのね・・・。

インストール時には最低限必要なものだけ選択。ファイルサーバーだけ選べばOK。

おまけ。
実機ではUSBメモリからインストールする予定が、なんか解らないがUSBメモリからnetistなイメージがブートしない。
Debian GNU/LinuxのnetinstなISOイメージからはUSBブートできるのでUSB-CD ROMからインストール・・・。
が、USB-CD ROMからもインストール出来なかったので、内蔵CDROMドライブをつないでインストールしました。

インストール後の最低限必要な設定

インストール時にDHCPでIPアドレスを取得するようになってしまっているので、固定IPに変更。
設定はDebian GNU/Linuxと同じ。

# vi /etc/network/interface

auto lo0
iface lo0 inet loopback

# The primary network interface
auto re0
iface re0 inet static
address 192.168.xxx.yyy
netmask 255.255.255.0
gateway 192.168.xxx.zzz
dns-nameservers 192.168.xxx.zzz

aptをつかって、sshをインストール。

# apt-get install ssh

日本語ロケールの設定

# dpkg-reconfigure locales

でja_JP.UTF-8にチェック、デフォルトにして

# update-locale LANGUAGE=”ja_JP:ja” LANG=”ja_JP.UTF-8″

これで再起動させたら準備は完了

[linux/Debian] Linux Software RAID1のHDDが片方だけあるときにデータを読み出す方法

ちょっと調べてみたけれども、情報が少なかったのでメモを残しておきます。

LinuxでSoftwara RAID1を組んでいたとします。別にこれはRAID5でもかまいません。
で、片方のARRAIが壊れました。
あるいは、他のサーバーで運用していたRAIDアレイがあって、サーバーが壊れちゃった。デモデータを取り出したいとします。

その時、別マシンでどうやってデータを吸い出すか、と言う方法です。

調べてみたら新規にRAIDを組む方法の話はあっても、既存のRAID ARRAYを別マシンに移植するとか、そんな手順の情報が少ないんですよね。

で、以下の手順で行います。

1.RAIDの片割れのHDDをマシンにつなぎます。
2.つなげたHDDが/dev/sdbだったとして、RAIDを構成していたパーティションがsdb1だったとします。
3./dev/md0にRAIDが見えるようにします。
4.以下のコマンドを入力します

#> mdadm –assemble /dev/md0 /dev/sdb1

5./proc/mdstatを見て動いているのか確認

#> cat /proc/mdstat

6.適当なところにマウントしてデータを吸い出したりする。

自宅サーバーではRAID5を構築していないので確認はできなかったのですが、RAID5でも同じようにできると思います。


なんでこのような方法を調べていたのかというと、
自宅のファイルサーバーはRAID1で構成していて、なおかつ毎朝6時に別のHDDにデータをコピーする(rysncによるミラーリング)ことによって、ファイルの喪失を防ぐようにしています。
いちばん初めは、この3つのHDDは同じメーカーの同じ型番(仮にAA HDD)でした。

それが、まずは1台が壊れた(RAID1の片側)ので、ミラー用のHDDをRAIDアレイに持っていって、新しく買ったHDD(仮にBB HDD)をミラーリング用にしました。

すると、しばらくしたら、もう1台壊れました(RAID1の片側)。
この時点で代替HDDを手に入れようと思ったら、AA HDDは手に入るわけも無く。BB HDDは手に入る状態だったので、それを入手しました。

で、BB HDDでRAID1を組み直してAA HDDをミラーにしたいと思いました。
今の状況なら、新規にRAIDを作って、RAID状態のAA HDDからデータをコピーした後に、AA HDDのRAIDを解除してやればOKな訳ですが、
「これ、別マシンに移植するとかなったらどうやるんだ?昔、別マシンにつなげたときは勝手に認識したけど、毎回そんなわけじゃないし。」と思って調べたわけです。

ついでに書いておくと、LinuxのSoftware RAIDは異なるメーカの異なる型番のHDDでも関係なくRAIDを組めるのですが、RAIDを組むHDDのパーティションサイズは統一しておかないと色々と面倒くさそうです。

ちなみに、今回買ったのはSeagateのST2000DM001です。
以前買ったときには1万円近くの値段だったのですが、昨日の時点で、ツクモネット通販で7425円でした。
またHDDが安くなってきているのですかね?
今のところ、ファイルサーバーの構成は2TB/2.5TB/1TBの構成なのですが、1TBを引っこ抜いて3TBにしたいな~と思っています。
が、いつになったら実行できるか・・・