このエントリーをはてなブックマークに追加
スポンサーリンク

PostgreSQLのインストール

ソースの入手

まず、ソースを入手します。
https://www.postgresql.jp/

PostgreSQLには主に7.4系、8.0系、8.1系、8.2系などがあります。今から新規に使うのであれば、できるだけバージョンの新しいのを使う方が良いです。バージョンが新しい方がアクセス速度やメモリ効率など、色々な点で改良されているからです。

ただ、現在すでに動いているシステムからのアップデートであれば、同じメジャー番号の最もマイナーバージョンの高いものを使う方が無難です。マイナーバージョンは主にセキュリティパッチやバグ修正のたびに更新されますので、マイナーバージョンが大きいという事は、それだけ安定した動作が期待できるからです。

バージョン7.2から7.3になる時に、int型に''(空文字列)をinsertするとエラーになるというルールができました。これは他のSQLの規則と合致していて良いルールなのですが、それまで正常に動いているシステムからバージョンアップさせる時にはソースの全面的な見直しが必要となります。

同様に、8.0から8.1へのバージョンアップの時にデフォルトでoidがつかなくなったり、8.1から8.2へのバージョンアップの時にデフォルトで¥がエスケープ記号とみなさなくなりました。いずれもpostgres.confファイルで変更可能ですが、現行システムからのバージョンアップの際には設定ファイルを見直す必要があるでしょう。

という事も踏まえて、必要と思われるバージョンをダウンしてください。

コンパイル&インストール

ソース一式をコンパイルします。

./configure --enable-multibyte
make
make install

最後の、--enable-multibyteは、バージョン7.2以下の時に日本語を扱う際に必要でしたが、7.3からは指定しなくても標準で日本語を扱えるようになり、8.2からは指定するとかえってエラー(unknown option)になります。8.2以上なら、単に./configureとします。

コンパイル&インストールには若干(というか、かなり)時間がかかりますので、気長に待ちます。なので私は、別窓を開いてapacheやPHPのコンパイルも同時に行います。(これはデュアルコアCPUで効果的です)

・バージョンごとに注意すべき点

・PostgreSQL7.2系の場合
前述の通り、バージョン7.2系で動いているシステムを新しいサーバー(新しいバージョンのLinux)に移す時に、互換性の関係で今でも7.2系をインストールしなければならない事があります。しかしながら、7.2系は比較的古いディストリビューションが主流の時に広まったものなので、現在よく使われている、Enterprise4やCentOS4ではコンパイルエラーになってしまう事があります。

原因は、最近のディストリビューション付属のコンパイラでは、#include <errno.h> の宣言が必要になったためです。そこで、コンパイルエラーの出たプログラムに、errorno.hを追加してあげます。
make
(エラーになる)
どのソースがエラーになったのか見極める

vi (エラーになったソース)
例)copy.c
#include <errno.h> ←この行を追加
#include <……>
#include <……>
     :
make

コンパイルエラーがでなくなるまでこの作業を繰り返します。

データーベースの初期化

データーベースの初期化は、最初に必ず1回だけ行います。データーベースの初期化を行った場合、そのユーザーはスーパーユーザーになり、Postgresにユーザーを追加/削除できるようになります。

PostgreSQL完全攻略ガイド(以下、シーラカンス本)では、「postgres」というユーザー名を用いるようになっているので、ここでもpostgresにしてみます。root権限で、「postgres」というユーザーを作成しておいてください。
useradd postgres
passwd postgres
(postgresのパスワード)×2
chmod 777 /usr/local/pgsql
そしたら、postgresになります。
su - postgres
そして、データーベースを初期化します。
/usr/loocal/pgsql/bin/initdb --encoding=EUC_JP --no-locale -D /usr/local/pgsql/data
これでデーターベースが初期化され、postgresがスーパーユーザーとして登録されます。--encoding=EUC_JPで、マルチバイトとしてEUCコードを使う事を指定しています。
コラム no-localeについて

PostgreSQL7.3以降+Linuxの組み合わせでは日本語のソートがうまくいかないというバグがあります。どうも、PostgreSQL7.3以降では、ロケールファイルを使って日本語のソート順位を判別しているようなのですが、RedHat系のLinuxのロケールファイルが正しく働いてないようです。そのため、--no-localeを指定して、ロケールファイルに頼らない事を指示します。

ただし、PostgreSQL7.2以前のバージョンで--no-localeと指定するとunknown optionと出てエラーになってしまうので、7.3以降のみ指定するようにしてください。
-D でデーターベースを記録しておくディレクトリを指定します。データーディレクトリはあらかじめ作成してあってはいけません。なので、ここではあらかじめ/usr/local/pgsqlディレクトリのバーミッションを777に設定しました。

しかし、このままでは任意の第3者がデーターベースに自由にアクセスできてしまい、セキュリティー以前の問題になってしまいます。なので、データーディレクトリを作成したら、ルート権限でパーミッションを元に戻します。
exit
chmod 755 /usr/local/pgsql

ログディレクトリ作成

Postgresのログを追加書き込みするようにしておくと、何らかの原因でpostmasterのデーモンが落ちてしまった時に原因究明に役立ちます。

mkdir /var/log/pgsql
chown postmaster.postmaster /var/log/pgsql
としてディレクトリを作っておき、

pg_ctlコマンドの最後に、 -l /var/log/pgsql/postgres.log をつけてpostmasterを起動させます。

ただし、このままではログがたまる一方で、そのうちハードディスクがパンクするでしょう。そこで、ログを定期的にローテーションするようにします。
vi /etc/logrotate.d/postgres
/var/log/postgres/*log {
    create 0644 postgres postgres
    missingok
    sharedscripts
    postrotate
        /bin/kill -HUP `head -1 /usr/local/pgsql/data/postmaster.pid  2> /dev/null` 2> /dev/null || true
    endscript
}
head -1 /usr/local/pgsql/data/postmaster.pid
の部分は、本来ならcat とすべき所ですが、catコマンドではシェアードメモリの残量まで出てしまい、たまたま同じプロセスIDのプロセスがあるとリスタートしてしまいますので、head -1コマンドで最初の1行だけを出すようにしています。

Postmasterの起動

PostgreSQL6以前では、長ったらしいスクリプトを/etc/rc.d/rc.localに記述して起動させていましたが、これはあまりスマートな方法とは言えません。PostgreSQL7降では、pg_ctlというコマンドを使うことができます。apacheでいうところの、apachectl コマンドのようなものです。
pg_ctl -D /usr/local/pgsql/data -l /var/log/postgres.log start
このようにすることで、postmasterを&付きで実行して常駐させるのと同じ効果が得られます。プロセスIDファイル(postmaster.pid)の管理やログファイルの生成はpg_ctlスクリプトがやってくれるので、見た目もかなりスマートになります。

・サーバー起動時に起動させる
サーバー起動時にPostgreSQLを起動させるためには、/etc/rc.d/init.dに自動起動スクリプトを記述します。同ディレクトリ内にある他の起動スクリプトをコピーしてからちょっといじれば簡単です。

vi /etc/rc.d/init.d/postgresql
#!/bin/bash
#
#       /etc/rc.d/init.d/postgres
#
# Starts the at daemon
#
# chkconfig: 345 95 5
# description: Runs commands scheduled by the at command at the time \
#    specified when at was run, and runs batch commands when the load \
#    average is low enough.
# processname: postgres

# Source function library.
. /etc/init.d/functions

RETVAL=0

start() {
        echo -n "Starting PostgreSQL... "
        if [ -f /usr/local/pgsql/data/postmaster.pid ];
           then
             RETVAL=1
           else 
             /bin/su - postgres -c "/usr/local/pgsql/bin/pg_ctl \
             -D /usr/local/pgsql/data -l /var/log/pgsql/postgres.log start"
             RETVAL=0
        fi
        [ $RETVAL -eq 0 ] && success || failure
        echo ""
}

stop() {
        echo -n "Stopping PostgreSQL..."
        if [ -f /usr/local/pgsql/data/postmaster.pid ];
           then
             /bin/su - postgres -c "/usr/local/pgsql/bin/pg_ctl \
             -D /usr/local/pgsql/data -m fast stop"
             RETVAL=0
           else 
             RETVAL=1
        fi
        [ $RETVAL -eq 0 ] && success || failure
        echo ""
}

restart() {
      stop
      sleep 2
      start
}

# See how we were called.
case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart|reload)
        restart
        ;;
  *)
        echo "Usage: postgres {start|stop|restart|reload}"
        exit 1
esac

exit $RETVAL
chmod 755 /etc/rc.d/init.d/postgresql
chkconfig postgresql on

注意:
これはあくまで例です。 あくまでも例なので、単にコピペして「動かないぞ、どうなってんだゴルァ」とか文句を言ったり、 よそのサイト(Yahoo知恵袋とか教えてgooとか2ちゃんねるとか)に質問を投げたりしないように。 お使いの環境に合わせて修正してください。

環境変数の追加

これまでPostgreSQLのコマンドは全てフルパスで実行してきましたが、これでは面倒なので、コマンドにパスを通しておきましょう。

vi /etc/profile.d/postgresql.sh
export POSTGRES_HOME=/usr/local/pgsql
export PGLIB=$POSTGRES_HOME/lib
export PGDATA=$POSTGRES_HOME/data
export MANPATH="$MANPATH":$POSTGRES_HOME/man
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH":"$PGLIB"
PATH="$PATH":/usr/local/pgsql/bin
vi /etc/ld.so.conf.d/postgres.conf
/usr/local/pgsql/lib
を記述した後、最後にldconfigとします。

ユーザーの追加

PostgreSQLのデーターベースを操作できるユーザーを追加します。まず su - postgresでpostgresになった後、
/usr/local/pgsql/bin/createuser ユーザー名

とします。この後、このユーザーがスーパーユーザーかどうか聞いてきます。スーパーユーザーになるとデーターベース作成権とユーザーを作成限が与えられます。nと答えると、このユーザーにデーターベース作成権を与えるか聞いてきます。

PHPが使うユーザー(apache等)にはデーターベース作成権を与えず、また、使えるSQLも少なく設定しておけば万一SQLインジェクションされた場合にも被害が少なくて済みます。

postgres.confの変更

PostgreSQLを最適に動作させるために、postgres.confをデフォルトのものから変更します。postgres.confは、initdb した時に -Dで指定したディレクトリにあります。(例:/usr/local/pgsql/data/postgres.conf)

PostgreSQL7.4系の場合

tcpip_socket = true
PHP4.2.0以降からPostgreSQLへの接続にhostソケットを使うようになったのでtrueに設定しておきます。ここがfalseのままだと、PHP4.2以降でPostgreSQLへの接続ができなくなります。

shared_buffers = (シェアードメモリの量)
sort_mem = (ソートメモリーの量)
vacuum_mem = (バキュームメモリーの量)

全てキロバイト単位で指定します。ここはデフォルトのままでも問題はないのですが、メモリーの許す限り大きな値にしておくと、PostgreSQLのパフォーマンスが飛躍的に向上します。データーベース専用のサーバーで使うのであれば、値を許容しうる上限にしておくと良いでしょう。

PostgreSQL8.0/8.1系の場合

listen_addresses = '*'
PostgreSQL8.xx以降では、trueやfalseではなく、接続を許可するアドレスを記述する方式に変わりました。全てを許可する場合は'*'としますが、アドレスやアドレス帯(IP/マスク)を指定する事もできます。全てを許可した場合、別途pg_hba.confで許可するアドレスを制限しないとデーターが外から丸見えになってしまいます。

shared_buffers = (シェアードメモリの量)
work_mem = (ソートメモリーの量)
maintenance_work_mem = (バキュームメモリーの量)

全てキロバイト単位で指定します。7系とは若干名称が異なります。データーベース専用のサーバーで使うのであれば、値を許容しうる上限にしておくと良いでしょう。

default_with_oids = on/off
デフォルトでoidをつけるかどうか。onかoffを指定します。oidを使わない場合はoffのままで大丈夫ですが、7系のプログラムでoidを使っている(可能性が少しでもある)場合は、onに設定しておくと良いでしょう。

PostgreSQL8.2系の場合

8.0/8.1系の設定に加えて、

standard_conforming_strings on/off
¥マークをエスケープ記号として扱う場合はon、単なる円を表すマークとして扱うならばoffにします。よくあるバグで、\1000と千円を表現するつもりが、8進数の1000と解釈されてしまいエラーになる事があり、そのため7系のプログラムでは¥を\\に変換するようになっています。互換性を保つのであればon、これから新しく開発するならoffが良いでしょう。

backslash_quote on/off
挿入する文字列の最後が\だと、\'という風にシングルクォートを閉じてるつもりが、シングルクォートがエスケープされてしまうのでエラーになるケースがあります。なので、\を\\にしてエスケープ記号ではなく単なる¥マークとしていると思います。これをonにすると¥がエスケープ記号となり、offにすると単なる円を表すマークになります。互換性を保つのであればon、これから新しく開発するならoffが良いでしょう。

escape_string_warning on/off
\を\\、'を\'という風にエスケープしている箇所を、エラーにせずワーニングにします。こうする事で、古いシステムから移行するの手助けになります。ワーニングにする時は、もう¥マークのエスケープをやめて、それをやってる箇所を書き直す時に使います。

以上の設定が完了したら
/etc/rc.d/init.d/postgresql stop
/etc/rc.d/init.d/postgresql start
ps ax | grep postmaster
としてみて、postmasterが常駐するかどうか確認します。メモリーの量を大きくしすぎるとpostmasterがダウンしてしまうので、常駐しない時はメモリー量の設定を少しずつ小さくしてみてください。

※restartとするとログが画面表示になってしまうので、stopしてstartします。

pg_hba.confの変更

接続を許すホストを指定します。pg_hba.confは、initdb した時に -Dで指定したディレクトリにあります。(例:/usr/local/pgsql/data/pg_hba.conf)
# TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD
# "local" is for Unix domain socket connections only
local   all         all                               trust
# IPv4 local connections:
host    all         all         127.0.0.1/32          trust
# IPv6 local connections:
host    all         all         ::1/128               trust
初期値はこんな風になっています。

ここで、
TYPE ソケットの種類
DATABASE データーベース名
USER ユーザー名
CIDR-ADDRESS 許可アドレス(またはアドレス帯)
METHOD 許可区分
という書式を、スペース区切りで記述します。(1つの設定が1行分になります)

・ソケットの種類
ローカルソケットかホストソケットかを指定します。PHP4.1以前ではローカルソケットさえ許可しておけば良かったのですが、PHP4.2以降ではhostソケットで127.0.0.1からのアクセスを許可しておく必要があります。これはPHPがhostソケット経由でPostgreSQLをアクセスするように変更になったためです。

・データーベース名、ユーザー名
どのデーターベースへ、どのユーザーを許可するかという意味です。「all」は「全部のデーターベース」「全部のユーザー」という意味になります。外部からの接続を許可する時は、allではなく厳密に設定する必要があります。

・許可アドレス(アドレス帯)
接続を許可するIPを指定します。ただし、/24とか/28みたいにサブネットマスクを指定する事で、アドレス帯に対して指定する事ができます。また、192.168.1.0 255.255.255.0 という風に、サブネットマスクをビット数ではなく、ネットマスクそのもので指定する事もできます。

・許可区分
trust(無条件許可)、password(パスワード必須)、MD5(暗号化パスワード必須)、reject(無条件拒否)等があります。trustに設定すると、パスワードなしで接続できるため、ローカルからメンテナンスするのが楽になります。ただし、外部からの接続をtrustで許可してしまうとセキュリティーが甘くなります。個人情報を扱う場合、外部からのtrustは禁物です。外部のallからのアクセスをtrustにするとデーターベースの中身がだだ漏れになるので、絶対にダメです。

password、md5は、いずれもパスワードを要求します。passwordは平文で要求するのに対し、md5は暗号化したパスワードを要求します。md5の他にもcrypt等があります。外部から平文でパスワードを要求すると万一中継ルーターを覗き見された時にパスワードがバレバレですので、md5等の暗号化パスワードを指定すると良いでしょう。

rejectに指定すると、指定のユーザー(または指定のDB)に対してアクセスの拒絶などを設定する事ができます。

・パスワードについて
PostgreSQLでは、createuserした地点の、そのユーザーのパスワード(/etc/shadow)をPostgreSQLのパスワードとして保存しますが、その後パスワードを変更する場合には、PostgreSQL内でパスワードを変更する必要があります。

alter user (ユーザー名) with password '(パスワード)';

phpPgAdminのインストール

phpを操作する時は、コマンドラインから

psql -U ユーザー名 DB名

として起動しますが、データーベースの中を確認するのにいちいち手動でselect * from table など入力しなければならず、いささか面倒です。そこで、ブラウザ上からデーターベースへアクセスすることのできる、phpPgAdminというソフトをインストールしてみましょう。

phpPgAdminは、PostgreSQLに対応したバージョンを使う必要があります。

まず、phpPgAdminのホームページ(http://phppgadmin.sourceforge.net/index.php)から、ソース一式(phpPgAdmin-バージョン番号.tar.gz)をダウンロードします。ダウンロードしたら、サーバーにアップします。サーバーにログインして、ブラウザから見えるディレクトリに移動し、ソースを解凍します。

tar xvzf phpPgAdmin-バージョン番号.tar.gz
すると、phpPgAdminが下にできますので移動し、vi等で初期設定ファイルを編集します。

cd phpPgAdmin
cd conf
vi config.inc.php

・config.inc.phpの変更箇所
$conf['servers'][0]['pg_dump_path'] = '/usr/bin/pg_dump';
$conf['servers'][0]['pg_dumpall_path'] = '/usr/bin/pg_dumpall';
この行はpg_dumpと、pg_dumpallコマンドのある場所をフルパスで指定します。デフォルトでは/usr/binになっていますが、PostgreSQLをソースを展開してインストールしたならば、パスは、/usr/local/pgsql/bin/となっているはずですので、/usrと/binの間に、/local/pgsqlを追加しておきましょう。
変更前
$conf['default_lang'] = 'english';
       ↓
変更後
$conf['default_lang'] = 'japanese';
デフォルトの言語を指定します。ここで指定しなくともログイン画面で選択することもできますが、ここを変更しておくとデフォルトの言語が「日本語」となり、ログインが若干楽になります。

このままでも使うことができますが、もしデーターベース上にEUCコードの日本語がある場合、データーベースを「表示」コマンドで表示させると日本語が化け化けになってしまいます。そこで、強引にブラウザのエンコードを強制指定します。viエディターで該当ファイルを開き、/コマンドで該当個所を探して変更します。

dataexport.php
変更前
echo "\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset={$data->codemap[$dbEncoding]}\" />\r\n";
           ↓
変更後
echo "\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=EUC-JP\" />\r\n";
classes/Misc.php
変更前
echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset={$lang['appcharset']}\" />\n";
          ↓
変更後
echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=EUC-JP\" />\n";
・セキュリティーの問題
このままでも使うことができますが、このままではこのディレクトリを第三者に発見されてしまうと、データーベースの中身が丸見えになってしまいます。そこで、このディレクトリにBASIC認証をかけましょう。

vi .htaccess
AuthUserFile /この場所/.htpasswd
AuthGroupFile /dev/null
AuthName "phpPgAdmin"
AuthType Basic
require valid-user
<Files ~ "^\.(htpasswd|htaccess)$">
deny from all
</Files>
このようなファイルを、phpPgAdminを展開したディレクトリにいれておきます。/この場所/の部分には現ディレクトリのフルパスをpwdコマンドで調べて入れておきます。

パスワードファイルを作成します。
/usr/local/apache2/bin/htpasswd -c .htpasswd ユーザー名

ここで、/usr/local/apache2は、apacheのインストールされているディレクトリです。デフォルトと違う場所にインストールした時は、その(apacheのインストールされた)ディレクトリを指定します。

ユーザー名任意ですが、あなたのUNIXアカウントでいいでしょう。パスワードを聞いてきますので入力します。確認のために再度同じパスワードを聞いてきますので、入力してください。すると、.htpasswdというファイルが作られ、ユーザー名:暗号化パスワードという形式でパスワードが記録されます。

このディレクトリにブラウザからアクセスすると、ブラウザがユーザー名とパスワードを聞いてきますので、今設定したユーザー名とパスワードを入れてください。
スポンサーリンク