1.6. オンラインリカバリを試してみる

Pgpool-IIは、「オンラインリカバリ」という技術を使ってダウンしたノードを復旧させることができます。 これはプライマリノードからデータをスタンバイノードへとコピーし、プライマリと同期させます。 それには長い時間がかかることがあり、その間にデータが更新されるかもしれません。 これは問題になりません。なぜなら、ストリーミングレプリケーション構成では、スタンバイはWALログを受け取り、それを適用することによってプライマリに追い付くことができるからです。 オンラインリカバリをテストするために、ノード0が落ちている先ほどのクラスタから始めましょう。

    $ pcp_recovery_node -p 11001 -n 0
    Password: 
    pcp_recovery_node -- Command Successful

    $ psql -p 11000 -c "show pool_nodes" test
    node_id | hostname | port  | status | lb_weight |  role   | select_cnt | load_balance_node | replication_delay | last_status_change
    ---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+---------------------
    0       | /tmp     | 11002 | up     | 0.500000  | standby | 0          | false             | 0                 | 2019-01-31 12:06:48
    1       | /tmp     | 11003 | up     | 0.500000  | primary | 0          | true              | 0                 | 2019-01-31 12:05:20
    (2 rows)
   

pcp_recovery_nodeは、インストールされたPgpool-IIに含まれる管理コマンドの一つです。 引数の-pは、コマンドにアサインされたポート番号です。 pgpool_setupは11001に設定しています。 引数の-nは、リカバリされるノードの番号です。 コマンドを実行すると、ノード0は"up"状態に復帰します。

pcp_recovery_nodeが実行するスクリプトは、pgpool.confで"recovery_1st_stage_command"として指定されています。 pgpool_setupがインストールするファイルはこれです。

    #! /bin/sh
    psql=/usr/local/pgsql/bin/psql
    DATADIR_BASE=/home/t-ishii/tmp/Tutorial
    PGSUPERUSER=t-ishii

    master_db_cluster=$1
    recovery_node_host_name=$2
    DEST_CLUSTER=$3
    PORT=$4
    recovery_node=$5

    pg_rewind_failed="true"

    log=$DATADIR_BASE/log/recovery.log
    echo >> $log
    date >> $log
    if [ $pg_rewind_failed = "true" ];then

    $psql -p $PORT -c "SELECT pg_start_backup('Streaming Replication', true)" postgres

    echo "source: $master_db_cluster dest: $DEST_CLUSTER" >> $log

    rsync -C -a -c --delete --exclude postgresql.conf --exclude postmaster.pid \
    --exclude postmaster.opts --exclude pg_log \
    --exclude recovery.conf --exclude recovery.done \
    --exclude pg_xlog \
    $master_db_cluster/ $DEST_CLUSTER/

    rm -fr $DEST_CLUSTER/pg_xlog 
    mkdir $DEST_CLUSTER/pg_xlog
    chmod 700 $DEST_CLUSTER/pg_xlog
    rm $DEST_CLUSTER/recovery.done
    fi
    cat > $DEST_CLUSTER/recovery.conf <<REOF
    standby_mode          = 'on'
    primary_conninfo      = 'port=$PORT user=$PGSUPERUSER'
    recovery_target_timeline='latest'
    restore_command = 'cp $DATADIR_BASE/archivedir/%f "%p" 2> /dev/null'
    REOF
    if [ $pg_rewind_failed = "true" ];then
    $psql -p $PORT -c "SELECT pg_stop_backup()" postgres
    fi

    if [ $pg_rewind_failed = "false" ];then
    cp /tmp/postgresql.conf $DEST_CLUSTER/
    fi