...
wal_level = hot_standby
# The following parameter is ignored on the master server, but due to the fact that master and slave can change places, we include it in the master config
hot_standby = on
...
host replication postgres 10.0.3.0/24 trust
...
wal_level = hot_standby
hot_standby = on
...
standby_mode = 'on'
primary_conninfo = 'host = 10.0.3.21 port = 5432 user = postgres'
trigger_file = '/var/lib/postgresql/9.3/main/postgresql.trigger'
...
backend_hostname0 = '10 .0.3.21 '
backend_port0 = 5432
backend_weight0 = 1
backend_data_directory0 = '/var/lib/postgresql/9.3/main'
backend_flag0 = 'ALLOW_TO_FAILOVER'
backend_hostname1 = '10 .0.3.22 '
backend_port1 = 5432
backend_weight1 = 1
backend_data_directory1 = '/var/lib/postgresql/9.3/main'
backend_flag1 = 'ALLOW_TO_FAILOVER'
# Because we have Hot Standby:
load_balance_mode = on
# We will work Streaming replication
master_slave_mode = on
master_slave_sub_mode = 'stream'
sr_check_period = 10
sr_check_user = 'postgres'
sr_check_password = ''
delay_threshold = 100
# It makes sense when slaves> 1
follow_master_command = ''
What to do when the node disappears:
failover_command = '/etc/pgpool2/failover.sh% d% P% H% R'
What to do when the dropped node returns:
failback_command = ''
# Run failover when we cannot connect to the backend
fail_over_on_backend_error = on
search_primary_node_timeout = 10
# What kind of user will we do online recovery
recovery_user = 'postgres'
recovery_password = ''
# At the first stage, pgpool continues to accept connections and requests from clients; the second stage does not.
# The running script should be in $ PGDATA
recovery_1st_stage_command = 'basebackup.sh'
recovery_2nd_stage_command = ''
# How many seconds are waiting for node recovery
recovery_timeout = 90
# We will use watchdog to monitor the status of pgpool
use_watchdog = on
wd_hostname = 'pgpool-1'
wd_port = 9000
wd_authkey = ''
# Virtual address to which the client application will connect:
delegate_IP = '10 .0.3.10 '
# Where will the interface management scripts lie:
ifconfig_path = '/ opt / AWS'
# Execute the command to assign a virtual IP node
if_up_cmd = 'if.sh up $ _IP_ $'
# We execute the command to remove the virtual IP from the node
if_down_cmd = 'if.sh down $ _IP_ $'
#Pgpool performs arping while dragging a virtual interface for an early update of the ARP cache
arping_cmd = ''
How can we check the liveliness of the neighboring pgpool node:
#heartbeat or try to send database requests through it
wd_lifecheck_method = 'heartbeat'
# Interval in seconds between checks:
wd_interval = 4
# Which port helmet:
wd_heartbeat_port = 9694
# Interval between keepalive packages
wd_heartbeat_keepalive = 2
# The time after which we consider the silent node to have disappeared:
wd_heartbeat_deadtime = 15
# Address of the next node:
heartbeat_destination0 = 'pgpool-2'
heartbeat_destination_port0 = 9694
# You can specify on which interface to work heartbeat'u
heartbeat_device0 = ''
# Describe the parameters of another node:
other_pgpool_hostname0 = 'pgpool-2'
other_pgpool_port0 = 9999
other_wd_port0 = 9000
...
10.0.3.11 pgpool-1
10.0.3.12 pgpool-2
10.0.3.21 db-1
10.0.3.22 db-2
#!/bin/bash -x FALLING_NODE=$1 # %d OLDPRIMARY_NODE=$2 # %P NEW_PRIMARY=$3 # %H PGDATA=$4 # %R KEY_PATH="/var/lib/postgresql/.ssh/id_rsa" if [ $FALLING_NODE = $OLDPRIMARY_NODE ]; then if [ $UID -eq 0 ] then sudo -u postgres ssh -T -i $KEY_PATH postgres@$NEW_PRIMARY "touch $PGDATA/postgresql.trigger" exit 0; fi ssh -T -i $KEY_PATH postgres@$NEW_PRIMARY "touch $PGDATA/postgresql.trigger" fi; exit 0;
sudo -u postgres psql -f /usr/share/postgresql/9.3/extension/pgpool-recovery.sql template1
#! /bin/sh DEST=$1 PGCTL=/usr/bin/pg_ctlcluster KEY_PATH="/var/lib/postgresql/.ssh/id_rsa" ssh -T -i $KEY_PATH postgres@$DEST "$PGCTL 9.3 main stop --force;$PGCTL 9.3 main restart"
#! /bin/sh datadir=$1 desthost=$2 destdir=$3 KEY_PATH="/var/lib/postgresql/.ssh/id_rsa" PGCTL="/usr/bin/pg_ctlcluster" ssh -T -i $KEY_PATH postgres@$desthost "$PGCTL 9.3 main stop --force" psql -c "SELECT pg_start_backup('Streaming Replication', true)" postgres rsync -C -a -c --delete -e ssh --exclude postgresql.conf --exclude postmaster.pid \ --exclude postmaster.opts --exclude pg_log \ --exclude recovery.conf --exclude recovery.done \ --exclude pg_xlog $datadir/ $desthost:$destdir/ ssh -T -i $KEY_PATH postgres@$desthost "cp $destdir/../recovery.done $destdir/recovery.conf;rm $destdir/postgresql.trigger" psql -c "SELECT pg_stop_backup()" postgres
pgpool-1 -> db-1, db-2You can use host-based ssh, you can generate ssh keys and enable them in authorized_keys.
pgpool-2 -> db-1, db-2
db-1 -> db-2
db-2 -> db-1
sudo -u postgres ssh -i /path_to_key -T postgres@db-1 id
mv main main.bak && sudo -u postgres pg_basebackup -h 10.0.3.21 -D /var/lib/postgresql/9.3/main -U postgres -v -P && cp recovery.done main/recovery.conf && chown postgres:postgres main/recovery.conf
(recovery.done - the created recovery.conf template which refers to the IP wizard) sudo service postgresql restart
application_name | walreceiveror simply check for the presence of wal sender / receiver in the process list on db-1 and db-2 hosts.
client_addr | 10.0.3.22
state | streaming
sent_location | 1 / 2A000848
write_location | 1 / 2A000848
flush_location | 1 / 2A000848
replay_location | 1 / 2A000848
sync_priority | 0
sync_state | async
wd_escalation: escalated to master pgpool successfullyAfter a while, running the second pgpool in the logs, we see that the neighboring pgpool node was successfully identified and the bundle worked:
find_primary_node: primary node id is 0The status of the pool can be viewed by one of the pcp_ * commands - pcp_pool_status, pcp_node_info, or by querying via pgpool of the show pool_nodes;, show pool_pools; nodes
openssl genrsa 1024> private-key.pem
openssl pkcs8 -topk8 -nocrypt -inform PEM -in private-key.pem -out private-key-in-PCKS8-format.pem
openssl req -new -x509 -nodes -sha1 -days 3650 -key private-key.pem -outform PEM> certificate.pem
#!/bin/sh if test $# -eq 0 then echo "This scripts adds and removes ip to subinterfaces and to AWS VPC configuration." echo "Don't forget to set variables inside this script." echo echo Usage: $0' [up|down] IP_ADDRESS' echo exit 1 fi #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #CORRECT VALUES MUST BE SET PRIOR TO RUN THIS SCRIPT #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #Proxy if used: export EC2_JVM_ARGS='-Dhttp.proxySet=true -Dhttps.proxySet=true -Dhttp.proxyHost=xxxx -Dhttp.proxyPort=3128 -Dhttps.proxyHost=xxxx -Dhttps.proxyPort=3128' #Path to unpacked ec2-api from http://s3.amazonaws.com/ec2-downloads/ec2-api-tools.zip export EC2_HOME=/opt #Path to java export JAVA_HOME=/usr #Path to generated private key & cert (READ http://docs.aws.amazon.com/IAM/latest/UserGuide/ManagingUserCerts.html) export EC2_PRIVATE_KEY=/opt/private-key-in-PCKS8-format.pem export EC2_CERT=/opt/certificate.pem #User access & secret key (READ http://docs.aws.amazon.com/IAM/latest/UserGuide/ManagingCredentials.html) export AWS_ACCESS_KEY=YOUR_ACCESS_KEY export AWS_SECRET_KEY=YOUR_SECRET_KEY #Region for this EC2 instance REGION=YOUR_REGION #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! AWS_PATH=$EC2_HOME VIP=$2 subnet () { SUB=`echo $VIP | awk '{ split($0,a,"."); print a[1]"."a[2]"."a[3]"."; }'` SUBNET=`$AWS_PATH/bin/ec2-describe-subnets --region $REGION | grep -F $SUB | awk '{print $2}'` echo Subnet-id: $SUBNET if [ -z "$SUBNET" ]; then echo "Wrong subnet!" exit 1; fi Instance_ID=`/usr/bin/curl --silent http://169.254.169.254/latest/meta-data/instance-id` echo Instance_ID=$Instance_ID ENI_ID=`$AWS_PATH/bin/ec2-describe-instances $Instance_ID --region $REGION | cut -f 2,3 | grep $SUBNET | awk '{print $1}'` echo ENI_ID=$ENI_ID } if_up () { subnet /usr/bin/sudo /sbin/ifconfig eth1:0 inet $VIP netmask 255.255.255.255 $AWS_PATH/bin/ec2-assign-private-ip-addresses -n $ENI_ID --secondary-private-ip-address $VIP --allow-reassignment --region $REGION } if_down (){ subnet /usr/bin/sudo /sbin/ifconfig eth1:0 down $AWS_PATH/bin/ec2-unassign-private-ip-addresses -n $ENI_ID --secondary-private-ip-address $VIP --region $REGION } case $1 in [uU][pP]) if_up break ;; [dD][oO][wW][nN]) if_down break ;; *) echo "Up/Down command missed!" exit 1 esac /usr/sbin/service networking restart > /dev/null 2>&1
Source: https://habr.com/ru/post/213409/