Apache1.3系でファイルが存在しない場合のみステータスコード503を返す方法

このサイトではないのですが、レンタルサーバーの不具合で、データベースに接続できなくなりました。

掲示板のプログラムでDBを利用していたのですが、そのサイトの顔と言えるコンテンツだったので、早急な対応が必要でした。

しかしそのサーバーはXREAで、その日は土曜日。休日には対応してくれないだろうし、しかもXREAはサポートがお粗末なので、いつ復旧するか、そもそも復旧できるのかすら分かりません。

というわけで、とりあえずサーチエンジン対策で503のステータスコードを出すことに決定。

メンテナンス中画面を出す正しい作法と.htaccessの書き方 | Web担当者Forum

を参考にmod_rewriteを使ってやってみます。
(以下、/bbs/以下が掲示板が動作しているディレクトリとします)

.htaccess

ErrorDocument 503 /bbs/503.php

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{REQUEST_URI} !=/bbs/503.php
  RewriteRule ^.*$ - [R=503,L]
</IfModule>

でも、これだとInternal Server Error に。
どうやら、Apache1.3系ではR=503はできない模様。
(というかApache1.3だってことをすっかり忘れてました)

Apache1.3系で特定のディレクトリ以下503を返す方法

で、いろいろと調べたところ、以下で取り急ぎ目的を達成できました。

.htaccess

ErrorDocument 503 /bbs/503.php
Redirect 503 /bbs

とりえあえず応急処置はこれで良しとして、次はコンテンツの復旧です。

さんざんCoreserver&XREAで泣かされてきたので、データ復旧しなかった場合を想定して、Googleのキャッシュからコンテンツを拾っていきます(私自身DBのバックアップを忘れていた手落ちもありました)。

そんなわけで、いくつか見つかったキャッシュデータを、静的なHTMLとして拾って、あるべき場所に配置しました。

この段階で、ファイルが存在するとき(要はキャッシュで復旧できたとき)は200でファイルを返して、ファイルが存在しないときは503を返したくなってきます。

そこで、焦っていてどこのサイトだか忘れてしまったのですが、PHPファイルを使って503を出す方法を見つけました。

PHPファイル

<?php
header ('HTTP/1.0 503 Service Temporarily Unavailable');
require_once dirname(__FILE__) . '/maintenance.htm.php';
# maintenance.htmも別途適当に作ります
?>

.htaccess

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/bbs/503.php
RewriteRule ^.*$ /bbs/503.php [R,L]

……が、302リダイレクトして503を出すページを表示させるのは気持ち悪いです。

Apache1.3系でファイルが無い場合のみ503を返す方法

というわけで、リダイレクト処理を無くして解決しました。
これでファイルorディレクトリが存在する場合は200とファイルを返し、存在しない場合は直に503を返し、メンテナンス表示をさせることができます。

PHPファイル

<?php
header ('HTTP/1.0 503 Service Temporarily Unavailable');
require_once dirname(__FILE__) . '/maintenance.htm';
# maintenance.htmも別途適当に作ります
?>

.htaccess

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/bbs/503.php
RewriteRule ^.*$ /bbs/503.php

というかめっちゃ苦労しました。
XREAは安くて機能が豊富で使いようによってはいいサーバーですが、私の使い方では苦労の方があきらかに多くなったので、もう使うのをやめようと思います(ちなみに月曜の今の時点で、DBは復旧していません……。技術部に回しますが、14日経っても直らない場合は催促してください、なんてメールだけ来ています(*_*))。

PostgreSQLで特定のデータベースをコピーする

そう頻繁にはないですが、PostgreSQLの特定のデータベースを、ちょちょっとコピーしたいということがあります。
例えば、DB関連のテストをするのに、いきなり本データでやるのはリスクがあるので、そういった時にコピーデータでテストすれば安心です。

実際何度もやっているのですが、たまにしか機会が無いので、その都度やり方を調べているので自分用にメモします。

SQLでコピー

私の場合は、基本的にphpPgAdminからpostgreSQLを操作することが多いので、以下のSQLを発行します。

CREATE DATABASE 新DB名 TEMPLATE 複製元のDB名

シェル環境でコピー

こっちは未確認ですが、マニュアルに載っていたので一応。

createdb -T 複製元のDB名 新DB名

完璧なコピーとは思わない方が良い!?

ただ、

CREATE DATABASEは、処理を始める時に(自身を除く)バックエンドプロセスがソースデータベースに接続していないことをチェックします。しかし、コピー先のデータベースの一貫性が失われる結果になる、コピー処理中の変更ができないことを保証しません。

とあるので、完璧なコピーだとは思わない方がいいかもしれませんね(私の場合はテスト位にしか使わないのでいいのですが)。

■参考サイト(ポスグレの公式ドキュメント)
テンプレートデータベース
http://www.postgresql.jp/document/pg803doc/html/manage-ag-templatedbs.html

Windowsのサービスのパスを変更する

普段私は単品でインストールしたApacheを使っているのですが、訳あってXAMPPをちょっとインストールすることに。

いろいろと動作テストをして、目的を達成したのでアンインストールしました。

……ところが、それ以降Apacheを起動させようとしても、起動時にエラー(The requested operation has failed!)が発生するようになってしまいました。

イベントログを見てみると、
> Apache2.2 サービスは次のエラーのため開始できませんでした:
> 指定されたパスが見つかりません。
とのことです。

Windowsのコントロールパネル→管理ツールからサービスを起動させて、Apacheの実行ファイルのパス欄を見てみたら、予想通り、XAMPPのパスが登録されていました。

C:\xampp\apache\bin\httpd.exe” -k runservice

先ほどインストールしたXAMPPにてあやまった操作をしてしまった(たぶんサービスに登録しちゃった)ため、パスを書き換えてしまったんですね。

しかしこの実行ファイルのパス欄は、変更ができません。
おそらくレジストリに登録されているんだと思いさくっと検索して解決したのでメモします。

レジストエディタを起動

まずはレジストリエディタを起動します。
Windowsのスタートから、ファイル名を指定して実行→regeditと入力してOKをクリックで、レジストリエディタを起動します。

パス(ImagePath)を変更

下記をたどっていきます。
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\

ここまで来てから、希望のサービス名を選択します。右ペインに、ImagePathとありますので、それを変更すればOK。

私の場合は、元のApacheのパスに変更しました。

“C:\Program Files\Apache Software Foundation\Apache2.2\bin\httpd.exe” -k runservice

これで無事解決です!

■参考サイト
winのサービスの実行ファイルのパスの変更方法 – ネットnote