[pgpool-general-jp: 611] Re: オンラインリカバリを実施するとノード間のシーケンスがずれる

Tatsuo Ishii ishii @ sraoss.co.jp
2009年 8月 14日 (金) 13:55:32 JST


石井です。

> おそらく原因は、
> PostgreSQLのsequenceが、nextvalした時に毎回WALに記録される
> わけでは無いためのようです。
> 
> 例えばpsqlから直接PostgreSQLに接続し、
> 
> =# CREATE SEQUENCE s1;
> CREATE SEQUENCE
> =# SELECT nextval('s1');
>  nextval
> ---------
>        1
> (1 row)
> 
> =# SELECT nextval('s1');
>  nextval
> ---------
>        2
> (1 row)
> 
> としたところで、
> pg_ctl stop -mimmediate
> し、再起動した後に再度nextvalすると、
> 
> =# SELECT nextval('s1');
>  nextval
> ---------
>       35
> (1 row)
> 
> となります(8.4.0での実行例です)。
> 
> これはおそらく、nextvalのたびに毎回WALに記録するのは
> 効率が悪いので、(32 + CACHE)回に一度だけしか
> WALには記録しないということだと思います。
> 
> sequenceは値が連続することは保証していないので
> PostgreSQLのリカバリの仕組みとしてはこれで問題ない
> ということだと思います。
> (が、pgpoolのリカバリの仕組みとしては、
> マスタとスレーブでsequenceの値が異なってしまっては
> 困りますね)。
> 
> pgpoolで対応するとすれば、リカバリを行なった後の
> 最初の接続時に、nextval/setvalを使って
> マスタとスレーブのsequenceを同期させるような
> 仕組みを実装する、くらいしか思いつかないのですが。

石田さんからのsuggestionで、リカバリのセカンドステージで以下を実行する
ようにしてみました。

# 強制的に現在のシーケンスをログに出力
psql -t -c 'SELECT datname FROM pg_database WHERE NOT datistemplate AND datallowconn' template1|
while read i
do
  if [ "$i" != "" ];then
    psql -c "SELECT setval(oid, nextval(oid)) FROM pg_class WHERE relkind = 'S'" $i
  fi
done

これは何をやっているかというと、全データベースの全シーケンスについて、
強制的に現在のシーケンス値をsetval()を使ってWALログに書くということを
やっています(WALログに書くのはsetval()の副作用)。
これを、セカンドステージの

psql -c 'SELECT pg_switch_xlog()' template1

の前でやるのが味噌です。

これで今のところリカバリ後シーケンス値が同期しているように見えます。
お試し下さい。

なお、これによって、マスタ側の全シーケンスが1つ進んでしまいますが、こ
れはしょうがないということで。
--
Tatsuo Ishii
SRA OSS, Inc. Japan

> >> たとえば、以下のようなテーブルを作成します。
> >> test_tab(
> >>  col1  bigserial,
> >>  col2  varchar2(10) )
> >> そうすると、test_tab_col1_seqというシーケンスが自動的に作成されて、
> >> col1にはtest_tab_col1_seqから連番が振られていきます。
> >> 縮退運転中、正常ノードのcol1が500まで進んで、障害ノードのほうは400で止まっているとします。
> >> この状態でインサートを継続したままオンラインリカバリを実行します。
> >> リカバリ完了後テーブルを確認すると、
> >> 途中まで(たとえば600まで)は期待通り同期されているのに、
> >> 途中から障害ノードのシーケンスが中抜きされるというような現象が発生します。
> >> (同じデータでも正常ノードでは601、障害ノードでは610が振られる)
> >
> >  これって一トランザクションの中で INSERT し続けているのでしょうか? それとも INSERT
> > 一つごとに COMMIT される形でしょうか?
> >
> >
> > --
> > Jun Kuriyama <kuriyama @ FreeBSD.org> // FreeBSD Project
> >         <kuriyama @ s2factory.co.jp> // S2 Factory, Inc.
> > _______________________________________________
> > pgpool-general-jp mailing list
> > pgpool-general-jp @ sraoss.jp
> > http://www.sraoss.jp/mailman/listinfo/pgpool-general-jp
> >
> >
> 
> 
> 
> -- 
> ISHIDA Akio <iakio @ mono-space.net/ishida @ cycleof5th.com>
> _______________________________________________
> pgpool-general-jp mailing list
> pgpool-general-jp @ sraoss.jp
> http://www.sraoss.jp/mailman/listinfo/pgpool-general-jp


pgpool-general-jp メーリングリストの案内