Tips: NTFSパーティションのネットワーク越しのバックアップ

Last-modified: 2010-02-06 (土) 16:04:46
初出 2006-8-18
最終更新 2010-2-6
私はNTFSパーティションもGNUのツール類(※1)だけを使ってバックアップをおこないます。
 

Windows用のバックアップツールを使えば、NTFSパーティションをバックアップしたものから一部のファイルだけを取り出したり、サイズの違うパーティションにレストアできます。ただし私の経験では、そのようなツールは環境によって時々エラーが発生し、レストアできない事態が”まま”発生します。

 

GNUのツールの場合、NTFSパーティションはイメージとしてバックアップ、レストアが出来るだけです(※2)。つまりバックアップ元のパーティションとレストア先のパーティションはHDD上の位置(※3)、大きさが一致していなければなりません。しかし、エラーフリーで運用できます(私の経験上)。
(2008-8-6追加) 言うまでもないことですが、イメージ形式のバックアップでは、バックアップ時のOSで中身を読めないファイルシステムもバックアップ出来ます。つまり、例えばLinuxを使ってSolarisやFreeBSDもバックアップ出来ます。本ページで「NTFS」と記述してある個所は、必要に応じて適宜他のファイルシステムに読み替えて下さい。バックアップ時のOSから対象のファイルシステムの中身が読めない場合に対象のファイルシステムのOS稼動中にゼロ埋めしておくこと等は、NTFSに限った話ではありません。

 

イメージとしてバックアップをおこなうので、当然、バックアップしたファイルは圧縮します。

 

圧縮率を上げる為に多少の工夫をこらします。以下の手順を用いると、環境によりかなり異なりますが、使わない場合と比べて遥かに高い圧縮率を得ることができます。(例えば、手順導入前の圧縮ファイルの大きさ3ギガバイト→導入後1.6ギガバイト)


NTFSパーティションのネットワーク越しのバックアップ

高い圧縮率でバックアップする為の事前処置をバックアップ対象のWindows OS上でおこなう場合

Windows上での事前処理手順1 「スワップファイルを消します」

  • システムのプロパティの仮想メモリで仮想メモリを使わない設定にします。
  • 設定変更してセーフモードで再起動するとスワップファイルが消えた状態でWindowsが立ち上がります。セーフモードの際にはハイバーネートファイルも自動的に消えます。
     
    ※:後の手順と関係ありますのでWindowsXPの場合はセーフモード、Windows2000の場合はネットワークありのセーフモードを選びます。

ここでは標準的な手法としてセーフモードの活用を紹介していますが、メモリ容量に余裕がある場合はセーフモードにする必要はありません。但しノーマルなモードの場合に休止状態を有効にしているとスワップファイルだけではなくハイバーネートファイルも手動でその場だけの設定変更をして消す必要があります。

Windows上での事前処理手順2 「ファイルシステムの空いている部分をゼロで埋めます」

  • Windows Vista、XPの場合は、以下のvbスクリプト(WSH)を実行すると良いです。(時々”消すファイルがない”エラーが発生するみたいです。致命的な問題ではありませんが、改善された方がいらっしゃいましたら教えて頂けたらと思います。)
    ※アンチウィルスソフトによっては、vbスクリプトの実行時に警告が出ることもあります。このスクリプトは改変しない限り、悪いことはしませんので適宜警告を外して実行して下さい。ノートン(Symantec)の場合だと"スクリプト全体を1回許可する"を選択するのが適当だと思います。
    'FillZero.vbsの名で保存して下さい
    'WindowsXP用です
    tmpMsg = "対象ドライブを入力して下さい"
    destDrv = InputBox(tmpMsg,,"C:")
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set src = fso.GetDrive(destDrv)
    fileSize = src.FreeSpace - 10000
    fileName = destDrv & "\zeroimage"
    If fso.FileExists(fileName) Then
        fso.DeleteFile(fileName)
    End If
    Set ws = CreateObject("Wscript.Shell")
    ws.run "fsutil file createnew " & fileName & " " &  fileSize , 1 , True
    ws.run "fsutil file setvaliddata " & fileName & " " & fileSize , 1 , True
    ws.run "fsutil file setzerodata offset=0 length=" & fileSize &  " " & fileName , 1 , True
    fso.DeleteFile(fileName)
  • Windows2000の場合は、空き容量に合わせてLinux上で
    $ dd if=/dev/zero of=zeroimage bs=1M count=2463
    みたいなコマンドを実行してゼロ埋めしたファイルを作り(※4)、それをWindows側にコピーした後、すぐ削除します。
     
    ※:実際にはWindowsXPの場合でもWindows2000と同じ手順がお薦めです。スピードが数倍違います。(2007-8-12修正)Windows XPのアップデートの影響か?、最近は上のvbスクリプトを実行する方が確実に速いようです。

Windows上での事前処理手順3 「再度スワップファイルを作成します」

  • 再びシステムのプロパティの仮想メモリの設定を開き、仮想メモリを使う設定にします。
  • すぐにスワップファイルが再作成されますが、中身はまだゼロのままなので後の圧縮率には影響しません。またノーマルモードで作業をしている場合は必要であれば休止状態も再設定する必要があるでしょう。

高い圧縮率でバックアップする為の事前処置をLinuxを使っておこなう場合

最近のLinuxは速度は遅いながらもNTFSファイルシステムへの書き込みが十分おこなえるようになってきました。
こういったLinuxを使うと、上記手順よりも遥かに簡単に事前処理がおこなえます。

Linuxを使っての事前処理手順1 「スワップ、休止用のファイルを削除します」

Windowsを完全に終了させ、デュアルブートのLinuxとかOne CDとかUSBブートのLinuxを起動します。

 

対象のNTFSパーティションが書き込み可でマウントされているディレクトリで、

# rm hiberfil.sys pagefile.sys

Linuxを使っての事前処理手順2 「ddコマンドでゼロ埋めします」

(2010-2-6追記)LinuxでのNTFSへの書き込み機能は安全ですが、不完全なものです。特にMFTへのファイルの書き出しが不完全なので、デフラグが不完全な状態で下記のゼロ埋め作業をおこなうと処理の最後の方で処理が止まってしまうことがあります。Linuxでゼロ埋めする前には出来る限り事前にWindows上でデフラグをしておきましょう。

 

対象のNTFSパーティションが書き込み可でマウントされているディレクトリで、

# dd if=/dev/zero of=zeroimage bs=1M || rm -f zeroimage

このコマンドでファイルシステムの未使用領域をゼロ埋めします。これが終わったら他のディレクトリにcdし、対象のパーティションをアンマウントしておきます。
NTFSに書き込めるLinuxを使った場合はたったこれだけで事前準備完了です。
Windowsの設定を一時的にも変更する必要がありませんし、引き続いてバックアップ処理もおこなえます。

ネットワーク越しにバックアップします

(前の手順でWindowsを使っていた場合は)Windowsを終了し、Linux等(※5)でバックアップします。
対象のパーティションがマウントされている場合はアンマウントしておきます(マウントしたままだとベリファイに不都合だし、リストアしてWindowsを起動した際にも少し不味い)。

# dd if=/dev/sda1 | ssh server-user@file-server \
"bzip2 --best > /savedir/client-name-sda1.img.bz2"

みたいなコマンドを実行します。ddとsshを組み合わせるだけです。
上の例ではサーバー側で圧縮していますが、クライアント側で圧縮する場合は以下の例のようになります。(※6)

# dd if=/dev/sda1 | bzip2 --best | ssh server-user@file-server \
"dd of=/savedir/client-name-sda1.img.bz2"

圧縮しないのなら以下のようにハッシュ値の取得を同時におこなうことができます。

# dd if=/dev/sda1 | ssh server-user@file-server \
"tee /savedir/client-name-sda1.img | md5sum > /savedir/md5sum-client-name-sda1.txt"
 

バックアップと逆の作業をおこなえばレストアできます。

 

もちろん必要もないのに圧縮する必要はありませんし、圧縮するにしてもgzipのように圧縮率は低いもののCPU負荷の低い圧縮手段を使う手もあります。

 

サイト内関連ページ:稼働中LinuxのOS丸ごとネットワーク越しのバックアップ
サイト内関連ページ:ハードディスク操作のまとめ
サイト内関連ページ:リカバリーDVDの作成法
サイト内関連ページ:強力な(?)NTFSのPBR修復法

 


※1:Partimageも使いません。私見ですが、バックアップコマンドを知っている人には不要だと思います。


※2:HDDは取り替えてもかまいません。HDDの容量が違ってもかまいません。


※3:あくまで当該HDD内の相対位置です。ブートする場合はバックアップ元とバックアップ先でハードディスクの順番が一致している必要がありますが、バックアップ・レストア時にその制限はありません。例をあげますと、プライマリーマスターをバックアップし、一旦セカンダリースレーブにレストアした後プライマリーマスターに付け替えてブートさせることは問題ありません。


※4:countで指定する値は、ドライブの空き領域 ÷ 1024 ÷ 1024 で求めます。


※5:Knoppix等の自動コンフィギュレーション機能を持つOneCDLinuxとか、クライアントにWindowsと同様にインストールされたLinux(つまりWindowsとLinuxのマルチブート環境にしているということ)を用いることを意味します。


※6:もちろん最後のddはcatに置き換えることもできます。でもバッファの関係でddの使用を推奨します。
この方法でWindows用の商用バックアップツールより高い圧縮率でバックアップできます。

(おまけ)巨大なNTFSパーティションのFAT32パーティションへのバックアップ

ネットワーク越しではなく、USB接続のHDD等にバックアップしたい場合もあるでしょう。
しかし、Linux、Windowsの両方から自由に書き込めるファイルシステムであるFAT32には1ファイルの最大の大きさが4Gバイト迄という制限があります。以下は圧縮しても4Gを超えてしまう大きなNTFSパーティションをFAT32のパーティション上にバックアップするスクリプトです。

※:これは手動起動用です。クーロン等で実行するには向いていません。
(サンプル) hoge-sda2-vfat-bkup.sh

#!/bin/sh -e
PCNAME=hoge
DEV=sda2
MNTPNT=/media/sda1
BKUPDIR=OSBKUP
DATE=$( /bin/date '+%Y%m%d' )
FNAME=${PCNAME}_${DEV}_${DATE}
SRC=/dev/${DEV}
DST=${MNTPNT}/${BKUPDIR}/${DATE}
if !(mount|grep "${MNTPNT}">/dev/null) then
	echo "${MNTPNT} is not mounted."
	exit 1
fi
mkdir -p ${DST}
cd ${DST}
dd if=/dev/${DEV} bs=1M count=4000 skip=0    |gzip --best> ${FNAME}_1.img.gz
dd if=/dev/${DEV} bs=1M count=4000 skip=4000 |gzip --best> ${FNAME}_2.img.gz
dd if=/dev/${DEV} bs=1M count=4000 skip=8000 |gzip --best> ${FNAME}_3.img.gz
dd if=/dev/${DEV} bs=1M            skip=12000|gzip --best> ${FNAME}_4.img.gz
dd if=/dev/${DEV}|md5sum|tee ${FNAME}_all-md5sum.txt
gzip -dc *.img.gz|md5sum

スクリプトの最後の2行のmd5sumの出力が合致したら、バックアップのベリファイも成功したということになります。
レストアはスクリプトの最後の行の応用でできます。簡単です。

 

ご要望、ご意見、質問を下のフォームにどうぞ
(でもここより、掲示板書き込みフォームのページに書いて頂いた方が気づき易いと思います。)