The Sixwish project

Linux Notes / Slony-I

PostgreSQL + Slony-I 実験 2
『プライマリキーが二個のテーブル』と『プライマリキー無し』のテーブルの場合

PostgreSQL 7.4.x系と、レプリケーションを行うためのSlony-Iを使って、レプリケーションバックアップを行うと言う企画ネタ。
第三回である今回は、実験編の二回目。

ちなみにOSはWhiteBox Linux 3.x(RHEL3.x Clone)を使用しています。
なお、この文書にしたがって生じた損害などについては一切の責任を負いかねますのでご了承ください。

さて、今回の実験対象となるテーブルは、『プライマリキーが二個のテーブル』と『プライマリキー無し』になります。
また、実験環境その他については、前回にまとめたのでそれを参照のこと。

プライマリキー二個とプライマリキー無しのテーブル

初期設定は終わっているので、テーブルを追加する方式で実験を行う。
というわけで、追加するテーブルのSQL文を作成してMASTER、SLAVEへと展開する。

テーブル作成

まずは、対象となるデータベースとテーブルを作成します。

[postgres@labgk slony-master]$ cd ../sql
[postgres@labgk sql]$ vi pri2.sql
DROP table pri2;

CREATE TABLE pri2 (
   KEY1    int        not null -- primary key1
  ,KEY2    int        not null -- primary key2
  ,Update  timestamp  not null -- regist date/time
  ,primary key( KEY1, KEY2)
);
[postgres@labgk sql]$ vi nonepri.sql
DROP table nonepri;

CREATE TABLE nonepri (
   category  text       not null -- category
  ,contents  text       not null -- contents
  ,Update    timestamp  not null -- regist date/time
);
[postgres@labgk sql]$ psql -f pri2.sql whitecat
psql:pri2.sql:1: ERROR:  table "pri2" does not exist
psql:pri2.sql:8: NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "pri2_pkey" for table "pri2"
CREATE TABLE
[postgres@labgk sql]$ psql -f nonepri.sql whitecat
psql:nonepri.sql:1: ERROR:  table "nonepri" does not exist
CREATE TABLE
[postgres@labgk sql]$ psql -h 172.16.0.53 -f pri2.sql blackcat
psql:pri2.sql:1: ERROR:  table "pri2" does not exist
psql:pri2.sql:8: NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "pri2_pkey" for table "pri2"
CREATE TABLE
[postgres@labgk sql]$ psql -h 172.16.0.53 -f nonepri.sql blackcat
psql:nonepri.sql:1: ERROR:  table "nonepri" does not exist
CREATE TABLE
[postgres@labgk sql]$

Slony-I Slonik Script

slonの対象になるように、slonikスクリプトを書いてレプリケーションの対象にする。

[postgres@labgk sql]$ cd ../slony-master
[postgres@labgk slony-master]$ vi slony-master-setup-add-tbl_1.sh
#!/bin/bash

if [ ! -f ./slony-setup.sh ]; then
    echo 'slony-setup.sh file not found.\n'
    exit -1
fi
. ./slony-setup.sh


slonik <<_EOF_
  cluster name = $CLUSTERNAME;
# 
# 
  node 1 admin conninfo = 'dbname=$MASTERDBNAME host=$MASTERHOST user=$REPLICATIONUSER';
  node 2 admin conninfo = 'dbname=$SLAVEDBNAME host=$SLAVEHOST user=$REPLICATIONUSER';

# Drop set
# (現在存在するsetと同じモノにしたいので、一度setをdropしてしまう)
echo 'Drop set';
drop set (id=1, origin=1);

# Set created
# (あらためて、setを作成する)
echo 'Set created';
create set (id=1, origin=1, comment='$MASTERDBNAME tables');

# Set add table
# -- infomation
# (setを削除したので、あらためて登録する)
echo 'Set infomation table';
set add table (set id=1, origin=1, id=1, full qualified name = 'public.infomation', comment='infomation table');

# Set add table
# -- pri2 table
echo 'Set pri2 table';
set add table (set id=1, origin=1, id=2, full qualified name = 'public.pri2', comment='2 primary key table');

# table add key
# (プライマリキーが無いテーブルには、強制的にプライマリキーになるものを不可して管理する)
echo 'Add key nonepri table';
table add key ( node id = 1, fully qualified name = 'public.nonepri' );

# Set add tables
# -- pri2 table
echo 'Set nonepri table';
set add table (set id=1, origin=1, id=3, full qualified name = 'public.nonepri', key = serial, comment='no primary key table');

_EOF_

追加方式でやれると思っていたのだが、どうやら一度setを捨てないと駄目らしい。

さて、ここまで書いたところで、これらのスクリプトを実行します。

[postgres@labgk slony-master]$ sh slony-master-setup-add-tbl_1.sh
<stdin>:10: Drop set
<stdin>:15: Set created
CONFIG dropSet: set_id=1
<stdin>:18: Set infomation table
CONFIG storeSet: set_id=1 set_origin=1 set_comment='whitecat tables'
<stdin>:23: Set pri2 table
<stdin>:28: Add key nonepri table
<stdin>:33: Set nonepri table
[postgres@labgk slony-master]$

設定できたようなので、Insertする実験。

[postgres@labgk slony-master]$ psql whitecat
Welcome to psql 7.4.6, the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help on internal slash commands
       \g or terminate with semicolon to execute query
       \q to quit

whitecat=# \d
           List of relations
 Schema |    Name    | Type  |  Owner
--------+------------+-------+----------
 public | infomation | table | postgres
 public | nonepri    | table | postgres
 public | pri2       | table | postgres
(3 rows)

whitecat=# INSERT INTO public.pri2 VALUES ( 1, 1, 'now');
INSERT 287534 1
whitecat=# INSERT INTO public.pri2 VALUES ( 1, 2, 'now');
INSERT 287536 1
whitecat=# INSERT INTO public.pri2 VALUES ( 2, 1, 'now');
INSERT 287541 1
whitecat=# INSERT INTO public.pri2 VALUES ( 2, 2, 'now');
INSERT 287543 1
whitecat=# \q
[postgres@labgk slony-master]$ psql -h 172.16.0.53 blackcat
Welcome to psql 7.4.6, the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help on internal slash commands
       \g or terminate with semicolon to execute query
       \q to quit

blackcat=# SELECT * From pri2 ;
 key1 | key2 | update
------+------+--------
(0 rows)

blackcat=# \q
[postgres@labgk slony-master]$

レプリケーションされていない……と言うことで、MASTERサーバーの中をチェックする。

[postgres@labgk slony-master]$ psql whitecat
Welcome to psql 7.4.6, the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help on internal slash commands
       \g or terminate with semicolon to execute query
       \q to quit

whitecat=# SELECT * From _graycat.sl_table ;
 tab_id | tab_reloid | tab_set |            tab_idxname             | tab_altered |     tab_comment
--------+------------+---------+------------------------------------+-------------+----------------------
      1 |     286706 |       1 | infomation_pkey                    | t           | infomation table
      2 |     287292 |       1 | pri2_pkey                          | t           | 2 primary key table
      3 |     287296 |       1 | nonepri__Slony-I_graycat_rowID_key | t           | no primary key table
(3 rows)

whitecat=# SELECT * From _graycat.sl_subscribe ;
 sub_set | sub_provider | sub_receiver | sub_forward | sub_active
---------+--------------+--------------+-------------+------------
(0 rows)

whitecat=# \q
[postgres@labgk slony-master]$

どうやら、subscribeされていないのが悪いらしい。それならば、sh slony-start.shを実行して登録してしまえばよいと……言うことで、実行と確認。

[postgres@labgk slony-master]$ sh slony-start.sh
[postgres@labgk slony-master]$ psql -h 172.16.0.53 blackcat
Welcome to psql 7.4.6, the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help on internal slash commands
       \g or terminate with semicolon to execute query
       \q to quit

blackcat=# SELECT * From pri2 ;
 key1 | key2 |           update
------+------+----------------------------
    1 |    1 | 2005-02-18 17:45:29.996444
    1 |    2 | 2005-02-18 17:45:33.005604
    2 |    1 | 2005-02-18 17:45:36.635481
    2 |    2 | 2005-02-18 17:45:39.553217
(4 rows)

blackcat=# \q
[postgres@labgk slony-master]$ psql whitecat
Welcome to psql 7.4.6, the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help on internal slash commands
       \g or terminate with semicolon to execute query
       \q to quit

whitecat=# SELECT * From _graycat.sl_subscribe ;
 sub_set | sub_provider | sub_receiver | sub_forward | sub_active
---------+--------------+--------------+-------------+------------
       1 |            1 |            2 | f           | t
(1 row)

whitecat=# 

これでレプリケーションされていることが確認できたので、次はプライマリキーが無いテーブルに対して実行してみる。

whitecat=# INSERT INTO nonepri VALUES ( 'test', 'same record', '2005-02-18 18:00:00.000000');
INSERT 287646 1
whitecat=# INSERT INTO nonepri VALUES ( 'test', 'same record', '2005-02-18 18:00:00.000000');
INSERT 287648 1
whitecat=# SELECT * From nonepri ;
 category |  contents   |       update        | _Slony-I_graycat_rowID
----------+-------------+---------------------+------------------------
 test     | same record | 2005-02-18 18:00:00 |       1000000000000001
 test     | same record | 2005-02-18 18:00:00 |       1000000000000002
(2 rows)

whitecat=# \q
[postgres@labgk slony-master]$ psql -h 172.16.0.53 blackcat
Welcome to psql 7.4.6, the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help on internal slash commands
       \g or terminate with semicolon to execute query
       \q to quit

blackcat=# SELECT * From nonepri ;
 category |  contents   |       update        | _Slony-I_graycat_rowID
----------+-------------+---------------------+------------------------
 test     | same record | 2005-02-18 18:00:00 |       1000000000000001
 test     | same record | 2005-02-18 18:00:00 |       1000000000000002
(2 rows)

blackcat=#

……なんか、強制的に付けちゃうみたいですね……まぁ、リレーショナルDBだから影響は少ないと思うけど、結構はた迷惑な機能だな……

結論。Slony-Iを使うのであれば、素直にプライマリキーを設定したほうが身のため。

まぁ、プライマリキーがいくつあってもおかしなことにはなりそうも無いので、そちらは良い。問題はプライマリキーが設定されていないテーブルに対する処置だね。唐突にああいうものが付属しているとちと憂鬱気分に……

もっとも、一度作成してしまえば滅多に作り変えないものであれば、早々影響は無いだろう。但し、仕様変更などがあった場合に一苦労しそう。