雑文発散

«前の日記(2011-02-15) 最新 次の日記(2011-09-19)» 編集
過去の日記

2011-08-13 [長年日記]

[PostgreSQL] PostgreSQL 9.1 Beta3 でストリーミング・レプリケーションを試してみた #1

PostgreSQL の勉強を一番頑張ってやっていたのは、バージョン 6.5 とかの頃で、7.4 の Silver 試験には受かったけど Gold には落ちたとか、そんな程度でボチボチやっていたんだけど、もうちょっと最新情報を追いかけようと思って PostgreSQL 9.1 Beta3 に手を出してみた。今回は、ストリーミング・レプリケーションのお試し。

うまい具合に(?)、Let's Postgres に「ストリーミング・レプリケーションの構築」という記事が上がっていたので、これをなぞることにした。

サーバ環境は Amazon EC2 上で、CentOS 5.6 x86_64 のマイクロインスタンスを2台使って構築。PostgreSQL は、本家の Yum Repository に 9.1 版も用意されていたので、そいつを使ってサクっとインストール、、、したのは良かったんだけど、yum でインストールできるのは、9.1 alpha3 が最新だった。

それだけなら、まぁ、いいかとも思ったんだけど、前述の記事にある「CREATE ROLE repl_user LOGIN REPLICATION PASSWORD '...';」の実行ができずにハマった。どうやら、alpha3 の段階では「REPLICATION」という Role が存在していなかった模様で、指定してもエラーになってしまった。

仕方ないので、ソースからコンパイルしようとしたら、今度は configure の段階で「おまえの flex は古過ぎる」と言われてストップ。CentOS 上では最新なのにねぇ。。。

ということで、第三の手段として、EnterpriseDB 社が配布しているワンクリックインストーラを使ってインストールしてみた。前から、インストーラを配布しているというのは知っていたけど、実際に使ってみたのは初めてだったけど、まぁ、なんとか使うことができた。

このワンクリックインストーラの日本語情報はあんまり無いようなイメージを持っているので、なんか適当にココへ記録しておく。

[PostgreSQL] PostgreSQL 9.1 Beta3 でストリーミング・レプリケーションを試してみた #2

ではインストール。EnterpriseDB 社のダウンロードページから、自分の OS に合ったインストーラを選択する。今回は Linux x86_64 をクリック。そのままダウンロードされるけど、まぁ、Linux からなら wget 使うよね。

# wget http://get.enterprisedb.com/postgresql/postgresql-9.1.beta3-linux-x64.bin

実行権限を付けて、実行。

# chmod +x postgresql-9.1.beta3-linux-x64.bin
# ./postgresql-9.1.beta3-linux-x64.bin

ここからインストーラが動いて、いくつか質問してくるので答えていく。お試しで動かす分には全てデフォルトの答えで良いんじゃないかと思う。

----------------------------------------------------------------------------
Welcome to the PostgreSQL Setup Wizard.
 
----------------------------------------------------------------------------
Please specify the directory where PostgreSQL will be installed.
 
Installation Directory [/opt/PostgreSQL/9.1]:  ←【インストール先のディレクトリ】
 
----------------------------------------------------------------------------
Please select a directory under which to store your data.
 
Data Directory [/opt/PostgreSQL/9.1/data]: ←【データディレクトリ(PGDATA)】
 
----------------------------------------------------------------------------
Please provide a password for the database superuser (postgres). A locked Unix
user account (postgres) will be created if not present.
 
Password :             ←【postgresユーザのパスワード】
Retype password :      ←【postgresユーザのパスワード(確認)】
----------------------------------------------------------------------------
Please select the port number the server should listen on.
 
Port [5432]: ←【postgres サーバの稼働ポート】
 
----------------------------------------------------------------------------
Advanced Options
 
Select the locale to be used by the new database cluster.
 
Locale
 
[1] [Default locale]
[2] C
[3] POSIX
[4] aa_DJ
[5] aa_DJ.iso88591
[6] aa_DJ.utf8
[7] aa_ER
【中略】
[631] zu_ZA
[632] zu_ZA.iso88591
[633] zu_ZA.utf8
Please choose an option [1] : 1 ←【locale の選択】
----------------------------------------------------------------------------
Setup is now ready to begin installing PostgreSQL on your computer.
 
Do you want to continue? [Y/n]: ←【インストールの最終確認】
 
----------------------------------------------------------------------------
Please wait while Setup installs PostgreSQL on your computer.
 
 Installing
 0% ______________ 50% ______________ 100%
 #########################################
 
----------------------------------------------------------------------------
Setup has finished installing PostgreSQL on your computer.
 
Launch Stack Builder at exit?
 
Stack Builder may be used to download and install additional tools, drivers and applications to complement your PostgreSQL installation. [Y/n]: ←【良く分かってない】

これでインストールは終わり。この状態で postgres サーバが起動状態になっているのが、個人的にはちょっとキモいかなぁ。ちなみにサーバの起動スクリプトは、 /etc/init.d/postgresql-9.1 にインストールされるので、CentOS の標準的なやり方で start / stop などができる。

ここから先の設定は、「ストリーミング・レプリケーションの構築」の記事に従っただけなので、ここでは割愛。リンク先の素晴らしい記事を読むのだ、みんな。

[PostgreSQL] PostgreSQL 9.1 Beta3 でストリーミング・レプリケーションを試してみた #3

ストリーミング・レプリケーションの設定が終わったので、簡単なお試しをしてみた。ここから先は postgres ユーザでの実行。

マスタのデータベースリスト

$ /opt/PostgreSQL/9.1/bin/psql -l
                              List of databases
    Name    |  Owner   | Encoding  | Collate | Ctype |   Access privileges
 -----------+----------+-----------+---------+-------+-----------------------
  postgres  | postgres | SQL_ASCII | C       | C     |
  template0 | postgres | SQL_ASCII | C       | C     | =c/postgres          +
            |          |           |         |       | postgres=CTc/postgres
  template1 | postgres | SQL_ASCII | C       | C     | =c/postgres          +
            |          |           |         |       | postgres=CTc/postgres
 (3 rows)

スタンバイのデータベースリスト

$ /opt/PostgreSQL/9.1/bin/psql -l
                              List of databases
    Name    |  Owner   | Encoding  | Collate | Ctype |   Access privileges
 -----------+----------+-----------+---------+-------+-----------------------
  postgres  | postgres | SQL_ASCII | C       | C     |
  template0 | postgres | SQL_ASCII | C       | C     | =c/postgres          +
            |          |           |         |       | postgres=CTc/postgres
  template1 | postgres | SQL_ASCII | C       | C     | =c/postgres          +
            |          |           |         |       | postgres=CTc/postgres
 (3 rows)

マスタで testdb を作成・確認

 $ /opt/PostgreSQL/9.1/bin/createdb --encoding=UTF-8 --locale=C --template=template0 testdb
 $ /opt/PostgreSQL/9.1/bin/psql -l
                              List of databases
    Name    |  Owner   | Encoding  | Collate | Ctype |   Access privileges
 -----------+----------+-----------+---------+-------+-----------------------
  postgres  | postgres | SQL_ASCII | C       | C     |
  template0 | postgres | SQL_ASCII | C       | C     | =c/postgres          +
            |          |           |         |       | postgres=CTc/postgres
  template1 | postgres | SQL_ASCII | C       | C     | =c/postgres          +
            |          |           |         |       | postgres=CTc/postgres
  testdb    | postgres | UTF8      | C       | C     |
 (4 rows)

スタンバイでデータベースリストを確認。スタンバイ側にも testdb が作成されている。

 $ /opt/PostgreSQL/9.1/bin/psql -l
                              List of databases
    Name    |  Owner   | Encoding  | Collate | Ctype |   Access privileges
 -----------+----------+-----------+---------+-------+-----------------------
  postgres  | postgres | SQL_ASCII | C       | C     |
  template0 | postgres | SQL_ASCII | C       | C     | =c/postgres          +
            |          |           |         |       | postgres=CTc/postgres
  template1 | postgres | SQL_ASCII | C       | C     | =c/postgres          +
            |          |           |         |       | postgres=CTc/postgres
  testdb    | postgres | UTF8      | C       | C     |
 (4 rows)

続いてテーブル作成の確認。まずはマスタにもスタンバイにもテーブルが存在しないことを確認。

マスタにはテーブルが存在していない。

 $ /opt/PostgreSQL/9.1/bin/psql testdb
 testdb=# \d
 No relations found.

スタンバイにもテーブルが存在していない。

$ /opt/PostgreSQL/9.1/bin/psql testdb
 testdb=# \d
 No relations found.

マスタでテーブルを作成。シリアル型とかタイムスタンプ型とかを定義。

testdb=# CREATE TABLE test (id SERIAL, name TEXT, created TIMESTAMP);
 NOTICE:  CREATE TABLE will create implicit sequence "test_id_seq" for serial column "test.id"
 CREATE TABLE
 testdb=# \d test
                                     Table "public.test"
  Column  |            Type             |                     Modifiers
 ---------+-----------------------------+---------------------------------------------------
  id      | integer                     | not null default nextval('test_id_seq'::regclass)
  name    | text                        |
  created | timestamp without time zone |

スタンバイでテーブルを確認。ちゃんとレプリケーションされてきた。

testdb=# \d test
                                    Table "public.test"
 Column  |            Type             |                     Modifiers
---------+-----------------------------+---------------------------------------------------
 id      | integer                     | not null default nextval('test_id_seq'::regclass)
 name    | text                        |
 created | timestamp without time zone |

マスタでデータを INSERT してみる。シリアル型とかタイムスタンプとかどうなるのかチェック。

testdb=# INSERT INTO test (name, created) VALUES ('hoge', now());
 INSERT 0 1
 testdb=# SELECT * FROM test;
  id | name |          created
 ----+------+----------------------------
   1 | hoge | 2011-08-13 04:15:43.168896
 (1 row)

スタンバイで確認。シリアル型の id もタイムスタンプ型の created もマスタと同じ値が出ている。

testdb=# SELECT * FROM test;
  id | name |          created
 ----+------+----------------------------
   1 | hoge | 2011-08-13 04:15:43.168896
 (1 row)

マスタでシリアル型の数値を進めてから、INSERT してみる。

testdb=# SELECT nextval('test_id_seq');
  nextval
 ---------
        2
 (1 row)
 
 testdb=# SELECT nextval('test_id_seq');
  nextval
 ---------
        3
 (1 row)
 
 testdb=# SELECT nextval('test_id_seq');
  nextval
 ---------
        4
 (1 row)
 
 testdb=# SELECT nextval('test_id_seq');
  nextval
 ---------
        5
 (1 row)
 
 testdb=# SELECT nextval('test_id_seq');
  nextval
 ---------
        6
 (1 row)
 
 testdb=# INSERT INTO test (name, created) VALUES ('fuga', now());
 INSERT 0 1
 testdb=# SELECT * FROM test;
  id | name |          created
 ----+------+----------------------------
   1 | hoge | 2011-08-13 04:15:43.168896
   7 | fuga | 2011-08-13 04:17:30.62726
 (2 rows)

スタンバイ側で確認。シリアル値は追従している。

testdb=# SELECT * FROM test;
  id | name |          created
 ----+------+----------------------------
   1 | hoge | 2011-08-13 04:15:43.168896
   7 | fuga | 2011-08-13 04:17:30.62726
 (2 rows)

ラージオブジェクトはどうなるのか? マスタで import してみる。

$ ll /tmp/postgresql-9.1beta3.tar.bz2
 -rw-r--r-- 1 root root 14773133 Jul  7 20:20 /tmp/postgresql-9.1beta3.tar.bz2
 
 testdb=# \lo_import /tmp/postgresql-9.1beta3.tar.bz2
 lo_import 16405
 testdb=# \lo_list
          Large objects
   ID   |  Owner   | Description
 -------+----------+-------------
  16405 | postgres |
 (1 row)

スタンバイで export してみる。ラージオブジェクトの ID も同じだし、export したファイルサイズも同じ。ちゃんと tar の展開もできた。owner が違うのは、スタンバイでの実行ユーザが postgres だからなので、ここでは問題ではない。

testdb=# \lo_list
          Large objects
   ID   |  Owner   | Description
 -------+----------+-------------
  16405 | postgres |
 (1 row)
 testdb=# \lo_export 16405 /tmp/postgresql-9.1beta3.tar.bz2
 lo_export
 
  $ ll /tmp/postgresql-9.1beta3.tar.bz2
  -rw-r--r-- 1 postgres postgres 14773133 Aug 13 04:21 /tmp/postgresql-9.1beta3.tar.bz2

というところで、当たり前だけどシリアル値やタイムスタンプ、ラージオブジェクトもレプリケーションできていたし、スタンバイ側で参照操作もできた。とはいえ、ここまでは、9.0 でもできていた非同期レプリケーションの筈なので、同期レプリケーションについては、まだ試していない。それから、障害時の対応についても試せていない。もうちょっと頑張らねば。

あ、ちなみにスタンバイで試しに INSERT してみたら、ちゃんとエラーになったよ。

testdb=# INSERT INTO test (name, created) VALUES ('hage', now());
 ERROR:  cannot execute INSERT in a read-only transaction

ストリーミング・レプリケーションを試してみた感想としては、複雑な設定もなく、割と簡単。スタンバイ側での初期データの準備も 9.1 で入ったという pg_basebackup コマンドのおかげて準備は楽だった。こうなってくると「同期レプリケーション」にも期待が高まる訳だけど、「PostgreSQL 9.1 の新機能」に少し気になる記述が。

同期モードでは遅延をゼロに抑えられるため、高い信頼性を求められる用途へもレプリケーションの適用範囲が広がりました。 ただし、ここでの「同期」とは、「結果を失わない」という意味であることに注意してください。同期モードであっても、更新直後にスレーブで参照クエリ実行すると、まだ更新が反映されていない場合があります。

この記事を読むまで「同期」の意味を間違えて把握していた。危ない危ない。