PostgreSQL (日本語) - ArchWiki

# PostgreSQL (日本語)

関連記事

- PhpPgAdmin

PostgreSQL はオープンソースの、コミュニティドリブンな、標準準拠のオブジェクト関係データベースシステムです。

この文章では PostgreSQL をセットアップする方法を説明してします。リモートクライアントから PostgreSQL にアクセスできるようにする設定方法も紹介します。データベース以外のウェブスタックの設定については、LAMP ページが役立つでしょう。MySQL に関連するセクション以外のところを見て下さい。

## はじめに

"postgres ユーザーになってください" という記述がセクションのところどころで出てくることがあります。この記事では postgres ユーザーで実行するべきコマンドには `[postgres]$` と記しています。

postgres ユーザーのシェルになるには root で次のコマンドを実行します:

    # su - postgres

sudo を使う場合、以下のコマンドを使用します:

    $ sudo -i -u postgres

postgres ユーザーは PostgreSQL をインストールしたときに自動で作成されます。ユーザーが作成されたら postgres ユーザーのパスワードを設定してください。

## PostgreSQL のインストール

公式リポジトリから postgresql をインストールしてください。

PostgreSQL を正しく機能させるには、postgres ユーザーでデータベースクラスタを初期化する必要があります。postgres ユーザーになって次のコマンドを実行してください:

    [postgres]$ initdb --locale en_US.UTF-8 -E UTF8 -D '/var/lib/postgres/data'

`postgresql` サービスを起動・有効化してください。

Warning:

- データベースを Btrfs ファイルシステム上に配置する場合は、データベースを作成する前に Copy-on-Write を無効化するべきです。

## 最初のデータベース/ユーザーの作成

Tip: If you create a PostgreSQL user with the same name as your Linux username, it allows you to access the PostgreSQL database shell without having to specify a user to login (which makes it quite convenient).

postgres ユーザーになってください。createuser コマンドを使って新しいデータベースユーザーを追加します:

    [postgres]$ createuser --interactive

createdb コマンドを使って読み書き権限がある前記のユーザーに新しいデータベースを作成します (データベースユーザーの名前が Linux ユーザーと同じ場合はログインシェルからコマンドを実行してください、もしくはコマンドに `-U database-username` を加えて下さい):

    $ createdb myDatabaseName

## PostgreSQL の習熟

### データベースシェルにアクセス

postgres ユーザーになってください。基本のデータベースシェル psql を起動します。psql ではデータベースやテーブルの作成・削除・パーミッションの設定・生の SQL コマンドの実行など全てが行えます。"-d" オプションを使って作成済みのデータベースに接続します (データベースを指定しなかった場合、psql はユーザー名と同じ名前のデータベースにアクセスします)

    [postgres]$ psql -d myDatabaseName

便利なコマンド:

ヘルプを表示

    => \help

特定のデータベースに接続

    => \c <database>

全てのユーザーとパーミッションレベルを表示

    => \du

現在のデータベースにある全てのテーブルのサマリー情報を表示

    => \dt

psql シェルを終了

    => \q or CTRL+d

多数のメタコマンドが存在しますが、最初は以上のコマンドで十分でしょう。

## 任意の設定

### リモートホストから PostgreSQL にアクセスできるように設定

PostgreSQL データベースサーバーの設定ファイルは `postgresql.conf` です。このファイルはサーバーのデータディレクトリ (通常は `/var/lib/postgres/data`) に配置されています。このフォルダには `pg_hba.conf` など、その他のメインの設定ファイルも保存されます。

Note: デフォルトでは、通常ユーザーを使ってこのフォルダを見ることは不可能になっているため、`find` や `locate` で conf ファイルを探そうとしても見つかりません。

`/var/lib/postgres/data/postgresql.conf` ファイルを編集します。接続と認証のセクションに `listen_addresses` という行を追加してください:

    listen_addresses = 'localhost,my_remote_ip_address'

他の行を注意して見て下さい。

ホストによる認証は `/var/lib/postgres/data/pg_hba.conf` で設定します。このファイルでは接続を許可するホストをコントロールします。デフォルトでは、データベースのスーパーユーザーを含め、あらゆるデータベースユーザーとして全てのローカルユーザーが接続できるようになっているので注意してください。以下のように行を追加します:

    # IPv4 local connections:
    host   all   all   my_remote_ip_address/32   md5

`your_desired_ip_address` はクライアントの IP アドレスに置き換えて下さい。

pg_hba.conf のドキュメントも参照。

設定をした後は、`postgresql` デーモンを再起動して変更を適用してください。

Note: Postgresql uses port 5432 by default for remote connections. So make sure this port is open and able to receive incoming connections.

トラブルシューティングの際はサーバーのログファイルを見て下さい:

    $ journalctl -u postgresql

### デフォルトのデータディレクトリを変更

新しく作成したデータベースが保存されるデフォルトのディレクトリは `/var/lib/postgres/data` です。これを変更するには、以下の手順を踏んで下さい:

新しいディレクトリを作成して postgres ユーザーをディレクトリの所有者にする:

    # mkdir -p /pathto/pgroot/data
    # chown -R postgres:postgres /pathto/pgroot

postgres ユーザーになって、新しいクラスタを初期化:

    [postgres]$ initdb -D /pathto/pgroot/data

`postgres.service` が有効になっていたら、無効にする。`/usr/lib/systemd/system/postgresql.service` を `/etc/systemd/system/postgresql.service` にコピーして、ファイルを編集してデフォルトの `PGROOT` と `PIDFile` のパスを変更する。

    Environment=PGROOT=/pathto/pgroot/
    ...
    PIDFile=/pathto/pgroot/data/postmaster.pid

### 新しいデータベースのデフォルトエンコーディングを UTF-8 に変更

Note: If you ran `initdb` with `-E UTF8` these steps are not required

(`createdb blog` などで) 新しいデータベースを作成するとき、PostgreSQL は実際にはテンプレートデータベースをコピーしています。2つの定義済みテンプレートが存在します: template0 が標準のテンプレートである一方、オンサイトの template1 は管理者によって変更を加えることができるテンプレートでデフォルトで使用されます。新しいデータベースのエンコーディングを変更するには、オンサイトの template1 を変更します。PostgresSQL シェル (psql) にログインして以下を実行してください:

まず、template1 を削除する必要があります。テンプレートは削除できないので、最初に template1 を通常のデータベースにします:

    UPDATE pg_database SET datistemplate = FALSE WHERE datname = 'template1';

そして template1 を削除:

    DROP DATABASE template1;

次に、新しいデフォルトエンコーディングを使って、template0 から新しいデータベースを作成します:

    CREATE DATABASE template1 WITH TEMPLATE = template0 ENCODING = 'UNICODE';

そして template1 をテンプレートに戻します:

    UPDATE pg_database SET datistemplate = TRUE WHERE datname = 'template1';

(任意) このテンプレートに接続できないようにしたい場合、datallowconn を FALSE に設定してください:

    UPDATE pg_database SET datallowconn = FALSE WHERE datname = 'template1';

Note: this last step can create problems when upgrading via `pg_upgrade`.

これで新しいデータベースを作成することが出来るようになりました:

    [postgres]$ createdb blog

psql にまたログインしてデータベースを確認すれば、新しいデータベースに適切なエンコーディングがあるのを見れるはずです:

    \l

                                  List of databases
      Name    |  Owner   | Encoding  | Collation | Ctype |   Access privileges
    -----------+----------+-----------+-----------+-------+----------------------
    blog      | postgres | UTF8      | C         | C     |
    postgres  | postgres | SQL_ASCII | C         | C     |
    template0 | postgres | SQL_ASCII | C         | C     | =c/postgres
                                                         : postgres=CTc/postgres
    template1 | postgres | UTF8      | C         | C     |

## 管理ツール

- phpPgAdmin — PostgreSQL のウェブベースの管理ツール。

  http://phppgadmin.sourceforge.net || phppgadmin

- pgAdmin — PostgreSQL の GUI ベースの管理ツール。

  http://www.pgadmin.org/ || pgadmin3

## PostgreSQL のアップグレード

### クイックガイド

以下は 9.2 から 9.3 へのアップグレードです。

     pacman -S --needed postgresql-old-upgrade
     su -
     su - postgres -c 'mv /var/lib/postgres/data /var/lib/postgres/data-9.2'
     su - postgres -c 'mkdir /var/lib/postgres/data'
     su - postgres -c 'initdb --locale en_US.UTF-8 -E UTF8 -D /var/lib/postgres/data'

pg_hba.conf や postgresql.conf などの設定ファイルをカスタマイズしている場合、新しい設定ファイルにマージしてください。そして:

     su - postgres -c 'pg_upgrade -b /opt/pgsql-9.2/bin/ -B /usr/bin/ -d /var/lib/postgres/data-9.2 -D /var/lib/postgres/data'

"pg_upgrade" が失敗する場合:

- cannot write to log file pg_upgrade_internal.log
  Failure, exiting
  "postgres" ユーザーに、ログファイルをディレクトリに書き出す権限がちゃんとあるか確認してください (例えば `/tmp`)。もしくは "sudo -u postgres" のかわりに "su - postgres" を使って下さい。
- LC_COLLATE error that says that old and new values are different
  Figure out what the old locale was, C or en_US.UTF-8 for example, and force it when calling initdb.

     sudo -u postgres LC_ALL=C initdb -D /var/lib/postgres/data

- There seems to be a postmaster servicing the old cluster.
  Please shutdown that postmaster and try again.
  Make sure postgres isn't running. If you still get the error then chances are these an old PID file you need to clear out.

     > sudo -u postgres ls -l /var/lib/postgres/data-9.2
       total 88
       -rw------- 1 postgres postgres     4 Mar 25  2012 PG_VERSION
       drwx------ 8 postgres postgres  4096 Jul 17 00:36 base
       drwx------ 2 postgres postgres  4096 Jul 17 00:38 global
       drwx------ 2 postgres postgres  4096 Mar 25  2012 pg_clog
       -rw------- 1 postgres postgres  4476 Mar 25  2012 pg_hba.conf
       -rw------- 1 postgres postgres  1636 Mar 25  2012 pg_ident.conf
       drwx------ 4 postgres postgres  4096 Mar 25  2012 pg_multixact
       drwx------ 2 postgres postgres  4096 Jul 17 00:05 pg_notify
       drwx------ 2 postgres postgres  4096 Mar 25  2012 pg_serial
       drwx------ 2 postgres postgres  4096 Jul 17 00:53 pg_stat_tmp
       drwx------ 2 postgres postgres  4096 Mar 25  2012 pg_subtrans
       drwx------ 2 postgres postgres  4096 Mar 25  2012 pg_tblspc
       drwx------ 2 postgres postgres  4096 Mar 25  2012 pg_twophase
       drwx------ 3 postgres postgres  4096 Mar 25  2012 pg_xlog
       -rw------- 1 postgres postgres 19169 Mar 25  2012 postgresql.conf
       -rw------- 1 postgres postgres    48 Jul 17 00:05 postmaster.opts
       -rw------- 1 postgres postgres    80 Jul 17 00:05 postmaster.pid   # <-- This is the problem

     > sudo -u postgres mv /var/lib/postgres/data-9.2/postmaster.pid /tmp

- ERROR: could not access file "$libdir/postgis-2.0": No such file or directory
  Retrieve postgis-2.0.so from postgis package for version postgresql 9.2 () and copy it to /opt/pgsql-9.2/lib (make sure the privileges are right)

### 詳細な手順

Note: PostgreSQL の公式の アップグレードドキュメント に従って下さい。

以下の手順はデータを喪失する可能性があります。自己責任でお願いします。

It is recommended to add the following to your `/etc/pacman.conf` file:

    IgnorePkg = postgresql postgresql-libs

This will ensure you do not accidentally upgrade the database to an incompatible version. When an upgrade is available, pacman will notify you that it is skipping the upgrade because of the entry in pacman.conf. Minor version upgrades (e.g., 9.0.3 to 9.0.4) are safe to perform. However, if you do an accidental upgrade to a different major version (e.g., 9.0.X to 9.1.X), you might not be able to access any of your data. Always check the PostgreSQL home page (http://www.postgresql.org/) to be sure of what steps are required for each upgrade. For a bit about why this is the case see the versioning policy.

PostgreSQL データベースをアップグレードする方法は大きく2つあります。詳しくは公式のドキュメントを読んで下さい。

For those wishing to use `pg_upgrade`, a postgresql-old-upgrade package is available in the repositories that will always run one major version behind the real PostgreSQL package. This can be installed side by side with the new version of PostgreSQL. When you are ready to perform the upgrade, you can do

    pacman -Syu postgresql postgresql-libs postgresql-old-upgrade

Note also that the data directory does not change from version to version, so before running pg_upgrade it is necessary to rename your existing data directory and migrate into a new directory. The new database must be initialized, as described near the top of this page.

    # systemctl stop postgresql
    # su - postgres -c 'mv /var/lib/postgres/data /var/lib/postgres/olddata'
    # su - postgres -c 'initdb --locale en_US.UTF-8 -E UTF8 -D /var/lib/postgres/data'

詳しくは上流の pg_upgrade のドキュメント を参照。

The upgrade invocation will likely look something like the following (run as the postgres user). Do not run this command blindly without understanding what it does!

    # su - postgres -c 'pg_upgrade -d /var/lib/postgres/olddata/ -D /var/lib/postgres/data/ -b /opt/pgsql-8.4/bin/ -B /usr/bin/'

#### 手動のダンプとリロード

You could also do something like this (after the upgrade and install of postgresql-old-upgrade) (NB: below is command for postgres8.4 update, you can find similar command in /opt/ for postgres 9.2 update. )

    # systemctl stop postgresql
    # /opt/pgsql-8.4/bin/pg_ctl -D /var/lib/postgres/olddata/ start
    # /opt/pgsql-8.4/bin/pg_dumpall >> old_backup.sql
    # /opt/pgsql-8.4/bin/pg_ctl -D /var/lib/postgres/olddata/ stop
    # systemctl start postgresql
    # psql -f old_backup.sql postgres

## トラブルシューティング

### 小規模なトランザクションのパフォーマンスを向上させる

If you are using PostgresSQL on a local machine for development and it seems slow, you could try turning synchronous_commit off in the configuration. Beware of the caveats, however.

    /var/lib/postgres/data/postgresql.conf

    synchronous_commit = off

### アイドル状態の際にディスクの書き込みを止めさせる

PostgreSQL は定期的に内部の "statistics" ファイルを更新しています。デフォルトでは、このファイルはディスク上に保存されるため、ノートパソコンのディスクのスピンダウンの妨げになったり、ハードドライブのシーク音が発生したりします。以下の設定オプションを使うことでこのファイルをメモリ上のファイルシステムに再配置することができます:

    /var/lib/postgres/data/postgresql.conf

    stats_temp_directory = '/run/postgresql'

### pg_connect() でデータベースに接続できない

php-pgsql をインストールして `php.info` ファイルを編集して `extension=pdo_pgsql.so` や `extension=pgsql.so` という行をアンコメントして httpd を再起動してください。

Categories:

- Database management systems (日本語)
- Web Server (日本語)