はじめに
NAntは.NETのビルドスクリプティングツールです。JavaのビルドツールAntとよく似ているので、本稿の説明はAntにもそのまま当てはまるものと思われます。本稿は、NAntについてある程度知っていることを前提としています。
純粋主義者は異を唱えるかもしれませんが、NAntは本質的には一般のビルドタスク(ソース制御操作、コンパイル、ファイルの移動や削除など)を中心に最適化された高級プログラミング言語だと言えます。その自動化能力ゆえ、常時統合を実現するためによく使われます。しかし、用途はそればかりでありません。
本稿では、私がNAntを用いて解決したある厄介なバックアップ問題を扱います。ここではカスタマイズ可能な混成的バックアップシステムを構築する方法を具体的に説明します。本稿はNAntの基本的な知識を前提としています。このツールの詳細については、NAntサイトを参照してください。
本稿で扱うバックアップ対象サーバーではWindows 2003、.NET、SQL、MySQL、MSDE、PHP、メールサーバーが実行されています。このサーバーは95件のクライアントをホストし、各クライアントのバックアップ要件は多岐に渡ります。バックアップについてまったく検討したことがないクライアントや自分でバックアップを管理したがるクライアントがある一方で、不慮のデータ消失を恐れて正式の信頼できるバックアッププロセスを要請するクライアントもあります。このように多様な要件を限られた予算で満たさなければならないため、このバックアップ問題を商用ツールで解決するのは現実的でありません。
そこで、必要なバックアップタイプをIISメタデータのバックアップ、MySQLデータのバックアップ、MS SQLデータのバックアップ、各サイトファイルのバックアップに分類しました。このリストを見る限り、NAntで要件は満たせそうです。もう1つ、バックアップと共に何を行うかという問題があります。とりあえず考えられるオプションとしては、ファイルを圧縮してサーバーに保存する、ファイルを圧縮してネットワークドライブに保存する、ファイルを圧縮してメールで送信する、などがあります。いずれにせよ、クライアントが違えばソリューションも異なる、という点を押さえておくことが大切です。
その他の設計目標は、1つはスケジュールバックアップが可能なことで、もう1つはサーバーに新規のクライアントを追加してもバックアッププロセスの設定作業に過剰な負荷がかからないようにすることです。
バックアップの課題(1):IISメタベースのバックアップ
IISメタベースにはIISの構成情報が格納されています。大きな障害が生じても、これとサイトデータがあればWebサーバーを復元できます。IISスナップイン内でバックアップ対象のコンピュータを右クリックし、[すべてのタスク]メニューの[構成のバックアップまたは復元]を選択すると、IISメタベースがバックアップされます。幸い、この機能はスクリプティングからも利用できます。
Windows 2000またはWindows XPでバックアップを作成するには、コマンドラインから次のコマンドを実行します。
Windows 2003では次のコマンドを実行します。
cscript iisback.vbs /backup /b <backup name>
これらのコマンドで作成したIISバックアップを使えば、後でIIS構成を復元することができます。単純にコマンドを実行しているだけなので、そのままNAntスクリプトに含めることができます。NAntスクリプトは次のようになります。
注
本稿のNAntスクリプトにおいて、スクリプト先頭の<!-- Parameters -->セクションに記載されている値は、スクリプトを呼び出すときにプロパティとして設定することを期待されている値です。
<?xml version="1.0"?>
<project name="IIS" default="CreateIISBackup">
<!-- Parameters
backupName
scriptDirectory
-->
<target name="CreateIISBackup" >
<exec basedir="${ scriptDirectory }" program="cscript"
commandline="iisback.vbs /backup /b ${backupName}" />
</target>
</project>
このスクリプトを「IIS.build」という名前で保存します。このスクリプトを呼び出す前にプロパティを設定しておく必要があるため、コマンドラインから直接実行することはできません。このIISスクリプトを実行するスクリプトは次のようになります。
<?xml version="1.0"?>
<project name="BackupIIS" default="Backup">
<property name="backupName" value="IISBackup" />
<!-- For this script to work, this must be set to the location
of the script (metaback.vbs or IISback.vbs) -->
<property name=" scriptDirectory" value="IISBackup" />
<target name="Backup" >
<nant buildfile="IIS.build" inheritall="true" />
</target>
</project>
このスクリプトを「BackupIIS.build」という名前で保存します。このバックアップを実行すると、IISBackupというIISバックアップが作成されます。このバックアップを実行するためには、両方のスクリプトを同じディレクトリに置き、「nant.exe」にシステムパスを通しておく必要があります。コマンドプロンプトを開き、スクリプトの置かれているディレクトリに移動して次のように入力し、[Enter]キーを押します。
nant -buildfile:BackupIIS.build
バックアップが正常に作成されたことを確認するため、IISスナップインを開き、コンピュータノードを右クリックし、[すべてのタスク]メニューの[構成のバックアップまたは復元]を選択します。バックアップグリッド内にIISBackupというバックアップが表示されるはずです。
バックアップの課題(2):サイトファイルのバックアップ
バックアップ要件は次のとおりです。サイト内のすべてのファイルをバックアップします。バックアップの必要なサイトごとに、すべてのファイルを圧縮し、アーカイブをメールで安全な保管場所へ送信します。
まず、2つのターゲットを持つNAntスクリプトを作成しました。最初のターゲットはディレクトリの圧縮を行うもので、もう1つのターゲットはディレクトリを圧縮し、そのアーカイブをメールで送信するものです。
<?xml version="1.0"?>
<project name="FileBackup" >
<!--parameters
baseDirectory This is the parent of the directory to be compressed
targetDirectory This is the directory to be compressed
backupDirectory This is the location to store the archives
-->
<target name="CompressDirectory">
<zip zipfile="${backupDirectory}${directoryName}.zip" >
<fileset basedir="${baseDirectory}">
<include name="${ targetDirectory}/*" />
<include name="${targetDirectory }/**/*" />
</fileset>
</zip>
</target>
<target name="CompressDirectoryAndEmail" depends="CompressDirectory">
<mail from="backup@anon.com"
tolist="secure@anon.com"
subject="${ targetDirectory} backup"
mailhost="localhost">
<files>
<include name="${backupDirectory}${ targetDirectory}.zip" />
</files>
<attachments>
<include name="${backupDirectory}${ targetDirectory}.zip" />
</attachments>
</mail>
<!-- The backup has be mailed so the file is no longer required. -->
<delete file="${backupDirectory}${targetDirectory}.zip" />
</target>
</project>
このファイルを「FileBackup.build」という名前で保存します。先のIISバックアップと同様、パラメータの設定が必要なので、このスクリプトを直接実行することはできません。別のスクリプトで、パラメータを設定し、バックアップ対象のサイトごとにバックアップポリシーを指定する必要があります。この例では、すべてのWebサイトが「C:inetpub」というディレクトリに保存されているものと仮定します。もう1つ、「C:ackup」というディレクトリがあります。現在のところ、Webサイトはweb1、web2、web3の3つです。これらはそれぞれ「C:inetpubweb1」「C:inetpubweb2」「C:inetpubweb3」に保存されています。web1の所有者はサイトを夜間バックアップし、アーカイブをサーバー上の「C:ackup」に保存することを要請しています。web2とweb3の所有者はサイトを夜間バックアップし、安全な場所にメールで送信することを要請していますが、サーバーにコピーを残すことは要請していません。これらの要件を満たすスクリプトは次のようになります。
注
このスクリプトではメールの送信のためにローカルホストのSMTPサーバーを使用しています。この部分については実際のローカルSMTPサーバーを設定してください。
<?xml version="1.0"?>
<project name="BackupWebsites" default="Backup">
<!-- These two properties can be declared globally,
because they are the same for all sites. -->
<property name="baseDirectory" value="C:inetpub" />
<property name="backupDirectory" value="C:ackup" />
<!-- This target exists only to specify which sites are
to be backed up, and in what order. -->
<target name="Backup" depends="BackupWeb1,BackupWeb2,BackupWeb3" />
<target name="BackupWeb1">
<property name="targetDirectory" value="web1" />
<nant buildfile="FileBackup.build" inheritall="true"
target="CompressDirectory" />
</target>
<target name="BackupWeb1">
<property name="targetDirectory" value="web2" />
<nant buildfile="FileBackup.build" inheritall="true"
target="CompressDirectoryAndEmail" />
</target>
<target name="BackupWeb1">
<property name="targetDirectory" value="web3" />
<nant buildfile="FileBackup.build" inheritall="true"
target="CompressDirectoryAndEmail" />
</target>
</project>
このスクリプトを「BackupWebsites.build」という名前で保存します。このバックアップを実行するためには、「FileBackup.build」と「BackupWebsites.build」を同じディレクトリに置いておく必要があります。コマンドプロンプトを開き、このディレクトリに移動して次のコマンドを実行します。
nant -buildfile:BackupWebsites.build
このスクリプトを実行すると、「web1.zip」というアーカイブが「C:ackup」に作られ、さらに「web2.zip」と「web3.zip」というアーカイブがメールでsecure@anon.comに送信されます。
バックアップの課題(3):サーバーデータベースのバックアップ
現在このサーバーがホストしている2つのデータベースサーバーに、バックアップの必要なデータベースが存在します。1つはMySQL 5データベースで、もう1つはMSDEデータベースです。データベースのバックアップを希望するユーザーは、バックアップを圧縮したうえで安全な場所にメールで送信するよう要請しています。最初のステップとして、1つのデータベースをバックアップするNAntスクリプトを作成します。このスクリプトには、MySQLデータベースをバックアップするためのターゲットとMSDEデータベースをバックアップするためのターゲットが必要です。MySQLのバックアップにはmysqldumpユーティリティを使い、バックアップの必要なデータベースに対して次のコマンドを実行します。
mysqldump -u <username> -p<password> <databasename>
バックアップに特化した読み取り専用のユーザーアカウントを用意することをお勧めします。MSDEデータベースをバックアップするには、osqlユーティリティを使い、次のコマンドでバックアップを実行します。
osql -E -U <username> -P <password> -Q "BACKUP DATABASE
<databasename> To DISK = <backupfile>;"
ここでもバックアップに特化した読み取り専用のユーザーアカウントを用意することをお勧めします。
注
このスクリプトではメールの送信のためにローカルホストのSMTPサーバーを使用しています。この部分については実際のローカルSMTPサーバーを設定してください。
<?xml version="1.0"?>
<project name="DatabaseBackup">
<!-- parameters
mysqlPath (optional) Only required for the MySQLBackup target.
This is the path to the mysqldump executable
(in the mysql bin directory).
databaseName The name of the database to backup.
username The user account to use for the backup.
password The user’s password.
tempDirectory A temporary directory to store the database backup,
prior to emailing it.
-->
<target name="BackupMySQL">
<exec basedir="${mysqlPath}" program="mysqldump"
commandline="-u ${username} -p${password} ${databaseName}"
output="${tempDirectory}${databaseName}.sql" />
<zip zipfile="${databaseName}.zip">
<fileset basedir="${tempDirectory}">
<include name="${tempDirectory}${databaseName}.sql" />
</fileset>
</zip>
<mail
from="backup@anon.com"
tolist="secure@anon.com"
subject="${databaseName} database backup"
mailhost="localhost">
<files>
<include name="${tempDirectory}${databaseName}.zip" />
</files>
<attachments>
<include name="${tempDirectory}${databaseName}.zip" />
</attachments>
</mail>
<delete file="${tempDirectory}${databaseName}.zip" />
</target>
<target name="BackupMSSQL">
<exec program="osql"
commandline="-E -U ${username} -P ${password} -Q
"BACKUP DATABASE ${databaseName} To DISK =
’${tempDirectory}${databaseName}.dat’;" />
<zip zipfile="${tempDirectory}${databaseName}.zip">
<fileset basedir="${tempDirectory}">
<include name="${tempDirectory}${databaseName}.dat" />
</fileset>
</zip>
<mail
from="backup@anon.com"
tolist="secure@anon.com"
subject="${databaseName} database backup"
mailhost="localhost">
<files>
<include name="${tempDirectory}${databaseName}.zip" />
</files>
<attachments>
<include name="${tempDirectory}${databaseName}.zip" />
</attachments>
</mail>
<delete file="${tempDirectory}${databaseName}.zip" />
</target>
</project>
このスクリプトを「DatabaseBackup.build」という名前で保存します。ここでもやはり、データベースのバックアップを制御する別のスクリプトが必要です。このサーバーにはweb1、web2、web3の3つのWebサイトが存在することを思い出してください。それぞれにデータベースが存在します。web1とweb2はぞれぞれweb1とweb2というMySQLデータベースを使用します。web3はweb3というMSDEデータベースを使用します。これらのデータベースの所有者は、データをバックアップして安全な場所へメールで送信することを要請しています。この要件を満たすスクリプトは次のようになります。
<?xml version="1.0"?>
<project name="BackupDatabases" target="Backup">
<!-- This property can be declared globally,
because it is the same for all databases. -->
<property name="tempDirectory" value="C:ackup" />
<property name="mysqlPath" value="C:program filesmysqlin" />
<!-- This target exists only to specify which databases are
to be backed up, and in what order. -->
<target name="Backup" depends="BackupWeb1,BackupWeb2,BackupWeb3" />
<target name="BackupWeb1">
<property name="databaseName" value="web1" />
<property name="username" value="web1user" />
<property name="password" value="P@ssword" />
<nant buildfile="DatabaseBackup.build" inheritall="true"
target="BackupMySQL" />
</target>
<target name="BackupWeb2">
<property name="databaseName" value="web2" />
<property name="username" value="web2user" />
<property name="password" value="P@ssword" />
<nant buildfile="DatabaseBackup.build" inheritall="true"
target="BackupMySQL" />
</target>
<target name="BackupWeb3">
<property name="databaseName" value="web3" />
<property name="username" value="web3user" />
<property name="password" value="P@ssword" />
<nant buildfile="DatabaseBackup.build" inheritall="true"
target="BackupMSSQL" />
</target>
</project>
このスクリプトを「BackupDatabases.build」という名前で保存します。このスクリプトをテストするには、「DatabaseBackup.build」と同じディレクトリに保存しておく必要があります。コマンドプロンプトを開き、このディレクトリに移動して次のコマンドを実行します。
nant -buildfile:BackupDatabases.build
このスクリプトを実行すると、先の3つのデータベースの内容がzipアーカイブに追加され、メールでsecure@anon.comに送信されます。
まとめ
本稿ではIISメタデータ、Webサイトファイル、データベースの3つのケースについてバックアップ用のスクリプトを作成しました。これらのバックアップタスクを統合し、スケジュールに従って実行するように設定する作業が残っています。すべてのビルドタスクを統合する最も簡単な方法は、次のようなバッチファイルを定義することです。
nant -buildfile:BackupIIS.build
nant -buildfile:BackupWebsites.build
nant -buildfile:BackupDatabases.build
これだけです。このシステムをセットアップしておけば、毎晩自動的にフルバックアップが行われます。サーバーに新規のサイトが追加されたときは、そのサイトをBackupWebsitesとBackupDatabasesの2つのスクリプトに追加するだけです。これらのツールはすべて無料で使え、信頼性もあります。
NAntの能力は単なるビルドツール以上のものがあります。本稿では強力な自動バックアップツールとしての可能性を示しましたが、他にも多くの可能性が考えられます。自らの手で管理タスクを実行するとき、NAntで自動化できないか自問自答してみるとよいでしょう。