PostgreSQLにおけるコンペアツールに関する報告

SRA OSS, Inc. 日本支社

pgpool、Slony-Iなどのレプリケーションシステムにおいてレプリケーション機能の有効性を容易に評価できるようにするため、2台の異なるデータベースに存在するテーブル間のデータを比較して差異を確認するコンペアツールを作成した。 ここでは、コンペアツールの概要を述べるとともに、その有効性について評価する。

概要

コンペアツールは、2台の異なるデータベースに存在するテーブル間のデータを比較し、データに差異があるかということを表示する。 データベースではデータの物理的な並びは保証されていないため、コンペアツールでは指定された列によって並び替えた結果に基づいてデータを比較する。 データを比較する際にはdiffコマンドを使用する。

ダウンロード

インストール

pgdiff.sh.gzをダウンロードして伸長すれば、そのままシェルスクリプトとして実行することが可能である。

$ gunzip pgdiff.sh.gz

なお、pgdiff.shではpsqlコマンドを使用するため、あらかじめPostgreSQLをインストールし、環境変数PATHにpsqlコマンドが存在するディレクトリを設定する必要がある。 PostgreSQLが/usr/local/pgsqlディレクトリにインストールされている場合、以下のように環境変数PATHを設定する。

$ export PATH=/usr/local/pgsql/bin:$PATH

使用方法

コンペアツールの使用方法は以下のとおりである。

./pgdiff [オプション...] テーブル名

また、指定できるオプションは以下のとおりである。

--mhost ホスト名
マスタのホスト名 (デフォルト: localhost)
--mport ポート番号
マスタのポート番号 (デフォルト: 5432)
--muser ユーザ名
マスタのユーザ名 (デフォルト: Unixのユーザ名)
--shost ホスト名
スレーブのホスト名 (デフォルト: localhost)
--sport ポート番号
スレーブのポート番号 (デフォルト: 5432)
--suser ユーザ名
スレーブのユーザ名 (デフォルト: Unixのユーザ名)
--database データベース名
比較するテーブルが存在するデータベース名 (デフォルト: Unixのユーザ名)
--sortcol 列名...
テーブルを比較する際に並び替えの対象となる列名 (複数の列名を指定する場合は列名をスペースによって区切る)
-h
--help
ヘルプを表示する

例えば、ホストmasterservとslaveservのtestdbデータベースに存在するaccountsテーブルのデータをid列で並び替えてから比較する場合は以下のとおりである。 データに差異があればマスタとスレーブ間のデータの異なる行が表示され、差異がなければ何も表示されない。

$ ./pgdiff.sh --mhost masterserv --shost slaveserv --database testdb --sortcol id accounts

評価結果

コンペアツールの有効性を確認するため、2台のデータベースのテーブルに以下の条件のもとでデータを格納し、コンペアツールによって期待したとおりにデータの差異が確認できることを評価した。

  • 同じデータを格納した場合
  • 異なるデータを格納した場合
  • 同じデータを格納したが、物理的な行の並びが異なる場合

評価に際しては、PostgreSQL 8.1.5を使用し、異なるポート番号5432、5433で動作するデータベースに対してpgbenchによってデータを初期化し、コンペアツールによってaccountsテーブルのデータの差異を確認した。

同じデータを格納した場合

accountsテーブルには、データを初期化してから操作されておらず、まったく同じデータが格納されている。

$ pgbench -i -p 5432
creating tables...
10000 tuples done.
(snip)
vacuum...done.
$ pgbench -i -p 5433
creating tables...
10000 tuples done.
(snip)
vacuum...done.
$ ./pgdiff.sh --mport 5432 --sport 5433 accounts

コンペアツールを実行したが何も表示されず、同じデータが格納されている場合に差異がないことを確認できた。

異なるデータを格納した場合

accountsテーブルには、INSERTコマンドによって異なるデータを挿入しており、異なるデータが格納されている。

$ pgbench -i -p 5432
creating tables...
10000 tuples done.
(snip)
vacuum...done.
$ psql -p 5432 -c "INSERT INTO accounts (aid, bid, abalance) VALUES (100001, 1, 0)"
INSERT 0 1
$ pgbench -i -p 5433
creating tables...
10000 tuples done.
(snip)
vacuum...done.
$ psql -p 5433 -c "INSERT INTO accounts (aid, bid, abalance) VALUES (100001, 1, 1)"
INSERT 0 1
$ ./pgdiff.sh --mport 5432 --sport 5433 accounts
100003c100003
<  100001 |   1 |        0 |
---
>  100001 |   1 |        1 |

コンペアツールを実行するとデータの異なる行が表示され、異なるデータが格納されている場合に差異があることを確認できた。

同じデータが格納したが、物理的な行の並びが異なる場合

accountsテーブルには、INSERTコマンドによって2行の同じデータを異なる並びで挿入しており、同じデータが格納されているが物理的な行の並びが異なっている。 なお、コンペアツールを実行する際にはaccountsテーブルのプライマリキーであるaid列を並び替えの対象として指定した。

$ pgbench -i -p 5432
creating tables...
10000 tuples done.
(snip)
vacuum...done.
$ psql -p 5432 -c "INSERT INTO accounts (aid, bid, abalance) VALUES (100001, 1, 0)"
INSERT 0 1
$ psql -p 5432 -c "INSERT INTO accounts (aid, bid, abalance) VALUES (100002, 1, 1)"
INSERT 0 1
$ pgbench -i -p 5433
creating tables...
10000 tuples done.
(snip)
vacuum...done.
$ psql -p 5433 -c "INSERT INTO accounts (aid, bid, abalance) VALUES (100002, 1, 1)"
INSERT 0 1
$ psql -p 5433 -c "INSERT INTO accounts (aid, bid, abalance) VALUES (100001, 1, 0)"
INSERT 0 1
$ ./pgdiff.sh --mport 5432 --sport 5433 --sortcol aid accounts

コンペアツールを実行したが何も表示されず、物理的な行の並びが異なっていても同じデータが格納されている場合に差異がないことを確認できた。