1#!/usr/bin/env bash
2#
3# Copyright (c) 2013-2021 PgPool Global Development Group
4#
5# Permission to use, copy, modify, and distribute this software and
6# its documentation for any purpose and without fee is hereby
7# granted, provided that the above copyright notice appear in all
8# copies and that both that copyright notice and this permission
9# notice appear in supporting documentation, and that the name of the
10# author not be used in advertising or publicity pertaining to
11# distribution of the software without specific, written prior
12# permission. The author makes no representations about the
13# suitability of this software for any purpose.  It is provided "as
14# is" without express or implied warranty.
15#-------------------------------------------------------------------
16# Set up pgpool-II and PostgreSQL temporary installation in current
17# directory for *testing* purpose.
18# Do not use this tool for production environment!
19#
20# usage: pgpool_setup [-m r|s|n|l][-n num_clusters][-p base_port][-pg pg_base_port][--no-stop][-d][-s][-r][-e]
21# -m s: create an installation as streaming replication mode.
22# (the default)
23# -m r: create an installation as native replication mode.
24# -m n: create an installation as raw mode.
25# -m l: create an installation as logical replication mode.
26# -m y: create an installation as slony mode.
27# -m i: create an installation as snapshot isolation mode.
28# -n num_clusters: create num_clusters PostgreSQL database cluster nodes
29# -p base_port: specify base port. pgpool port is base_port.
30#  pcp port is base_port + 1. The first PostgreSQL node's port is
31#  base_port + 2, second PostgreSQL node's port is base_port + 3
32#  and so on.
33# if -pg option is specified, the first PostgreSQL node's port is
34# assigned to pg_pase_port, the second PostgreSQL node's port is
35# pg_base_port + 1 and so on.
36# --no-stop: do not stop pgpool and PostgreSQL after the work
37# -d: start pgpool with debug mode
38# -s: use replication slot, rather than wal archive.
39# -r: use pg_rewind for base backup if possible.
40# -e: do not create PostgreSQL clusters
41#
42# The user run this script will become the PostgreSQL super user as
43# well.  Current directory must be empty.  Assume that appropriate
44# pgpool and PostgreSQL binaries are in the command search path.
45# The user must have passwordless access to localhost over SSH.
46#
47# Layout after executing this script:
48#  data[0-]: PostgreSQL database clusters
49#  log: pgpool.log and pgpool_status resides here
50#  run: pgpool-II pid file resides here(generated by pgpool-II)
51#  etc/pgpool.conf: pgpool-II configuration file
52#  etc/pool_passwd: generated by pgpool-II
53#  ./startall: a script to start pgpool-II and all PostgreSQL servers
54#  ./shutdownall: a script to shutdown pgpool-II and all PostgreSQL servers
55#
56# test database "test" is created.
57# pcp username and password is set to the person who executed this script.
58#
59#-------------------------------------------
60# Configuration section
61#-------------------------------------------
62# Starting port number to be used. Each PostgreSQL is assigned
63# $BASEPORT + 2, $BASEPORT + 3 and so on.
64# pgpool port and pcp_port will be assigned to $BASEPORT and $BASEPORT +1 .
65BASEPORT=${BASEPORT:-"11000"}
66ORIGBASEPORT=$BASEPORT
67# PostgreSQL startig port number.
68PGBASEPORT=`expr $BASEPORT + 2`
69# Default number of PostgreSQL database clusters
70NUMCLUSTERS=${NUMCLUSTERS:-"2"}
71# Where to look for pgpool.conf.sample
72PGPOOL_INSTALL_DIR=${PGPOOL_INSTALL_DIR:-"@@PGPOOL_INSTALL_DIR@@"}
73PGPOOLDIR=${PGPOOLDIR:-"@@PGPOOL_CONFIG_DIR@@"}
74# PostgreSQL commands(initdb, pg_ctl, psql) install dir
75PGBIN=${PGBIN:-"@@PGSQL_BIN_DIR@@"}
76# LD_LIBRARY_PATH
77LPATH=${PGLIB:-"@@PGSQL_LIB_DIR@@"}
78# unix socket directory
79PGSOCKET_DIR=${PGSOCKET_DIR:-"/tmp"}
80# initdb args
81INITDBARG="--no-locale -E UTF_8"
82# Use replication slot
83USE_REPLICATION_SLOT=${USE_REPLICATION_SLOT:-"false"}
84# Use pg_rewind
85USE_PG_REWIND=${USE_PG_REWIND:-"false"}
86# Check TIME_WAIT in shutdownall script
87CHECK_TIME_WAIT=${CHECK_TIME_WAIT:-"false"}
88#-------------------------------------------
89# End of configuration section
90#-------------------------------------------
91#
92# user name
93WHOAMI=`whoami`
94
95# our root directory
96BASEDIR=`pwd`
97
98# PostgreSQL bin directory
99INITDB=$PGBIN/initdb
100PG_CTL=$PGBIN/pg_ctl
101PSQL=$PGBIN/psql
102
103# get PostgreSQL major version
104vstr=`$INITDB -V|awk '{print $3}'|sed 's/\./ /g'`
105#vstr="12beta1"
106#vstr="9.1.24"
107#vstr="11.1"
108
109# check if alpha or beta
110echo $vstr|egrep "[a-z]" > /dev/null
111if [ $? = 0 ];then
112    vstr=`echo $vstr|sed 's/\([0-9]*\).*/\1/'`
113    major1=`echo $vstr|awk '{print $1}'`
114    major2=`echo $vstr|awk '{print $2}'`
115    if [ -z $major2 ];then
116	major2=0
117    fi
118else
119    vstr=`echo $vstr|sed 's/\./ /g'`
120    major1=`echo $vstr|awk '{print $1}'`
121
122    if [ $major1 -ge 10 ];then
123        major2=0
124    else
125        major2=`echo $vstr|awk '{print $2}'`
126    fi
127fi
128major1=`expr $major1 \* 10`
129PGVERSION=`expr $major1 + $major2`
130echo PostgreSQL major version: $PGVERSION
131
132if [ $PGVERSION -gt 91 ];then
133    INITDBARG="$INITDBARG --data-checksums"
134fi
135
136# pgpool-II configuration file location.
137CONF=$BASEDIR/etc/pgpool.conf
138# failover script
139FAILOVER_SCRIPT=$BASEDIR/etc/failover.sh
140# follow primary script
141FOLLOW_PRIMARY_SCRIPT=$BASEDIR/etc/follow_primary.sh
142# pgpool_remote_start
143PGPOOL_REMOTE_START_SCRIPT=pgpool_remote_start
144# Start script name. This will be generated in this script.
145STARTALL=$BASEDIR/startall
146# Shutdown script name. This will be generated in this script.
147SHUTDOWNALL=$BASEDIR/shutdownall
148PCP_PASS_FILE=$BASEDIR/pcppass
149# pgpool reload script name. This will be generated in this script.
150PGPOOL_RELOAD=$BASEDIR/pgpool_reload
151
152export PGHOST=$PGSOCKET_DIR
153
154#-------------------------------------------
155# create failover script
156#-------------------------------------------
157function create_failover_script()
158{
159cat >> $FAILOVER_SCRIPT <<'EOF'
160#! /bin/sh
161# Execute command by failover.
162# special values:  %d = node id
163#                  %h = host name
164#                  %p = port number
165#                  %D = database cluster path
166#                  %m = new main node id
167#                  %M = old main node id
168#                  %H = new main node host name
169#                  %P = old primary node id
170#                  %R = new main database cluster path
171#                  %r = new main port number
172#                  %% = '%' character
173failed_node_id=$1
174failed_host_name=$2
175failed_port=$3
176failed_db_cluster=$4
177new_main_id=$5
178old_main_id=$6
179new_main_host_name=$7
180old_primary_node_id=$8
181new_main_port_number=$9
182new_main_db_cluster=${10}
183mydir=__MYDIR__
184log=$mydir/log/failover.log
185pg_ctl=__PGBIN__/pg_ctl
186cluster0=$mydir/data0
187cluster1=$mydir/data1
188PCP_PORT=__PCPPORT__
189pgversion=__PGVERSION__
190export PCPPASSFILE=__PCPPASSFILE__
191PGPOOL_BIN=__PGPOOL_INSTALL_DIR__/bin
192
193date >> $log
194echo "failed_node_id $failed_node_id failed_host_name $failed_host_name failed_port $failed_port failed_db_cluster $failed_db_cluster new_main_id $new_main_id old_main_id $old_main_id new_main_host_name $new_main_host_name old_primary_node_id $old_primary_node_id new_main_port_number $new_main_port_number new_main_db_cluster $new_main_db_cluster" >> $log
195
196# check if all node is down
197if [ $new_main_id = "-1" ];then
198    echo "no new main node is available" >>$log
199    exit 0
200fi
201
202if [ a"$failed_node_id" = a"$old_primary_node_id" ];then	# main node failed
203! 	new_primary_db_cluster=${mydir}/data"$new_main_id"
204	echo $pg_ctl -D $new_primary_db_cluster promote >>$log	# let standby take over
205	$pg_ctl -D $new_primary_db_cluster promote >>$log	# let standby take over
206	sleep 2
207fi
208EOF
209
210#-------------------------------------------
211# replace some variables in the script
212#-------------------------------------------
213/bin/sed -i \
214	 -e "/__MYDIR__/s@__MYDIR__@$BASEDIR@" \
215	 -e "/__PGBIN__/s@__PGBIN__@$PGBIN@" \
216	 -e "/__PCPPASSFILE__/s@__PCPPASSFILE__@$PCP_PASS_FILE@" \
217	 -e "/__PCPPORT__/s/__PCPPORT__/$PCP_PORT/" \
218	 -e "/__PGVERSION__/s/__PGVERSION__/$PGVERSION/" \
219	 -e "/__PGPOOL_INSTALL_DIR__/s@__PGPOOL_INSTALL_DIR__@$PGPOOL_INSTALL_DIR@" \
220	 $FAILOVER_SCRIPT
221
222chmod 755 $FAILOVER_SCRIPT
223}
224
225#-------------------------------------------
226# create follow primary script
227#-------------------------------------------
228function create_follow_primary_script()
229{
230cat >> $FOLLOW_PRIMARY_SCRIPT <<'EOF'
231#! /bin/sh
232# Execute command by failover.
233# special values:  %d = node id
234#                  %h = host name
235#                  %p = port number
236#                  %D = database cluster path
237#                  %m = new primary node id
238#                  %M = old main node id
239#                  %H = new primary node host name
240#                  %P = old primary node id
241#                  %R = new primary database cluster path
242#                  %r = new primary port number
243#                  %N = old primary node host name
244#                  %S = old primary node port number
245#                  %% = '%' character
246node_id=$1
247host_name=$2
248port=$3
249db_cluster=$4
250new_primary_id=$5
251old_main_id=$6
252new_primary_host_name=$7
253old_primary_node_id=$8
254new_primary_port_number=$9
255new_primary_db_cluster=${10}
256mydir=__MYDIR__
257log=$mydir/log/failover.log
258pg_ctl=__PGBIN__/pg_ctl
259cluster0=$mydir/data0
260cluster1=$mydir/data1
261cluster2=$mydir/data2
262PCP_PORT=__PCPPORT__
263pgversion=__PGVERSION__
264export PCPPASSFILE=__PCPPASSFILE__
265PGPOOL_BIN=__PGPOOL_INSTALL_DIR__/bin
266
267echo "follow primary script started" >> $log
268date >> $log
269echo "node_id $node_id host_name $host_name port $port db_cluster $db_cluster new_primary_id $new_primary_id old_main_id $old_main_id new_main_host_name $new_main_host_name old_primary_node_id $old_primary_node_id new_primary_port_number $new_primary_port_number new_primary_db_cluster $new_primary_db_cluster" >> $log
270
271# Skip the target standby node if it's not running
272$pg_ctl -D $db_cluster status >/dev/null 2>&1
273if [ $? = 0 ]
274then
275    # change primary node connection info so that it points to the new primary
276    if [ $pgversion -ge 120 ];then
277        sed -i "s/port=[0-9]*/port=$new_primary_port_number/" $db_cluster/myrecovery.conf
278        sed -i "/restore_command/s/data[0-9]/`basename $new_primary_db_cluster`/" $db_cluster/myrecovery.conf
279    else
280	# if recovery.conf is not found, rename recovery.done.
281	if [ ! -f $db_cluster/recovery.conf ];then
282	   mv $db_cluster/recovery.done $db_cluster/recovery.conf
283	fi
284        sed -i "s/port=[0-9]*/port=$new_primary_port_number/" $db_cluster/recovery.conf
285        sed -i "/restore_command/s/data[0-9]/`basename $new_primary_db_cluster`/" $db_cluster/recovery.conf
286    fi
287
288    touch $db_cluster/standby.signal
289
290    echo "restart the target server" >> $log
291    $pg_ctl -w -m f -D $db_cluster restart >> $log 2>&1
292
293    $pg_ctl -D $db_cluster status >>$log 2>&1
294    if [ $? != 0 ]
295    then
296        echo "restarting $db_cluster failed" >>$log
297        echo "fail back to pcp_recovery_node" >>$log
298        $PGPOOL_BIN/pcp_recovery_node -w -h localhost -p $PCP_PORT -n $node_id >> $log 2>&1
299    else
300        # attach the node
301        $PGPOOL_BIN/pcp_attach_node -w -h localhost -p $PCP_PORT -n $node_id >> $log 2>&1
302    fi
303else
304    echo "$db_cluster is not running. skipping follow primary command." >> $log
305fi
306echo "follow primary script ended" >> $log
307EOF
308
309#-------------------------------------------
310# replace some variables in the script
311#-------------------------------------------
312
313/bin/sed -i \
314	 -e "/__MYDIR__/s@__MYDIR__@$BASEDIR@" \
315	 -e "/__PGBIN__/s@__PGBIN__@$PGBIN@" \
316	 -e "/__PCPPASSFILE__/s@__PCPPASSFILE__@$PCP_PASS_FILE@" \
317	 -e "/__PCPPORT__/s/__PCPPORT__/$PCP_PORT/" \
318	 -e "/__PGVERSION__/s/__PGVERSION__/$PGVERSION/" \
319	 -e "/__PGPOOL_INSTALL_DIR__/s@__PGPOOL_INSTALL_DIR__@$PGPOOL_INSTALL_DIR@" \
320	$FOLLOW_PRIMARY_SCRIPT
321
322chmod 755 $FOLLOW_PRIMARY_SCRIPT
323}
324
325#-------------------------------------------
326# create pgpool_remote_start script
327# argument: PostgreSQL database cluster directory
328#-------------------------------------------
329function create_pgpool_remote_start_script()
330{
331cat >> $1/$PGPOOL_REMOTE_START_SCRIPT <<'EOF'
332#! /bin/sh
333#
334# start postmaster on the recovered node
335#
336if [ $# -ne 2 ]
337then
338    echo "pgpool_remote_start remote_host remote_datadir"
339    exit 1
340fi
341
342DEST=$1
343DESTDIR=$2
344PGCTL=__PGBIN__/pg_ctl
345
346ssh -T $DEST $PGCTL -w -D $DESTDIR start 2>/dev/null 1>/dev/null < /dev/null &
347EOF
348
349#-------------------------------------------
350# replace some variables in the script
351#-------------------------------------------
352/bin/sed -i \
353	-e "/__PGBIN__/s@__PGBIN__@$PGBIN@" \
354	$1/$PGPOOL_REMOTE_START_SCRIPT
355
356chmod 755 $1/$PGPOOL_REMOTE_START_SCRIPT
357}
358
359#-------------------------------------------
360# set postgresql.conf
361# argument: PostgreSQL database cluster directory
362#-------------------------------------------
363function set_postgresql_conf
364{
365	PGCONF=$1/postgresql.conf
366	PGHBACONF=$1/pg_hba.conf
367
368	echo "listen_addresses = '*'" >> $PGCONF
369	echo "port = $PORT" >> $PGCONF
370	echo "logging_collector = on" >> $PGCONF
371	echo "log_filename = '%A.log'" >> $PGCONF
372	echo "log_line_prefix = '%p %m '" >> $PGCONF
373	echo "log_truncate_on_rotation = on" >> $PGCONF
374	echo "log_statement = 'all'" >> $PGCONF
375	echo "max_prepared_transactions = 10" >> $PGCONF
376	echo "unix_socket_directories = '$PGSOCKET_DIR'" >> $PGCONF
377	echo "max_wal_senders = $NUMCLUSTERS" >> $PGCONF
378
379	if [ $PGVERSION -ge 120 ];then
380	    echo "include_if_exists = 'myrecovery.conf'" >> $PGCONF
381	fi
382
383	if [ $MODE = "s" ];then
384		echo "hot_standby = on" >> $PGCONF
385		echo "wal_level = 'hot_standby'" >> $PGCONF
386
387		if [ $USE_REPLICATION_SLOT = "false" ];then
388		    echo "archive_mode = on" >> $PGCONF
389		    echo "archive_command = 'cp %p $BASEDIR/archivedir/`basename $1`/%f </dev/null'" >> $PGCONF
390		else
391		    num_slots=`expr $NUMCLUSTERS + 10`
392		    echo "max_replication_slots = $num_slots" >> $PGCONF
393		fi
394
395	elif [ $MODE = 'r' -o $MODE = 'n' -o $MODE = 'l' -o $MODE = 'y' -o $MODE = 'i' ];then
396		echo "wal_level = 'archive'" >> $PGCONF
397		echo "archive_mode = on" >> $PGCONF
398		echo "archive_command = 'cp %p $BASEDIR/archivedir/`basename $1`/%f </dev/null'" >> $PGCONF
399		if [ $MODE = 'l' ];then
400		    echo "wal_level = 'logical'" >> $PGCONF
401		fi
402	fi
403
404	# Snapshot isolation mode requires REPEATABLE READ transaction isolation mode.
405	if [ $MODE = 'i' ];then
406	    echo "default_transaction_isolation = 'repeatable read'" >> $PGCONF
407	fi
408
409    sed -i '/host.*all.*all.*trust$/s/^/#/g' $PGHBACONF
410    sed -i '/local.*all.*all.*trust$/s/^/#/g' $PGHBACONF
411
412    if [ $PGVERSION -ge 100 ];
413    then
414	echo "host      all   scram_user     0/0    scram-sha-256" >> $PGHBACONF
415	echo "host      all   md5_user       0/0    md5" >> $PGHBACONF
416    fi
417
418    echo "host      all   all       0/0    trust" >> $PGHBACONF
419
420    if [ $PGVERSION -ge 100 ];
421    then
422	echo "local      all   scram_user      scram-sha-256" >> $PGHBACONF
423	echo "local      all   md5_user        md5" >> $PGHBACONF
424    fi
425
426    echo "local      all   all      trust" >> $PGHBACONF
427
428    ed $1/pg_hba.conf <<EOF
429/^#local *replication/s/^#//p
430/^#host *replication/s/^#//p
431/^#host *replication/s/^#//p
432w
433q
434EOF
435}
436
437#-------------------------------------------
438# create basebackup.sh for streaming replication mode
439# argument1: PostgreSQL database cluster
440# argument2: cluster node number
441#-------------------------------------------
442function create_basebackup_stream {
443SCRIPT=basebackup.sh
444cat >> $1/$SCRIPT <<'EOF'
445#! /bin/sh
446psql=__PGBIN__/psql
447pg_rewind=__PGBIN__/pg_rewind
448PG_CTL=__PGBIN__/pg_ctl
449DATADIR_BASE=__DATADIR_BASE__
450PGSUPERUSER=__PGSUPERUSER__
451MAX_DURATION=60
452pgversion=__PGVERSION__
453
454main_db_cluster=$1
455recovery_node_host_name=$2
456DEST_CLUSTER=$3
457PORT=$4
458recovery_node=$5
459
460pg_rewind_failed="true"
461
462log=$DATADIR_BASE/log/recovery.log
463echo >> $log
464date >> $log
465EOF
466
467echo "export PGHOST=$PGSOCKET_DIR" >> $1/$SCRIPT
468
469pg_rewind_failed="true"
470
471if [ $USE_PG_REWIND = "true" ];then
472cat >> $1/$SCRIPT <<'EOF'
473
474# First try pg_rewind
475
476# Make backup copy of postgresql.conf since pg_rewind blindly copies
477# $main_db_cluster/postgresql.conf.
478cp $DEST_CLUSTER/postgresql.conf /tmp/
479echo "pg_rewind starts" >> $log
480$pg_rewind -P -D $DEST_CLUSTER --source-server="port=$PORT user=$PGSUPERUSER dbname=postgres" >> $log 2>&1
481if [ $? != 0 ];then
482    # pg_rewind failed. Fallback to rsync.
483   echo "pg_rewind failed. Fall back to rsync" >> $log
484   pg_rewind_failed="true"
485else
486   pg_rewind_failed="false"
487fi
488EOF
489fi
490
491cat >> $1/$SCRIPT <<'EOF'
492if [ $pg_rewind_failed = "true" ];then
493
494$psql -p $PORT -c "SELECT pg_start_backup('Streaming Replication', true)" postgres
495
496echo "source: $main_db_cluster dest: $DEST_CLUSTER" >> $log
497
498rsync -C -a -c --delete --exclude postgresql.conf --exclude postmaster.pid \
499--exclude postmaster.opts --exclude pg_log \
500--exclude recovery.conf --exclude recovery.done \
501--exclude pg_xlog --exclude pg_wal \
502--exclude log \
503$main_db_cluster/ $DEST_CLUSTER/
504
505rm -fr $DEST_CLUSTER/pg_xlog
506mkdir $DEST_CLUSTER/pg_xlog
507chmod 700 $DEST_CLUSTER/pg_xlog
508
509rm -fr $DEST_CLUSTER/pg_wal
510mkdir $DEST_CLUSTER/pg_wal
511chmod 700 $DEST_CLUSTER/pg_wal
512
513rm $DEST_CLUSTER/recovery.done
514fi
515EOF
516
517if [ $USE_REPLICATION_SLOT = "true" ];then
518    cat >> $1/$SCRIPT <<'EOF'
519$psql -p $PORT -c "SELECT * FROM pg_create_physical_replication_slot('pgpool_setup_slot$recovery_node')" postgres
520EOF
521fi
522
523if [ $PGVERSION -ge 120 ];then
524    cat >> $1/$SCRIPT <<'EOF'
525cat > $DEST_CLUSTER/myrecovery.conf <<REOF
526primary_conninfo      = 'host=localhost port=$PORT user=$PGSUPERUSER application_name=''server$recovery_node'''
527recovery_target_timeline='latest'
528EOF
529
530else
531
532    cat >> $1/$SCRIPT <<'EOF'
533cat > $DEST_CLUSTER/recovery.conf <<REOF
534standby_mode          = 'on'
535primary_conninfo      = 'host=localhost port=$PORT user=$PGSUPERUSER application_name=''server$recovery_node'''
536recovery_target_timeline='latest'
537EOF
538fi
539
540if [ $USE_REPLICATION_SLOT = "false" ];then
541    cat >> $1/$SCRIPT <<'EOF'
542restore_command = 'cp $DATADIR_BASE/archivedir/`basename $1`/%f "%p" 2> /dev/null'
543REOF
544EOF
545else
546    cat >> $1/$SCRIPT << 'EOF'
547primary_slot_name = 'pgpool_setup_slot$recovery_node'
548REOF
549EOF
550fi
551
552cat >> $1/$SCRIPT <<'EOF'
553if [ $pg_rewind_failed = "true" ];then
554$psql -p $PORT -c "SELECT pg_stop_backup()" postgres
555fi
556
557if [ $pg_rewind_failed = "false" ];then
558    cp /tmp/postgresql.conf $DEST_CLUSTER/
559fi
560touch $DEST_CLUSTER/standby.signal
561EOF
562
563#-------------------------------------------
564# replace some variables in the script
565#-------------------------------------------
566/bin/sed -i \
567	-e "/__PGBIN__/s@__PGBIN__@$PGBIN@" \
568	-e "/__DATADIR_BASE__/s@__DATADIR_BASE__@$BASEDIR@" \
569	-e "/__PGSUPERUSER__/s/__PGSUPERUSER__/$WHOAMI/" \
570	-e "/__PGVERSION__/s/__PGVERSION__/$PGVERSION/" \
571$1/$SCRIPT
572
573chmod 755 $1/$SCRIPT
574}
575
576#-------------------------------------------
577# create basebackup.sh for native replication mode and snapshot isolation mode.
578# argument1: full path to database cluster directory of main node
579# argument2: node number of target node
580#-------------------------------------------
581function create_basebackup_replication {
582    CLUSTERDIR=$1
583    n=$2
584    SCRIPT=basebackup.sh
585
586    create_basebackup_stream $CLUSTERDIR $n
587    cat >> $1/$SCRIPT <<'EOF'
588# start target server as a streaming replication standby server
589$PG_CTL -w -D $DEST_CLUSTER start
590
591# wait till the standby catches up primary server or
592# $MAX_DURATION seconds passes
593sec=0
594while [ $sec -lt $MAX_DURATION ]
595do
596  sec=`expr $sec + 1`
597
598  if [ $pgversion -ge 100 ];then
599    result=`psql -p $4 -c "SELECT sent_lsn = replay_lsn FROM pg_stat_replication where application_name = 'server$recovery_node'" postgres|sed -n 3p|sed 's/ //'`
600  else
601    result=`psql -p $4 -c "SELECT sent_location = replay_location FROM pg_stat_replication where application_name = 'server$recovery_node'" postgres|sed -n 3p|sed 's/ //'`
602  fi
603
604  # echo "result: $result"
605  if [ "$result" = "t" ];then
606    sec=$MAX_DURATION
607  fi
608  sleep 1
609done
610EOF
611
612#-------------------------------------------
613# replace some variables in the script
614#-------------------------------------------
615/bin/sed -i \
616	-e "/__PGBIN__/s@__PGBIN__@$PGBIN@" \
617	-e "/__DATADIR_BASE__/s@__DATADIR_BASE__@$BASEDIR@" \
618	-e "/__PGSUPERUSER__/s/__PGSUPERUSER__/$WHOAMI/" \
619	-e "/__ARCHDIR__/s@__ARCHDIR__@$BASEDIR/archivedir/\`basename \$1\`@" \
620	-e "/__PGVERSION__/s/__PGVERSION__/$PGVERSION/" \
621$1/$SCRIPT
622
623chmod 755 $1/$SCRIPT
624}
625
626#-------------------------------------------
627# create pgpool_recovery_pitr (2nd stage script)for native replication mode
628# argument: PostgreSQL database cluster directory
629#-------------------------------------------
630function create_pgpool_recovery_pitr {
631SCRIPT=pgpool_recovery_pitr
632cat >> $1/$SCRIPT <<'EOF'
633#! /bin/sh
634psql=__PGBIN__/psql
635DATADIR_BASE=__DATADIR_BASE__
636PGSUPERUSER=__PGSUPERUSER__
637PGCTL=__PGBIN__/pg_ctl
638
639main_db_cluster=$1
640recovery_node_host_name=$2
641DEST_CLUSTER=$3
642PORT=$4
643
644log=$DATADIR_BASE/log/recovery.log
645EOF
646
647echo "export PGHOST=$PGSOCKET_DIR" >> $1/$SCRIPT
648
649cat >> $1/$SCRIPT <<'EOF'
650# Force to flush current value of sequences to xlog
651$psql -q -p $PORT -t -c 'SELECT datname FROM pg_database WHERE NOT datistemplate AND datallowconn' template1|
652while read i
653do
654  if [ "$i" != "" ];then
655    $psql -p $PORT -c "SELECT setval(oid, nextval(oid)) FROM pg_class WHERE relkind = 'S'" $i
656  fi
657done
658
659$psql -p $PORT -c "SELECT pgpool_switch_xlog('__ARCHDIR__')" template1
660
661$PGCTL -D $DEST_CLUSTER promote
662EOF
663#-------------------------------------------
664# replace some variables in the script
665#-------------------------------------------
666/bin/sed -i \
667	-e "/__PGBIN__/s@__PGBIN__@$PGBIN@" \
668	-e "/__DATADIR_BASE__/s@__DATADIR_BASE__@$BASEDIR@" \
669	-e "/__PGSUPERUSER__/s/__PGSUPERUSER__/$WHOAMI/" \
670	-e "/__ARCHDIR__/s@__ARCHDIR__@$BASEDIR/archivedir/\`basename \$1\`@" \
671	$1/$SCRIPT
672
673chmod 755 $1/$SCRIPT
674}
675
676#-------------------------------------------
677# create initial recovery.conf
678# argument1: PostgreSQL database cluster directory
679# argument2: cluster No. We assume that data0 is primary
680#-------------------------------------------
681function create_recovery_conf {
682    if [ $PGVERSION -ge 120 ];then
683	fname=myrecovery.conf
684    elif [ $2 = "0" ];then
685	fname=recovery.done
686    else
687	fname=recovery.conf
688    fi
689
690    if [ $PGVERSION -lt 120 ];then
691	cat > $1/$fname <<EOF
692standby_mode          = 'on'
693EOF
694    fi
695
696    cat > $1/$fname <<EOF
697primary_conninfo      = 'host=localhost port=$BASEPORT user=$WHOAMI application_name=''server$2'''
698recovery_target_timeline='latest'
699EOF
700    if [ $USE_REPLICATION_SLOT = true ];then
701	echo "primary_slot_name = 'pgpool_setup_slot$2'" >> $1/$fname
702    else
703	cat >> $1/$fname <<EOF
704restore_command = 'cp $BASEDIR/archivedir/`basename $1`/%f "%p" 2> /dev/null'
705EOF
706    fi
707}
708
709function set_pool_hba_conf {
710    POOL_HBACONF=$1
711    sed -i '/host.*all.*all.*trust$/s/^/#/g' $POOL_HBACONF
712    sed -i '/local.*all.*all.*trust$/s/^/#/g' $POOL_HBACONF
713
714    if [ $PGVERSION -ge 100 ];
715    then
716	echo "host    all         scram_user  0/0                   scram-sha-256" >> $POOL_HBACONF
717	echo "host    all         md5_user    0/0                   md5" >> $POOL_HBACONF
718
719	echo "local   all         scram_user                        scram-sha-256" >> $POOL_HBACONF
720	echo "local   all         md5_user                          md5" >> $POOL_HBACONF
721    fi
722
723    echo "local   all         all                               trust" >> $POOL_HBACONF
724
725    echo "host    all         all         127.0.0.1/32          trust" >> $POOL_HBACONF
726    echo "host    all         all         ::1/128               trust" >> $POOL_HBACONF
727}
728
729#-------------------------------------------
730# set pgpool.conf
731# argument: absolute path to pgpool.conf
732#-------------------------------------------
733function set_pgpool_conf {
734	echo "sr_check_user = '$WHOAMI'" >> $CONF
735	echo "recovery_user = '$WHOAMI'" >> $CONF
736	echo "recovery_password = ''"  >> $CONF
737	echo "recovery_1st_stage_command = 'basebackup.sh'" >> $CONF
738
739	if [ $MODE = "r" -o $MODE = "i" ];then
740		echo "recovery_2nd_stage_command = 'pgpool_recovery_pitr'" >> $CONF
741	fi
742
743	n=0
744	while [ $n -lt $NUMCLUSTERS ]
745	do
746	    echo "health_check_period$n = 10" >> $CONF
747	    echo "health_check_timeout$n = 20" >> $CONF
748	    echo "health_check_user$n = '$WHOAMI'" >> $CONF
749	    echo "health_check_password$n = ''" >> $CONF
750	    echo "health_check_database$n = 'postgres'" >> $CONF
751	    echo "health_check_max_retries$n = 3" >> $CONF
752	    echo "health_check_retry_delay$n = 1" >> $CONF
753	    echo "connect_timeout$n = 1000" >> $CONF
754	    n=`expr $n + 1`
755	done
756	OIDDIR=$BASEDIR/log/pgpool/oiddir
757	mkdir -p $OIDDIR
758	echo "memqcache_oiddir = '$OIDDIR'" >> $CONF
759	echo "log_per_node_statement = on" >> $CONF
760
761	if [ $MODE = "s" ];then
762		echo "failover_command = '$FAILOVER_SCRIPT %d %h %p %D %m %M %H %P %r %R'" >> $CONF
763	fi
764
765	echo "socket_dir = '$PGSOCKET_DIR'" >> $CONF
766	echo "pcp_socket_dir = '$PGSOCKET_DIR'" >> $CONF
767	echo "log_line_prefix = '%m: %a pid %p: '" >> $CONF
768}
769
770#-------------------------------------------
771# wait for pgpool comes up
772#-------------------------------------------
773function wait_for_pgpool_startup {
774	timeout=20
775
776	while [ $timeout -gt  0 ]
777	do
778		$PSQL -p $PGPOOL_PORT -c "show pool_nodes" postgres >/dev/null 2>&1
779		if [ $? = 0 ];then
780#		        echo "pgpool-II comes up after `expr 20 - $timeout` seconds"
781			break;
782		fi
783		timeout=`expr $timeout - 1`
784		sleep 1
785	done
786}
787
788#-------------------------------------------
789# wait for pgpool reload finished
790#-------------------------------------------
791function wait_for_pgpool_reload {
792	timeout=20
793	num_node=$1
794
795	while [ $timeout -gt  0 ]
796	do
797		N=`$PSQL -p $PGPOOL_PORT -c "show pool_status" test | grep backend_data | wc -l`
798		if [ $N = $num_node ];then
799			break;
800		fi
801		timeout=`expr $timeout - 1`
802		sleep 1
803	done
804}
805
806#-------------------------------------------
807# create each PostgreSQL cluster
808#-------------------------------------------
809function create_postgresql_clusters {
810    n=0
811    while [ $n -lt $NUMCLUSTERS ]
812    do
813	CLUSTER="data"`expr $n`
814	CLUSTERDIR=$BASEDIR/$CLUSTER
815	PORT=`expr $BASEPORT + $n`
816
817	if [ $NO_CREATE_PGCLUSTER = "false" ];then
818	    echo -n "creating database cluster $CLUSTERDIR..."
819	    $INITDB -D $CLUSTERDIR $INITDBARG >&5 2>&1
820	    echo "done."
821
822	    # set postgresql.conf
823	    echo "update postgresql.conf"
824	    set_postgresql_conf $CLUSTERDIR >&5 2>&1
825
826	    # create pgpool_remote_start script under cluster directory
827	    echo "creating pgpool_remote_start"
828	    create_pgpool_remote_start_script $CLUSTERDIR >&5 2>&1
829
830	    echo "creating basebackup.sh"
831	    # create basebackup.sh
832	    if [ $MODE = 's' ];then
833		create_basebackup_stream $CLUSTERDIR $n >&5 2>&1
834	    elif [ $MODE = 'r' -o $MODE = 'i' ];then
835		create_basebackup_replication $CLUSTERDIR $n >&5 2>&1
836		create_pgpool_recovery_pitr $CLUSTERDIR $n >&5 2>&1
837	    fi
838
839	    # create recovery.conf or recovery.done if streaming replication
840	    # mode
841	    if [ $MODE = "s" ];then
842		echo "creating recovery.conf"
843		create_recovery_conf $CLUSTERDIR $n >&5 2>&1
844	    fi
845
846	    echo "$PG_CTL -D $CLUSTERDIR -m f stop" >> $SHUTDOWNALL
847	    echo "$PG_CTL -w -D $CLUSTERDIR start" >> $STARTALL
848	fi
849
850	n=`expr $n + 1`
851
852	echo "#$n port is $PORT" >> README.port
853
854	# create archive directory
855	test ! -d archivedir/$CLUSTER && mkdir -p archivedir/$CLUSTER
856
857    done
858}
859
860#-------------------------------------------
861# if streaming replication mode, we need to create data1 and so on, by
862# using online recovery.
863#-------------------------------------------
864function create_followers
865{
866    if [ $MODE = 's' ];then
867	if [ $NO_CREATE_PGCLUSTER = "false" ];then
868	    # temporarily start data0 cluster to create extensions
869	    echo "temporarily start data0 cluster to create extensions"
870	    $PG_CTL -w -D data0 start >&5 2>&1
871	    $PSQL -p $BASEPORT template1 >&5 2>&1 <<EOF
872CREATE EXTENSION pgpool_regclass;
873CREATE EXTENSION pgpool_recovery;
874CREATE DATABASE test;
875EOF
876	    if [ $USE_REPLICATION_SLOT = "true" ];then
877		n=0
878		while [ $n -lt $NUMCLUSTERS ]
879		do
880		    $PSQL -p $BASEPORT template1 -c "SELECT * FROM pg_create_physical_replication_slot('pgpool_setup_slot$n')" >&5 2>&1
881		    n=`expr $n + 1`
882		done
883	    fi
884	fi
885
886	n=0
887	PORT=$BASEPORT
888	CLUSTER="data"`expr $n`
889	CLUSTERDIR=$BASEDIR/$CLUSTER
890	echo "backend_hostname$n = '$PGSOCKET_DIR'" >> $CONF
891	echo "backend_port$n = $PORT" >> $CONF
892	echo "backend_weight$n = 1" >> $CONF
893	echo "backend_data_directory$n = '$CLUSTERDIR'" >> $CONF
894	echo "backend_application_name$n = 'server$n'" >> $CONF
895
896	if [ $NO_CREATE_PGCLUSTER = "false" ];then
897	    # temporarily start pgpool
898	    echo "temporarily start pgpool-II to create standby nodes"
899	    $PGPOOL_INSTALL_DIR/bin/pgpool -D -n -f $BASEDIR/etc/pgpool.conf -F $BASEDIR/etc/pcp.conf -a $BASEDIR/etc/pool_hba.conf > $BASEDIR/log/pgpool.log 2>&1 &
900
901	    wait_for_pgpool_startup
902	fi
903
904	if [ $NUMCLUSTERS -gt 1 ];then
905	    n=1
906	    while [ $n -lt $NUMCLUSTERS ]
907	    do
908		# create archive directory
909		test ! -d $BASEDIR/archivedir/`basename $CLUSTER` && mkdir -p $BASEDIR/archivedir/`basename $CLUSTER`
910
911		# set up pgpool.conf
912		PORT=`expr $PORT + 1`
913		echo "backend_hostname$n = '$PGSOCKET_DIR'" >> $CONF
914		echo "backend_port$n = $PORT" >> $CONF
915		echo "backend_weight$n = 1" >> $CONF
916		CLUSTER="data"`expr $n`
917		CLUSTERDIR=$BASEDIR/$CLUSTER
918		echo "backend_data_directory$n = '$CLUSTERDIR'" >> $CONF
919		echo "backend_application_name$n = 'server$n'" >> $CONF
920		n=`expr $n + 1`
921	    done
922
923	    if [ $NO_CREATE_PGCLUSTER = "false" ];then
924		$PGPOOL_INSTALL_DIR/bin/pgpool -f $BASEDIR/etc/pgpool.conf reload
925	    fi
926	fi
927
928	if [ $NO_CREATE_PGCLUSTER = "false" ];then
929	    wait_for_pgpool_reload $NUMCLUSTERS
930	    $PSQL -p $PGPOOL_PORT -c "show pool_nodes" test
931	    export PCPPASSFILE=$PCP_PASS_FILE
932	    # recovery data1 and so on
933	    n=1
934	    while [ $n -lt $NUMCLUSTERS ]
935	    do
936		echo -n "recovery node $n..."
937		$PGPOOL_INSTALL_DIR/bin/pcp_recovery_node -w -h localhost -p $PCP_PORT -n $n
938		echo "done."
939		n=`expr $n + 1`
940		wait_for_pgpool_startup
941	    done
942	fi
943
944	#
945	#	replication mode
946	#
947    else
948	n=0
949	PORT=$BASEPORT
950	CLUSTER="data"`expr $n`
951	CLUSTERDIR=$BASEDIR/$CLUSTER
952
953	while [ $n -lt $NUMCLUSTERS ]
954	do
955	    if [ $NO_CREATE_PGCLUSTER = "false" ];then
956		if [ $MODE = 'l' -o $MODE = 'y' ]
957		then
958		    # temporarily start data$n cluster to create extensions
959		    echo "temporarily start data${n} cluster to create extensions"
960		    $PG_CTL -w -D data${n} start >&5 2>&1
961		    $PSQL -p `expr $BASEPORT + $n` template1 >&5 2>&1 <<EOF
962CREATE EXTENSION pgpool_regclass;
963CREATE EXTENSION pgpool_recovery;
964CREATE DATABASE test;
965EOF
966		    $PG_CTL -m f -D data${n} stop >&5 2>&1
967		fi
968	    fi
969
970	    # set up pgpool.conf
971	    echo "backend_hostname$n = '$PGSOCKET_DIR'" >> $CONF
972	    echo "backend_port$n = $PORT" >> $CONF
973	    echo "backend_weight$n = 1" >> $CONF
974
975	    if [ $n -eq 0 -a $MODE = "l" ]
976	    then
977		echo "backend_flag$n = ALWAYS_PRIMARY" >> $CONF
978	    fi
979
980	    CLUSTER="data"`expr $n`
981	    CLUSTERDIR=$BASEDIR/$CLUSTER
982	    echo "backend_data_directory$n = '$CLUSTERDIR'" >> $CONF
983	    PORT=`expr $PORT + 1`
984	    n=`expr $n + 1`
985	done
986
987	if [ $NO_CREATE_PGCLUSTER = "false" ];then
988	    echo "start all"
989	    $STARTALL >&5 2>&1
990	    echo -n "waiting for pgpool-II coming up..."
991	    wait_for_pgpool_startup
992	    #	sleep 20
993	    echo "done."
994	fi
995    fi
996
997    if [ $NO_CREATE_PGCLUSTER = "false" ];then
998	if [ $MODE = "r" -o $MODE = "n" -o $MODE = "i" ];then
999	    echo "create extensions"
1000	    $PSQL -p $PGPOOL_PORT template1 >&5 2>&1 <<EOF
1001CREATE EXTENSION pgpool_regclass;
1002CREATE EXTENSION pgpool_recovery;
1003CREATE DATABASE test;
1004EOF
1005	fi
1006    fi
1007}
1008
1009#################################################################################
1010#
1011# main script
1012#
1013################################################################################
1014function usage()
1015{
1016	echo "usage: $0 [-m r|s|n|l|y|i] [-n num_clusters] [-p base_port] [-pg pg_base_port][--no-stop] [-d] [-s] [-r] [-e]";exit 1
1017}
1018
1019#-------------------------------------------
1020# Argument check
1021# usage: $0  [-m r|s|n][-n num_clusters][-p base_port][-pg pg_base_port][--no-stop][-d][-s][-r]
1022#-------------------------------------------
1023#
1024# default mode is streaming replication mode
1025MODE="s"
1026NO_STOP="false"
1027
1028NO_CREATE_PGCLUSTER="false"
1029
1030while [ $# -gt 0 ]
1031do
1032	if [ $1 = "-m" ];then
1033		shift
1034		case $1 in
1035			r ) MODE="r";;
1036			s ) MODE="s";;
1037			n ) MODE="n";;
1038			l ) MODE="l";;
1039			y ) MODE="y";;
1040			i ) MODE="i";;
1041			* ) usage;;
1042		esac
1043	elif [ $1 = "-n" ];then
1044		shift
1045		NUMCLUSTERS=$1
1046	elif [ $1 = "-p" ];then
1047		shift
1048		BASEPORT=$1
1049		ORIGBASEPORT=$1
1050	elif [ $1 = "-pg" ];then
1051		shift
1052		PGBASEPORT=$1
1053	elif [ $1 = "--no-stop" ];then
1054		shift
1055		NO_STOP="true"
1056	elif [ $1 = "-d" ];then
1057		PGPOOLDEBUG="true"
1058	elif [ $1 = "-s" ];then
1059	    USE_REPLICATION_SLOT="true"
1060	elif [ $1 = "-r" ];then
1061	    USE_PG_REWIND="true"
1062	elif [ $1 = "-e" ];then
1063	     NO_CREATE_PGCLUSTER="true"
1064	elif [ $1 = "--help" -o $1 = "-o" ];then
1065		usage
1066		exit
1067	else
1068		usage
1069		exit
1070	fi
1071	shift
1072done
1073
1074SAMPLE_CONF=$PGPOOLDIR/pgpool.conf.sample
1075
1076case $MODE in
1077	r) MODENAME="native replication mode"
1078	   CLUSTERING_MODE_STR="native_replication"
1079		;;
1080	s ) MODENAME="streaming replication mode"
1081	    CLUSTERING_MODE_STR="streaming_replication"
1082		;;
1083	n ) MODENAME="raw mode"
1084	    CLUSTERING_MODE_STR="raw"
1085		;;
1086	l ) MODENAME="logical replication mode"
1087	    CLUSTERING_MODE_STR="logical_replication"
1088	    ;;
1089	y ) MODENAME="slony mode"
1090	    CLUSTERING_MODE_STR="slony"
1091	    ;;
1092	i ) MODENAME="snapshot isolation mode"
1093	    CLUSTERING_MODE_STR="snapshot_isolation"
1094	    ;;
1095esac
1096
1097# If USE_REPLICATION_SLOT is provided as an environment variable, turn on -s
1098if [ a$USE_REPLICATION_SLOT = a"true" ];then
1099    USE_REPLICATION_SLOT="true"
1100fi
1101
1102# If USE_PG_REWIND is provided as an environment variable, turn on -r
1103if [ a$USE_PG_REWIND = a"true" ];then
1104    USE_PG_REWIND="true"
1105fi
1106
1107#-------------------------------------------
1108# Make sure that current directory is empty
1109#-------------------------------------------
1110if [ "`/bin/ls`" != "" ]
1111then
1112	echo "$0: Current directory is not empty. Please remove files and directories then try again."
1113	exit 1
1114fi
1115
1116exec 5> $BASEDIR/pgpool_setup.log
1117
1118#-------------------------------------------
1119# everything looks good. starting setup...
1120#-------------------------------------------
1121echo "Starting set up in $MODENAME"
1122
1123#-------------------------------------------
1124# assign base port for PostgreSQL
1125#-------------------------------------------
1126ORIG_BASEPORT=$BASEPORT
1127BASEPORT=$PGBASEPORT
1128
1129#-------------------------------------------
1130# install pgpool.conf
1131#-------------------------------------------
1132test ! -d etc && mkdir etc
1133cp $SAMPLE_CONF $CONF
1134echo "backend_clustering_mode = $CLUSTERING_MODE_STR" >> $CONF
1135cp $PGPOOLDIR/pool_hba.conf.sample $BASEDIR/etc/pool_hba.conf
1136
1137#-------------------------------------------
1138# create startall, shutdownall and pgpool_reload
1139#-------------------------------------------
1140echo "creating startall and shutdownall"
1141echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LPATH" > $STARTALL
1142echo 'dir=`pwd`' >> $STARTALL
1143echo "PGPOOL_INSTALL_DIR=$PGPOOL_INSTALL_DIR" >> $STARTALL
1144chmod 755 $STARTALL
1145echo 'dir=`pwd`' > $SHUTDOWNALL
1146echo "PGPOOL_INSTALL_DIR=$PGPOOL_INSTALL_DIR" >> $SHUTDOWNALL
1147echo '$PGPOOL_INSTALL_DIR/bin/pgpool -f $dir/etc/pgpool.conf -m f stop && while [ -f $dir/run/pgpool.pid ];do sleep 1;done' >> $SHUTDOWNALL
1148if [ $CHECK_TIME_WAIT != "false" ];then
1149   echo "while  netstat -a|grep $ORIGBASEPORT ;do sleep 1;done" >> $SHUTDOWNALL
1150fi
1151chmod 755 $SHUTDOWNALL
1152echo 'dir=`pwd`' > $PGPOOL_RELOAD
1153echo "PGPOOL_INSTALL_DIR=$PGPOOL_INSTALL_DIR" >> $PGPOOL_RELOAD
1154echo '$PGPOOL_INSTALL_DIR/bin/pgpool -f $dir/etc/pgpool.conf reload' >> $PGPOOL_RELOAD
1155chmod 755 $PGPOOL_RELOAD
1156
1157#-------------------------------------------
1158# setup ports
1159#-------------------------------------------
1160PGPOOL_PORT=$ORIG_BASEPORT
1161PCP_PORT=`expr $PGPOOL_PORT + 1`
1162
1163#-------------------------------------------
1164# create failover script
1165#-------------------------------------------
1166echo "creating failover script"
1167create_failover_script >&5 2>&1
1168
1169#-------------------------------------------
1170# create each PostgreSQL cluster
1171#-------------------------------------------
1172create_postgresql_clusters
1173
1174#-------------------------------------------
1175# create pgpool.conf
1176#-------------------------------------------
1177set_pgpool_conf $CONF
1178set_pool_hba_conf $BASEDIR/etc/pool_hba.conf
1179
1180echo "port = $PGPOOL_PORT" >> $CONF
1181echo "pcp_port = $PCP_PORT" >> $CONF
1182
1183#-------------------------------------------
1184# create password file for pcp
1185#-------------------------------------------
1186echo "localhost:${PCP_PORT}:${WHOAMI}:${WHOAMI}" >> $PCP_PASS_FILE
1187chmod 0600 $PCP_PASS_FILE
1188
1189test ! -d run && mkdir run
1190echo "pid_file_name = '$BASEDIR/run/pgpool.pid'" >> $CONF
1191test ! -d log && mkdir log
1192echo "logdir = '$BASEDIR/log'" >> $CONF
1193
1194if [ "$PGPOOLDEBUG" = "true" ];then
1195    echo '$PGPOOL_INSTALL_DIR/bin/pgpool -d -D -n -f $dir/etc/pgpool.conf -F $dir/etc/pcp.conf -a $dir/etc/pool_hba.conf 2>&1 | cat > $dir/log/pgpool.log &' >> $STARTALL
1196else
1197    echo '$PGPOOL_INSTALL_DIR/bin/pgpool -D -n -f $dir/etc/pgpool.conf -F $dir/etc/pcp.conf -a $dir/etc/pool_hba.conf 2>&1 | cat > $dir/log/pgpool.log &' >> $STARTALL
1198fi
1199
1200# create pcp.conf
1201
1202if [ -f $PGPOOLDIR/pcp.conf.sample ];then
1203    cp $PGPOOLDIR/pcp.conf.sample etc/pcp.conf
1204fi
1205echo -n "${WHOAMI}:" >> etc/pcp.conf
1206$PGPOOL_INSTALL_DIR/bin/pg_md5 $WHOAMI >> etc/pcp.conf
1207
1208# create pool_passwd
1209$PGPOOL_INSTALL_DIR/bin/pg_md5 -m -f etc/pgpool.conf -u $WHOAMI $WHOAMI
1210
1211#-------------------------------------------
1212# if streaming replication mode, we need to create data1 and so on, by
1213# using online recovery.
1214#-------------------------------------------
1215   create_followers
1216
1217#-------------------------------------------
1218# create follow_primary failover script
1219#-------------------------------------------
1220if [ $MODE = "s" ];then
1221	echo "creating follow primary script"
1222	create_follow_primary_script >&5 2>&1
1223	echo "follow_primary_command = '$FOLLOW_PRIMARY_SCRIPT %d %h %p %D %m %M %H %P %r %R'" >> $CONF
1224fi
1225
1226if [ $NO_CREATE_PGCLUSTER = "false" ];then
1227    $PSQL -p $PGPOOL_PORT test <<EOF
1228show pool_nodes;
1229EOF
1230fi
1231
1232echo "pgpool port is $PGPOOL_PORT" >> README.port
1233echo "pcp port is $PCP_PORT" >> README.port
1234
1235if [ $NO_STOP = "false" ];then
1236	echo "shutdown all"
1237	$SHUTDOWNALL >&5 2>&1
1238fi
1239
1240echo "export PGPOOL_PORT=$PGPOOL_PORT" > bashrc.ports
1241echo "export PCP_PORT=$PCP_PORT" >> bashrc.ports
1242echo "export PCPPASSFILE=$PCP_PASS_FILE" >> bashrc.ports
1243chmod 755 bashrc.ports
1244
1245echo
1246echo "pgpool-II setting for $MODENAME is done."
1247echo "To start the whole system, use ${STARTALL}."
1248echo "To shutdown the whole system, use ${SHUTDOWNALL}."
1249echo "pcp command user name is \"$WHOAMI\", password is \"$WHOAMI\"."
1250echo "Each PostgreSQL, pgpool-II and pcp port is as follows:"
1251cat README.port
1252echo "The info above is in README.port."
1253
1254if [ $NO_STOP = "true" ];then
1255	echo "CAUTION: whole system is still running."
1256fi
1257