ZFS send/recvとnetcatを使ってネットワーク越しにZFSのデータを移行する
今回のサーバ更新では、ZFSからZFSへデータ移行をする必要があった。一般的にはrsyncやtarを使うんだろうけど、せっかくなのでZFSの機能を使って移行してみたら、かなり高速で快適だったのでメモ。
ZFSには、複製を作成するためのsend/recvという機能が用意されている。標準入出力を使ってデータをやりとりできるので、netcatを使ってネットワーク越しにつなぐことで、データを移行する。
まずは新サーバでの操作。netcatでネットワークからの入力を待ち受けて、標準出力へリダイレクトし、zfs recvで受信する。ポート番号は適当に選択する。受信するpoolはあらかじめ作成しておくこと。
# nc -l -p ポート番号 -w 120 | zfs recv -v pool/export@snapshot
次は、旧サーバでの操作。zfs sendはスナップショットしか送信できないので、スナップショットを作ってsendする。
# zfs snapshot pool/export@snapshot # zfs send pool/export@snapshot | nc 宛先IPアドレス ポート番号
あとは待つだけ。rsyncやtarに比べて、ファイルシステムを直に扱うためオーバーヘッドが少ない、何も考えなくてもファイル作成時刻などのメタデータがそのままコピーできる、旧サーバのsnapshotも移行しようと思えば移行できる、などいいことだらけなので、今後もサーバ更新の際はzfs send/recvを使うようにしよう。
追記
netcatは転送するデータを暗号化せず平文で流すので、家庭内LANなどの覗き見されないネットワーク環境で使うこと。
覗き見の可能性があるなら、素直にsshを使うのがお手軽。
FreeBSD 9.1-RELEASEでSSDのTRIM命令を有効にする
新しい自宅サーバでは、起動ドライブにSSDを使ってみた。SSDはHDDといろいろと違うところがあるけど、そのうちの一つにTRIM命令がある。
SSDは、HDDと違っていわゆる上書きができないため、上書きする場合は、書き込まれているデータをいったん待避して、その領域をまっさらにしてから書き戻すことになる。ところで、一般的なファイルシステムでは、ファイルを削除した場合、管理データだけ削除してディスク上のデータはそのまま残しておく作りになっていることが多い。すると、削除したファイルが使っていた領域は、OSではすでに不要になっているのに、SSDとしては不要かどうか分からないので、上書きの際にいちいち待避することになる。
OSがファイルを削除した際に、SSDに対して「この領域はもう使いませんよ」と教えてあげることができたら、このような非効率は発生しない。そのための命令がTRIM命令というわけ。
FreeBSDでもしばらく前からTRIM命令をサポートしてる。ただし、デフォルトでは無効になっているので、必要なファイルシステムに対してtunefsの-tオプションを使って有効にしてやる必要がある。
-t enable | disable Turn on/off the TRIM enable flag. If enabled, and if the under‐ lying device supports the BIO_DELETE command, the file system will send a delete request to the underlying device for each freed block. The trim enable flag is typically set when the underlying device uses flash-memory as the device can use the delete command to pre-zero or at least avoid copying blocks that have been deleted.
実際にはこんな感じ。マウントされていると変更できないので、memstickとかLiveCDを使って起動して変更すべし。
# tunefs -t enable /dev/ada4p2
有効になっているかどうかは、dumpfsを使って確認できる。flagsにtrimが入っていれば有効。
# dumpfs /dev/ada4p2 省略 flags soft-updates+journal trim 省略
ついでに/etc/fstabでnoatimeを指定して、atimeを無効にしておいた。これで書き込みが少なくなって、SSDの寿命が延びるはず。
HP ProLiant MicroServerのFreeBSD 9.1-RELEASE dmesg
参考に、HP ProLiant MicroServerをFreeBSD 9.1-RELEASEで動かしたときのdmesgを載せておく。
全てのデバイスは適切に認識されて、動作してる。NICはbgeで、options=c019b
SSDを接続したSATAポートは、光学ドライブ用のため150MB/sで動作してるけど、体感的に問題ないのでそのままにしてる。非公式BIOSを書き込めば、300MB/s動作させられるらしい。
Copyright (c) 1992-2012 The FreeBSD Project. Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 The Regents of the University of California. All rights reserved. FreeBSD is a registered trademark of The FreeBSD Foundation. FreeBSD 9.1-RELEASE #0 r243825: Tue Dec 4 09:23:10 UTC 2012 root@farrell.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC amd64 CPU: AMD Turion(tm) II Neo N40L Dual-Core Processor (1497.55-MHz K8-class CPU) Origin = "AuthenticAMD" Id = 0x100f63 Family = 10 Model = 6 Stepping = 3 Features=0x178bfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CLFLUSH,MMX,FXSR,SSE,SSE2,HTT> Features2=0x802009<SSE3,MON,CX16,POPCNT> AMD Features=0xee500800<SYSCALL,NX,MMX+,FFXSR,Page1GB,RDTSCP,LM,3DNow!+,3DNow!> AMD Features2=0x837ff<LAHF,CMP,SVM,ExtAPIC,CR8,ABM,SSE4A,MAS,Prefetch,OSVW,IBS,SKINIT,WDT,NodeId> TSC: P-state invariant real memory = 8589934592 (8192 MB) avail memory = 8111689728 (7735 MB) Event timer "LAPIC" quality 400 ACPI APIC Table: <HP ProLiant> FreeBSD/SMP: Multiprocessor System Detected: 2 CPUs FreeBSD/SMP: 1 package(s) x 2 core(s) cpu0 (BSP): APIC ID: 0 cpu1 (AP): APIC ID: 1 ioapic0 <Version 2.1> irqs 0-23 on motherboard kbd1 at kbdmux0 acpi0: <HP ProLiant> on motherboard acpi0: Power Button (fixed) acpi0: reservation of fee00000, 1000 (3) failed acpi0: reservation of ffb80000, 80000 (3) failed acpi0: reservation of fec10000, 20 (3) failed acpi0: reservation of fed80000, 1000 (3) failed acpi0: reservation of 0, a0000 (3) failed acpi0: reservation of 100000, d7f00000 (3) failed cpu0: <ACPI CPU> on acpi0 cpu1: <ACPI CPU> on acpi0 attimer0: <AT timer> port 0x40-0x43 irq 0 on acpi0 Timecounter "i8254" frequency 1193182 Hz quality 0 Event timer "i8254" frequency 1193182 Hz quality 100 atrtc0: <AT realtime clock> port 0x70-0x71 irq 8 on acpi0 Event timer "RTC" frequency 32768 Hz quality 0 hpet0: <High Precision Event Timer> iomem 0xfed00000-0xfed003ff on acpi0 Timecounter "HPET" frequency 14318180 Hz quality 950 Event timer "HPET" frequency 14318180 Hz quality 550 Event timer "HPET1" frequency 14318180 Hz quality 450 Timecounter "ACPI-safe" frequency 3579545 Hz quality 850 acpi_timer0: <32-bit timer at 3.579545MHz> port 0x808-0x80b on acpi0 pcib0: <ACPI Host-PCI bridge> port 0xcf8-0xcff on acpi0 pci0: <ACPI PCI bus> on pcib0 pcib1: <ACPI PCI-PCI bridge> at device 1.0 on pci0 pci1: <ACPI PCI bus> on pcib1 vgapci0: <VGA-compatible display> port 0xe000-0xe0ff mem 0xf0000000-0xf7ffffff,0xfe8f0000-0xfe8fffff,0xfe700000-0xfe7fffff irq 18 at device 5.0 on pci1 pcib2: <ACPI PCI-PCI bridge> irq 18 at device 6.0 on pci0 pci2: <ACPI PCI bus> on pcib2 bge0: <HP NC107i PCIe Gigabit Server Adapter, ASIC rev. 0x5784100> mem 0xfe9f0000-0xfe9fffff irq 18 at device 0.0 on pci2 bge0: CHIP ID 0x05784100; ASIC REV 0x5784; CHIP REV 0x57841; PCI-E miibus0: <MII bus> on bge0 brgphy0: <BCM5784 10/100/1000baseT PHY> PHY 1 on miibus0 brgphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, 1000baseT, 1000baseT-master, 1000baseT-FDX, 1000baseT-FDX-master, auto, auto-flow bge0: Ethernet address: XX:XX:XX:XX:XX:XX ahci0: <ATI IXP700 AHCI SATA controller> port 0xd000-0xd007,0xc000-0xc003,0xb000-0xb007,0xa000-0xa003,0x9000-0x900f mem 0xfe6ffc00-0xfe6fffff irq 19 at device 17.0 on pci0 ahci0: AHCI v1.20 with 4 3Gbps ports, Port Multiplier supported ahcich0: <AHCI channel> at channel 0 on ahci0 ahcich1: <AHCI channel> at channel 1 on ahci0 ahcich2: <AHCI channel> at channel 2 on ahci0 ahcich3: <AHCI channel> at channel 3 on ahci0 ohci0: <AMD SB7x0/SB8x0/SB9x0 USB controller> mem 0xfe6fe000-0xfe6fefff irq 18 at device 18.0 on pci0 usbus0 on ohci0 ehci0: <AMD SB7x0/SB8x0/SB9x0 USB 2.0 controller> mem 0xfe6ff800-0xfe6ff8ff irq 17 at device 18.2 on pci0 usbus1: EHCI version 1.0 usbus1 on ehci0 ohci1: <AMD SB7x0/SB8x0/SB9x0 USB controller> mem 0xfe6fd000-0xfe6fdfff irq 18 at device 19.0 on pci0 usbus2 on ohci1 ehci1: <AMD SB7x0/SB8x0/SB9x0 USB 2.0 controller> mem 0xfe6ff400-0xfe6ff4ff irq 17 at device 19.2 on pci0 usbus3: EHCI version 1.0 usbus3 on ehci1 pci0: <serial bus, SMBus> at device 20.0 (no driver attached) atapci0: <ATI IXP700/800 UDMA133 controller> port 0x1f0-0x1f7,0x3f6,0x170-0x177,0x376,0xff00-0xff0f at device 20.1 on pci0 ata0: <ATA channel> at channel 0 on atapci0 ata1: <ATA channel> at channel 1 on atapci0 isab0: <PCI-ISA bridge> at device 20.3 on pci0 isa0: <ISA bus> on isab0 pcib3: <ACPI PCI-PCI bridge> at device 20.4 on pci0 pci3: <ACPI PCI bus> on pcib3 ohci2: <AMD SB7x0/SB8x0/SB9x0 USB controller> mem 0xfe6fc000-0xfe6fcfff irq 18 at device 22.0 on pci0 usbus4 on ohci2 ehci2: <AMD SB7x0/SB8x0/SB9x0 USB 2.0 controller> mem 0xfe6ff000-0xfe6ff0ff irq 17 at device 22.2 on pci0 usbus5: EHCI version 1.0 usbus5 on ehci2 acpi_button0: <Power Button> on acpi0 sc0: <System console> at flags 0x100 on isa0 sc0: VGA <16 virtual consoles, flags=0x300> vga0: <Generic ISA VGA> at port 0x3c0-0x3df iomem 0xa0000-0xbffff on isa0 ppc0: cannot reserve I/O port range ctl: CAM Target Layer loaded acpi_throttle0: <ACPI CPU Throttling> on cpu0 hwpstate0: <Cool`n'Quiet 2.0> on cpu0 Timecounters tick every 1.000 msec usbus0: 12Mbps Full Speed USB v1.0 usbus1: 480Mbps High Speed USB v2.0 usbus2: 12Mbps Full Speed USB v1.0 usbus3: 480Mbps High Speed USB v2.0 usbus4: 12Mbps Full Speed USB v1.0 usbus5: 480Mbps High Speed USB v2.0 ugen0.1: <ATI> at usbus0 uhub0: <ATI OHCI root HUB, class 9/0, rev 1.00/1.00, addr 1> on usbus0 ugen1.1: <ATI> at usbus1 uhub1: <ATI EHCI root HUB, class 9/0, rev 2.00/1.00, addr 1> on usbus1 ugen2.1: <ATI> at usbus2 uhub2: <ATI OHCI root HUB, class 9/0, rev 1.00/1.00, addr 1> on usbus2 ugen3.1: <ATI> at usbus3 uhub3: <ATI EHCI root HUB, class 9/0, rev 2.00/1.00, addr 1> on usbus3 ugen4.1: <ATI> at usbus4 uhub4: <ATI OHCI root HUB, class 9/0, rev 1.00/1.00, addr 1> on usbus4 ugen5.1: <ATI> at usbus5 uhub5: <ATI EHCI root HUB, class 9/0, rev 2.00/1.00, addr 1> on usbus5 uhub4: 4 ports with 4 removable, self powered uhub0: 5 ports with 5 removable, self powered uhub2: 5 ports with 5 removable, self powered uhub5: 4 ports with 4 removable, self powered uhub1: 5 ports with 5 removable, self powered uhub3: 5 ports with 5 removable, self powered ada0 at ahcich0 bus 0 scbus0 target 0 lun 0 ada0: <WDC WD30EZRX-00DC0B0 80.00A80> ATA-9 SATA 3.x device ada0: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes) ada0: Command Queueing enabled ada0: 2861588MB (5860533168 512 byte sectors: 16H 63S/T 16383C) ada0: Previously was known as ad4 ada1 at ahcich1 bus 0 scbus1 target 0 lun 0 ada1: <WDC WD30EZRX-00DC0B0 80.00A80> ATA-9 SATA 3.x device ada1: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes) ada1: Command Queueing enabled ada1: 2861588MB (5860533168 512 byte sectors: 16H 63S/T 16383C) ada1: Previously was known as ad6 ada2 at ahcich2 bus 0 scbus2 target 0 lun 0 ada2: <WDC WD30EZRX-00DC0B0 80.00A80> ATA-9 SATA 3.x device ada2: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes) ada2: Command Queueing enabled ada2: 2861588MB (5860533168 512 byte sectors: 16H 63S/T 16383C) ada2: Previously was known as ad8 ada3 at ahcich3 bus 0 scbus3 target 0 lun 0 ada3: <WDC WD30EZRX-00DC0B0 80.00A80> ATA-9 SATA 3.x device ada3: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes) ada3: Command Queueing enabled ada3: 2861588MB (5860533168 512 byte sectors: 16H 63S/T 16383C) ada3: Previously was known as ad10 ada4 at ata0 bus 0 scbus4 target 1 lun 0 ada4: <INTEL SSDSC2CT120A3 300i> ATA-9 SATA 2.x device ada4: 150.000MB/s transfers (SATA, UDMA6, PIO 8192bytes) ada4: 114473MB (234441648 512 byte sectors: 16H 63S/T 16383C) ada4: Previously was known as ad1 SMP: AP CPU #1 Launched! Timecounter "TSC-low" frequency 11699577 Hz quality 800 Trying to mount root from ufs:/dev/ad1p2 [rw,noatime]... ZFS filesystem version 5 ZFS storage pool version 28
freebsd-updateを使ってFreeBSD 9.0-RELEASEからFreeBSD 9.1-RELEASEにアップグレード
FreeBSD 9.0-RELEASEで始めた自宅サーバだけど、ほどなくFreeBSD 9.1-RELEASEがリリースされたのでアップグレードした。FreeBSD.orgのサーバが侵入されちゃった事件の影響か、少しリリースが遅れたけど、無事にリリースされてよかったよ。
アップグレードは、いつもどおりfreebsd-updateを使ってバイナリアップデート。しばらく前から、ソースツリーは展開してなかったりする。うーん、軟弱になったもんだ。
手順はいつも通りで特に変わったところは無し。
まずは元リリースの最新に更新する。これは、FreeBSD-EN-12:01.freebsd-updateを修正しておかないと、freebsd-updateがうまく動かないから。
# freebsd-update fetch # freebsd-update install
次に9.1-RELEASEへの更新差分をゲットする。しばらく時間がかかるので注意。
# freebsd-update upgrade -r 9.1-RELEASE
ゲットしたら、インストール。この段階では、kernelだけが新しくなるので、再起動して新しいkernelで動作させる。
# freebsd-update install # shutdown -r now
次に残りの更新をインストールして再起動する。
# freebsd-update install # shutdown -r now
8.2-RELEASE以前からのアップグレードだと、portsの作り直しが必要だけど、今回は9.0-RELEASEからなので、これでおしまい。ZFSは同じバージョンなので、zpool、ZFSのupgradeも不要。
自宅サーバを富士通 PRIMERGY MX130 S2からHP ProLiant MicroServerに更新
某所でHP ProLiant MicroServerがいいらしい、と聞いたので、調査してみた。本当によさそうだったので、富士通 PRIMERGY MX130 S2から乗り換えた。
MicroServerのスペックはこんな感じ。
- CPU:AMD Turion II NEO N40Lプロセッサー(1.5GHz、15W、2MB)×1
- メモリ:PC3-10600 DDR3 2スロット 最大8GB
- HDD:SATA 4台搭載可能
- 光学ドライブ:HDDとは別に5inchベイに搭載可能
PRIMERGY MX130 S2と比較すると、よい点は
- HDDが専用ベイできれいに4台搭載可能、取り付け・取り外しも簡単(ただしホットプラグは未対応)
- HDDを4台搭載しても、光学ドライブを搭載可能(MX130は4台目を5inchベイに搭載する必要があった)
- eSATAポート搭載、外付けHDD箱による拡張もできる
いまいちな点は
- メモリスロットが2スロット(MX130 S2は4スロット)
- 筐体が立方体に近く、設置場所の変更が必要(これは人によると思う)
- メモリや拡張カードの増設が面倒(マザーボードから各種コネクタを外して引っ張り出す必要がある)
今の利用状況から判断すると、メモリは8GBあれば足りそうだったのと、HDD 4台搭載して5inchベイが空くこと、低消費電力でいけそうなところに魅力を感じて乗り換えることにした。
N40LのHDD 250GBモデルがAmazonで17,800円だったので、これをベースにメモリとHDDを別調達した。ZFS Rootは面倒だったので、起動用にSSDをチョイス。最終的に追加したパーツはこんな感じ。
OSは9.1-Rリリース前だったので9.0-Rをインストール。ZFSは、以前は容量の都合でRAIDZだったけど、今回は3TBに増量して余裕があったので、3TBのミラーx2で行くことにした。旧サーバからデータを移行して、無事稼働開始。HDDが前面から簡単に取り外しできるので、HDD故障したときの交換が楽になりそう。壊れないのが一番だけど。
HP ProLiant MicroServer TurionII NEO N40L 1.5GHz | ||||
|
WD Green 3.5inch IntelliPower 3.0TB 64MBキャッシュ SATA3.0 WD30EZRX-1TBP/N 【フラストレーションフリーパッケージ(FFP)】 | ||||
|
Intel SSD 330 Series Maple Crest 120GB MLC 2.5inch 9.5mm Reseller Box SSDSC2CT120A3K5 | ||||
|
perlでEvernoteのAPIを使うときに'Missing version identifier'で怒られた
とある目的でperlからEvernoteのAPIを使う必要にかられて挑戦してみたところ、'Missing version identifier'でUserStore->checkVersionが異常終了して困ってた。環境を変えて調べてみると、Mac OS X上にperlbrewで作ったperl 5.14.2環境ではうまくいかなくて、FreeBSD環境だとうまくいく。
例外の内容はこんなかんじ。
$VAR1 = bless( { 'code' => 0, 'message' => 'Missing version identifier' }, 'Thrift::TException' );
よくよく考えると、Evernote APIはThrift::HttpClient経由でlibwwwを使うんだけど、アクセス先がhttpsだった。Mac OS X上では、libwwwをhttps対応させてなかったのが原因だ。というわけで、Crypt::SSLeayとLWP::Protocol::httpsを追加でインストールして解決した。
FreeBSD portsだとMakefileの以下の記述により、OPTIONS SSLを有効にしていればSSL対応になるので、最初は気づかなかったよ。
.if defined(WITH_SSL) RUN_DEPENDS+= p5-Crypt-SSLeay>=0:${PORTSDIR}/security/p5-Crypt-SSLeay \ p5-LWP-Protocol-https>=0:${PORTSDIR}/www/p5-LWP-Protocol-https .endif