Репликация и балансировка в Postgresql 9.5

Настройка репликации Postgresql 9.5 на debian 8

С репликацией у postgresql пока не все просто, но она работает. Рассмотрим всё на примере.

1.Конфигурация

ОС debian 8 jessie
node1 – 10.4.1.161 – postgresql master
node2- 10.4.1.162 – postgresql standby1
node3- 10.4.1.163 – postgresql standby2
10.4.1.180 – ваш пк для проверки баз на репликацию, например через pgadmin3.

2.Добавляем репы postgresq 9.5

Добавляем репы Postgres(на 2 ноды)

wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo nano /etc/apt/sources.list.d/pgdg.list
deb https://apt.postgresql.org/pub/repos/apt/ jessie-pgdg main

3. Настройка нод

Создадим папку для пользователя postgres до установки его (на обе ноды)

sudo mkdir /home/postgres
sudo chown postgres -v  /home/postgres
sudo chgrp postgres -v /home/postgres

Ставим Postgresql 9.5

sudo apt-get install postgresql-9.5
sudo service postgresql stop
Зададим пароль для пользователя postgres
sudo passwd postgres

Создадим ключ для авторизации пользователей postgres(на 2 нодах)

sudo su postgres
cd /home/postgres
ssh-keygen -t rsa

ВНИМАНИЕ!!! СОЗДАЕМ КЛЮЧИ на обоих БЕЗ ПАРОЛЬНОЙ ФРАЗЫ!!!

cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
chmod go-rwx ~/.ssh/*

Переход на NODE1

cd /home/postgres
cd ~/.ssh
scp id_rsa.pub  postgres@10.4.1.162:/home/postgres/.ssh/id_rsa.pub1

Переход на NODE2

scp id_rsa.pub  postgres@10.4.1.161:/home/postgres/.ssh/id_rsa.pub2
cd /home/postgres
cat ~/.ssh/id_rsa.pub1 >> ~/.ssh/authorized_keys

Переход NODE1

cd /home/postgres
cat ~/.ssh/id_rsa.pub2 >> ~/.ssh/authorized_keys
sudo su postgresql  #user postgresql (смотрим еще раз чтобы юзер был postgres)

Таким же образом добавим 3 ноду – суть такая – все ноды должны подключаться друг к другу через пользователя postgres,
!!!!!!!!!а также необходимо добавить ключ для подключения postgresql к root!!!!!
Редактим конфиг:

sudo nano /etc/postgresql/9.5/main/pg_hba.conf

В любой точке файла (только не в конце) поместите следующие строки, которые откроют новому пользователю доступ к этому серверу:

host    replication     postgres       10.4.1.0/32            md5
hostnossl    replication             postgres       10.4.1.162/32            md5
hostnossl    replication             postgres       10.4.1.108/32            md5
host    all             postgres       10.4.1.0/32            md5
host    all              rep       10.4.1.0/32            md5

Save (ctrl+o)
Отредактируем конфиг postgres

sudo nano /etc/postgresql/9.5/main/postgresql.conf

Найдите в нём следующие параметры, раскомментируйте их и измените их значения таким образом:

listen_addresses = '*'
port = 5433
wal_level = hot_standby
archive_mode = on
archive_command = 'cd .'
wal_keep_segments = 64
max_wal_senders = 8
hot_standby = on
# опционально: не дожидаемся fsync на реплике при синхронной репликации
# synchronous_commit = remote_write
# если хотим синхронную репликацию на одну любую реплику
# synchronous_standby_names = '*'

Save(ctrl+o)
Далее открываем psql:

sudo su postgres
psql

Меняем пароль пользователя postgres:

ALTER ROLE postgres PASSWORD 'secretpass';

Перезапускаем PostgreSQL:

sudo service postgresql restart

Мастер настроен!

Переход на NODE2

Останавливаем PostgreSQL:

sudo service postgresql stop

Становимся пользователем postgres(вы должны были заранее,как говорилось выше создать пароль для postgre:

sudo su postgres

Сливаем данные с node1(мастера):
Под этим пользователем переливаем данные с мастера:

cd /var/lib/postgresql/9.5/
tar -cvzf main_backup-`date +%s`.tgz main
rm -rf main
mkdir main
chmod go-rwx main
pg_basebackup -P -R -X stream -c fast -h 10.4.1.161 -U postgres -D ./main

Попросят пароль от пользователя постгрес на 1 сервере(node1). Введем его.

Создадим конфиг рекавери на:

sudo nano /var/lib/postgresql/9.5/main/recovery.conf

Вставим строки в пустой файл:

##################################################
standby_mode = 'on'
primary_conninfo = 'host=10.4.1.161  port=5432 user=postgres password=2456'
trigger_file = '/var/lib/postgresql/9.5/main/trigger'
restore_command = 'cp /var/lib/postgresql/9.5/main/archive/%f "%p"'

Также в recovery.conf можно дописать:

recovery_min_apply_delay = 10min

… если вы хотите реплику, отстающую от мастера на заданное количество времени.
Это позволит быстро восстановить данные в случае выполненного случайно drop database.

Правим конфиг подлкючений на 2-й ноде

sudo nano /etc/postgresql/9.5/main/pg_hba.conf
host replication postgres 10.4.1.161/32 md5
hostnossl replication all 10.4.1.161/32 md5
hostnossl replication postgres 10.4.1.161/32 md5
hostnossl all postgres 10.4.1.108/32 md5
host all all 10.4.1.161/32 md5
hostnossl all all 10.4.1.161/32 md5

Настраиваем конфиг

sudo nano /etc/postgresql/9.5/main/postgresql.conf

Приводи к такому виду как на первом, только меняем listen_addresses

# какие адреса слушать, замените на IP сервера
listen_addresses = '10.4.1.162'
wal_level = hot_standby
# опционально: не дожидаемся fsync на реплике при синхронной репликации
# synchronous_commit = remote_write
# это нужно, чтобы работал pg_rewind
wal_log_hints = on
max_wal_senders = 8
wal_keep_segments = 64
# если хотим синхронную репликацию на одну любую реплику
# synchronous_standby_names = '*'
hot_standby = on

Запускаем PostgreSQL:

sudo service postgresql start

Проверяем висит ли Postgresql на порте

netstat -plnt4 | grep 5432

4.Проверка репликации

На мастере говорим:

sudo su postgres
psql
SELECT * FROM pg_stat_replication;
Видим
pid  | usesysid | usename  | application_name | client_addr | client_hostname | client_port |         backend_start         | backend_xmin |   state   | sent_location | write_location | flush_location | replay_location | sync_priority | sync_state
------+----------+----------+------------------+-------------+-----------------+-------------+-------------------------------+--------------+-----------+---------------+----------------+----------------+-----------------+---------------+------------
 1469 |       10 | postgres | walreceiver      | 10.4.1.162  |                 |       50276 | 2016-04-15 14:37:30.972511+05 |              | streaming | 0/18001010    | 0/18001010     | 0/18001010     | 0/18001010      |             0 | async
(1 строка)

На реплике(node2)

ps aux | grep receiver
Видим
postgres  1876  0.0  0.8 239024  8560 ?        Ss   15:06   0:00 postgres: wal receiver process

5.Переключаем реплику в режим мастера

Остановим мастер. Допустим, что-то случилось.

sudo su postgres
/usr/lib/postgresql/9.5/bin/pg_ctl promote -D /var/lib/postgresql/9.5/main/

В логе увидим:

LOG:  received promote request
FATAL:  terminating walreceiver process due to administrator command
LOG:  redo done at 2/63000DC0
LOG:  last completed transaction was at log time 2016-01-01 15:35:42
LOG:  selected new timeline ID: 5
LOG:  archive recovery complete
LOG:  MultiXact member wraparound protections are now enabled
LOG:  database system is ready to accept connections
LOG:  autovacuum launcher started

При этом в каталоге /var/lib/postgresql/9.5/main файл recovery.conf автоматически будет переименован в recovery.done.
Легко проверить, что в бывшую реплику теперь можно писать. Конечно, если только вы не использовали синхронную репликацию с одной-единственной репликой.
Интересно, что хотя реплику и можно промоутнуть до мастера без перезапуска PostgreSQL, на практике вы, вероятно, все же захотите его перезапустить по следующей причине. Дело в том, что приложение, которое ранее подключилось к этой реплике, так и будет использовать ее в качестве реплики даже после промоута, хотя операции чтения можно было бы размазать по остальным репликам в кластере. Перезапустив PostgreSQL, вы порвете все сетевые соединения, а значит приложению придется подключиться заново, проверить, подключился ли он к мастеру или реплике (запрос SELECT pg_is_in_recovery(); вернет false на мастере и true на репликах), и использовать сетевое соединение соответствующим образом.

6.Переключение на новый мастер оставшихся реплик и восстановление упавшего мастера до реплики.

Переключение остальных реплик на новый мастер, а также восстановление бывшего мастера в качестве реплики происходит одинаково.
Чтобы было чуть меньше путаницы с новым мастером, старым мастером, старой репликой и новой репликой, условимся, что сервера мы называем в соответствии с их текущими ролями. То есть, мастером мы называем новый мастер, бывший репликой до фейловера, а репликой — тот, второй сервер.
В простом и не совсем правильном варианте нужно отредактировать, или создать, если его еще нет, файл /var/lib/postgresql/9.5/main/recovery.conf, указав в нем правильный IP мастера, и сделать sudo service postgresql restart (простой reload не прокатит). Кто-то для того, чтобы не править конфиги и не останавливать СУБД, использует схему с балансировщиком и DNS, но я лично так никогда не делал. В любом случае, этот способ неправильный. Для того, чтобы все хорошо работало во всяких хитрых граничных случаях, реплику следует остановить, сделать pg_rewind, затем запустить реплику.
Утилита pg_rewind находит точку в WAL, начиная с которой WAL мастера и WAL реплики начинают расходиться. Затем она «перематывает» (отсюда и название) WAL реплики на эту точку и накатывает недостающую историю с мастера. Таким образом, реплика и мастер всегда приходят к консистентному состоянию. Плюс к этому pg_rewind синхронизирует файлы мастера и реплики намного быстрее, чем pg_basebackup или rsync.
Если вы считаете, что pg_rewind не требуется при использовании синхронной репликации, вот пример маловероятной, но теоретически возможной ситуации. У вас много серверов с PostgreSQL. Сервера в кластере умирают сравнительно часто, поэтому вы решили автоматизировать фейловер. Умирает мастер, запускается фейловер. Среди реплик находится та, что имеет наиболее длинный WAL, на ней делается pg_ctl promote. В этот момент с очень большой задержкой (скажем, 5 секунд — были какие-то сетевые проблемы) на другую реплику прилетает пакет от уже мертвого мастера, и WAL этой реплики становится длиннее WAL нового мастера. Вы не сможете подключить эту реплику к новому мастеру, все сломалось. Если вы хотите, чтобы фейловер работал в том числе и при таких странных граничных случаях, используйте pg_rewind.
Итак, на реплике говорим:

sudo su postgres
/usr/lib/postgresql/9.5/bin/pg_rewind -D /var/lib/postgresql/9.5/main/ --source-server="host=10.4.1.162 port=5432 user=postgres password=secretpass"

Типичный вывод:

servers diverged at WAL position 2/67002170 on timeline 5
rewinding from last common checkpoint at 2/67002100 on timeline 5
Done!

Перемещаем и правим recovery.conf:

sudo mv /var/lib/postgresql/9.5/main/recovery.done /var/lib/postgresql/9.5/main/recovery.conf
sudo nano /var/lib/postgresql/9.5/main/recovery.conf

Проверяем IP мастера и наличие строчки:

recovery_target_timeline = 'latest'

Запускаем реплику, смотрим в логи. Там обязательно должно быть:

LOG:  database system is ready to accept read only connections

Значит PostgreSQL работает в качестве реплики.
Если вдруг видим что-то вроде:

ERROR: requested WAL segment 0000000200000005 has already been removed

… значит реплика слишком отстала от мастера, и нужно перенести файлы с мастера при помощи pg_basebackup, как было описано в начале этой статьи.

7.Добавление дополнительного слейва postgresql

Допустим вам понадобилось добавить еще один slave, пусть это будет pg3.domain.local c ip адресом 10.4.1.163. Это всё делается очень просто.

  1. Устанавливаем postgresql там же образом как и 1-ый слейв, также редактируем postgres.conf
listen_addresses = 'localhost,10.4.1.163'
wal_level = hot_standby
archive_mode = on
archive_command = 'cd .'
wal_keep_segments = 64
max_wal_senders = 8
hot_standby = on
# опционально: не дожидаемся fsync на реплике при синхронной репликации
# synchronous_commit = remote_write
# если хотим синхронную репликацию на одну любую реплику
# synchronous_standby_names = '*'

Правим конфиг подлкючений на 3-й ноде

sudo nano /etc/postgresql/9.5/main/pg_hba.conf
host replication postgres 10.4.1.161/32 md5
hostnossl replication all 10.4.1.161/32 md5
hostnossl replication postgres 10.4.1.161/32 md5
hostnossl all postgres 10.4.1.108/32 md5
host all all 10.4.1.161/32 md5
hostnossl all all 10.4.1.161/32 md5
host replication postgres 10.4.1.162/32 md5
hostnossl replication all 10.4.1.162/32 md5
hostnossl replication postgres 10.4.1.162/32 md5
host all all 10.4.1.162/32 md5
hostnossl all all 10.4.1.162/32 md5

Сливаем данные с node1(мастера):
Под этим пользователем переливаем данные с мастера:

cd /var/lib/postgresql/9.5/
tar -cvzf main_backup-`date +%s`.tgz main
rm -rf main
mkdir main
chmod go-rwx main
pg_basebackup -P -R -X stream -c fast -h 10.4.1.161 -U postgres -D ./main

Попросят пароль от пользователя постгрес на 1 сервере(node1). Введем его.

Создадим конфиг рекавери на:

sudo nano /var/lib/postgresql/9.5/main/recovery.conf

Вставим строки в пустой файл:

##################################################
standby_mode = 'on'
primary_conninfo = 'host=10.4.1.161  port=5432 user=postgres password=2456'
trigger_file = '/var/lib/postgresql/9.5/main/trigger'
restore_command = 'cp /var/lib/postgresql/9.5/main/archive/%f "%p"'

Не забываем добавить на ТЕКУЩЕМ МАСТЕР сервере новую реплику в разрешенные подключения(ДОБАВИМ СТРОКИ НА МАСТЕР СЕРВЕРЕ, А ЗАОДНО И НАДРУГИХ РЕКПЛИКАХ, НА СЛУЧАЙ ПЕРЕХОДА ИХ В РЕЖИМ МАСТЕРА):

sudo nano /etc/postgresql/9.5/main/pg_hba.conf
host replication postgres 10.4.1.163/32 md5
hostnossl replication all 10.4.1.163/32 md5
hostnossl replication postgres 10.4.1.163/32 md5

8.Настройка балансировки через PGPOOL2

Если у вас несколько нод, то вы захотите настроить балансировку на них, чтобы подключение шло через одну точку.
Для этого мы будем использовать pgpool2.
Установка. Будем ставить из исходника, но для начала установим и удалим пакет – усвоил это урок из установки Nginx из исходников

apt-get install pgpool2 -y
apt-get remove l pgpool2 -y

Качаем исходники

cd /tmp
wget https://www.pgpool.net/download.php?f=pgpool-II-3.5.4.tar.gz
tar -xvf download.php?f=pgpool-II-3.5.4.tar.gz
cd download.php?f=pgpool-II-3.5.4

Ставим пакеты для сборки

apt-get install libpq-dev make checkinstall -y

Конфигурируем и устанавливаем

./configure
mkdir -p /usr/local/share/man
make -j4

Устанавливаем в систему

checkinstall

Переходим в каталог с файлами
cd /usr/local/etc

Настройка. Отредактируем файл pgpool.conf

 nano /etc/pgpool2/pgpool.conf

Удалим все и вставим след конфиг

# ----------------------------
# pgPool-II configuration file
# ----------------------------
#
# This file consists of lines of the form:
#
#   name = value
#
# Whitespace may be used.  Comments are introduced with "#" anywhere on a line.
# The complete list of parameter names and allowed values can be found in the
# pgPool-II documentation.
#
# This file is read on server startup and when the server receives a SIGHUP
# signal.  If you edit the file on a running system, you have to SIGHUP the
# server for the changes to take effect, or use "pgpool reload".  Some
# parameters, which are marked below, require a server shutdown and restart to
# take effect.
#
#------------------------------------------------------------------------------
# CONNECTIONS
#------------------------------------------------------------------------------
# - pgpool Connection Settings -
listen_addresses = '*'
                                   # Host name or IP address to listen on:
                                   # '*' for all, '' for no TCP/IP connections
                                   # (change requires restart)
port = 5432
                                   # Port number
                                   # (change requires restart)
socket_dir = '/var/run/postgresql'
                                   # Unix domain socket path
                                   # The Debian package defaults to
                                   # /var/run/postgresql
                                   # (change requires restart)
listen_backlog_multiplier = 2
                                   # Set the backlog parameter of listen(2) to
								   # num_init_children * listen_backlog_multiplier.
                                   # (change requires restart)
serialize_accept = off
                                   # whether to serialize accept() call to avoid thundering herd problem
                                   # (change requires restart)
# - pgpool Communication Manager Connection Settings -
pcp_listen_addresses = '*'
                                   # Host name or IP address for pcp process to listen on:
                                   # '*' for all, '' for no TCP/IP connections
                                   # (change requires restart)
pcp_port = 9898
                                   # Port number for pcp
                                   # (change requires restart)
pcp_socket_dir = '/var/run/postgresql'
                                   # Unix domain socket path for pcp
                                   # The Debian package defaults to
                                   # /var/run/postgresql
                                   # (change requires restart)
# - Backend Connection Settings -
backend_hostname0 = '10.4.1.161 '
backend_port0 = 5433
backend_weight0 = 1
backend_data_directory0 = '/var/lib/postgresql/9.5/main'
backend_flag0 = 'ALLOW_TO_FAILOVER'
backend_hostname1 = '10.4.1.162 '
backend_port1 = 5433
backend_weight1 = 1
backend_data_directory1 = '/var/lib/postgresql/9.5/main'
backend_flag1 = 'ALLOW_TO_FAILOVER'
backend_hostname1 = '10.4.1.163 '
backend_port1 = 5433
backend_weight1 = 1
backend_data_directory1 = '/var/lib/postgresql/9.5/main'
backend_flag1 = 'ALLOW_TO_FAILOVER'
# - Authentication -
enable_pool_hba = on
                                   # Use pool_hba.conf for client authentication
pool_passwd = 'pool_passwd'
                                   # File name of pool_passwd for md5 authentication.
                                   # "" disables pool_passwd.
                                   # (change requires restart)
authentication_timeout = 60
                                   # Delay in seconds to complete client authentication
                                   # 0 means no timeout.
# - SSL Connections -
ssl = off
                                   # Enable SSL support
                                   # (change requires restart)
#ssl_key = './server.key'
                                   # Path to the SSL private key file
                                   # (change requires restart)
#ssl_cert = './server.cert'
                                   # Path to the SSL public certificate file
                                   # (change requires restart)
#ssl_ca_cert = ''
                                   # Path to a single PEM format file
                                   # containing CA root certificate(s)
                                   # (change requires restart)
#ssl_ca_cert_dir = ''
                                   # Directory containing CA root certificate(s)
                                   # (change requires restart)
#------------------------------------------------------------------------------
# POOLS
#------------------------------------------------------------------------------
# - Concurrent session and pool size -
num_init_children = 32
                                   # Number of concurrent sessions allowed
                                   # (change requires restart)
max_pool = 4
                                   # Number of connection pool caches per connection
                                   # (change requires restart)
# - Life time -
child_life_time = 300
                                   # Pool exits after being idle for this many seconds
child_max_connections = 0
                                   # Pool exits after receiving that many connections
                                   # 0 means no exit
connection_life_time = 0
                                   # Connection to backend closes after being idle for this many seconds
                                   # 0 means no close
client_idle_limit = 0
                                   # Client is disconnected after being idle for that many seconds
                                   # (even inside an explicit transactions!)
                                   # 0 means no disconnection
#------------------------------------------------------------------------------
# LOGS
#------------------------------------------------------------------------------
# - Where to log -
log_destination = 'stderr'
                                   # Where to log
                                   # Valid values are combinations of stderr,
                                   # and syslog. Default to stderr.
# - What to log -
log_line_prefix = '%t: pid %p: '   # printf-style string to output at beginning of each log line.
log_connections = off
                                   # Log connections
log_hostname = off
                                   # Hostname will be shown in ps status
                                   # and in logs if connections are logged
log_statement = off
                                   # Log all statements
log_per_node_statement = on
                                   # Log all statements
                                   # with node and backend informations
log_standby_delay = 'none'
                                   # Log standby delay
                                   # Valid values are combinations of always,
                                   # if_over_threshold, none
# - Syslog specific -
syslog_facility = 'LOCAL0'
                                   # Syslog local facility. Default to LOCAL0
syslog_ident = 'pgpool'
                                   # Syslog program identification string
                                   # Default to 'pgpool'
# - Debug -
debug_level = 0
                                   # Debug message verbosity level
                                   # 0 means no message, 1 or more mean verbose
#log_error_verbosity = default          # terse, default, or verbose messages
#client_min_messages = notice           # values in order of decreasing detail:
                                        #   debug5
                                        #   debug4
                                        #   debug3
                                        #   debug2
                                        #   debug1
                                        #   log
                                        #   notice
                                        #   warning
                                        #   error
#log_min_messages = warning             # values in order of decreasing detail:
                                        #   debug5
                                        #   debug4
                                        #   debug3
                                        #   debug2
                                        #   debug1
                                        #   info
                                        #   notice
                                        #   warning
                                        #   error
                                        #   log
                                        #   fatal
                                        #   panic
#------------------------------------------------------------------------------
# FILE LOCATIONS
#------------------------------------------------------------------------------
pid_file_name = '/var/run/postgresql/pgpool.pid'
                                   # PID file name
                                   # (change requires restart)
logdir = '/var/log/postgresql'
                                   # Directory of pgPool status file
                                   # (change requires restart)
#------------------------------------------------------------------------------
# CONNECTION POOLING
#------------------------------------------------------------------------------
connection_cache = on
                                   # Activate connection pools
                                   # (change requires restart)
                                   # Semicolon separated list of queries
                                   # to be issued at the end of a session
                                   # The default is for 8.3 and later
reset_query_list = 'ABORT; DISCARD ALL'
                                   # The following one is for 8.2 and before
#reset_query_list = 'ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT'
#------------------------------------------------------------------------------
# REPLICATION MODE
#------------------------------------------------------------------------------
replication_mode = off
                                   # Activate replication mode
                                   # (change requires restart)
replicate_select = off
                                   # Replicate SELECT statements
                                   # when in replication mode
                                   # replicate_select is higher priority than
                                   # load_balance_mode.
insert_lock = on
                                   # Automatically locks a dummy row or a table
                                   # with INSERT statements to keep SERIAL data
                                   # consistency
                                   # Without SERIAL, no lock will be issued
lobj_lock_table = ''
                                   # When rewriting lo_creat command in
                                   # replication mode, specify table name to
                                   # lock
# - Degenerate handling -
replication_stop_on_mismatch = off
                                   # On disagreement with the packet kind
                                   # sent from backend, degenerate the node
                                   # which is most likely "minority"
                                   # If off, just force to exit this session
failover_if_affected_tuples_mismatch = off
                                   # On disagreement with the number of affected
                                   # tuples in UPDATE/DELETE queries, then
                                   # degenerate the node which is most likely
                                   # "minority".
                                   # If off, just abort the transaction to
                                   # keep the consistency
#------------------------------------------------------------------------------
# LOAD BALANCING MODE
#------------------------------------------------------------------------------
load_balance_mode = on
                                   # Activate load balancing mode
                                   # (change requires restart)
ignore_leading_white_space = on
                                   # Ignore leading white spaces of each query
white_function_list = ''
                                   # Comma separated list of function names
                                   # that don't write to database
                                   # Regexp are accepted
black_function_list = 'nextval,setval,nextval,setval'
                                   # Comma separated list of function names
                                   # that write to database
                                   # Regexp are accepted
database_redirect_preference_list = ''
								   # comma separated list of pairs of database and node id.
								   # example: postgres:primary,mydb[0-4]:1,mydb[5-9]:2'
								   # valid for streaming replicaton mode only.
app_name_redirect_preference_list = ''
								   # comma separated list of pairs of app name and node id.
								   # example: 'psql:primary,myapp[0-4]:1,myapp[5-9]:standby'
								   # valid for streaming replicaton mode only.
allow_sql_comments = off
								   # if on, ignore SQL comments when judging if load balance or
								   # query cache is possible.
								   # If off, SQL comments effectively prevent the judgment
								   # (pre 3.4 behavior).
#------------------------------------------------------------------------------
# MASTER/SLAVE MODE
#------------------------------------------------------------------------------
master_slave_mode = off
                                   # Activate master/slave mode
                                   # (change requires restart)
master_slave_sub_mode = 'slony'
                                   # Master/slave sub mode
                                   # Valid values are combinations slony or
                                   # stream. Default is slony.
                                   # (change requires restart)
# - Streaming -
sr_check_period = 0
                                   # Streaming replication check period
                                   # Disabled (0) by default
sr_check_user = 'nobody'
                                   # Streaming replication check user
                                   # This is necessary even if you disable
                                   # streaming replication delay check with
                                   # sr_check_period = 0
sr_check_password = ''
                                   # Password for streaming replication check user
sr_check_database = 'postgres'
                                   # Database name for streaming replication check
delay_threshold = 0
                                   # Threshold before not dispatching query to standby node
                                   # Unit is in bytes
                                   # Disabled (0) by default
# - Special commands -
follow_master_command = ''
                                   # Executes this command after master failover
                                   # Special values:
                                   #   %d = node id
                                   #   %h = host name
                                   #   %p = port number
                                   #   %D = database cluster path
                                   #   %m = new master node id
                                   #   %H = hostname of the new master node
                                   #   %M = old master node id
                                   #   %P = old primary node id
                                   #   %r = new master port number
                                   #   %R = new master database cluster path
                                   #   %% = '%' character
#------------------------------------------------------------------------------
# HEALTH CHECK
#------------------------------------------------------------------------------
health_check_period = 5
                                   # Health check period
                                   # Disabled (0) by default
health_check_timeout = 0
                                   # Health check timeout
                                   # 0 means no timeout
health_check_user = 'postgres'
                                   # Health check user
health_check_password = ''
                                   # Password for health check user
health_check_database = ''
                                   # Database name for health check. If '', tries 'postgres' frist, then 'template1'
health_check_max_retries = 0
                                   # Maximum number of times to retry a failed health check before giving up.
health_check_retry_delay = 1
                                   # Amount of time to wait (in seconds) between retries.
connect_timeout = 10000
                                   # Timeout value in milliseconds before giving up to connect to backend.
								   # Default is 10000 ms (10 second). Flaky network user may want to increase
								   # the value. 0 means no timeout.
								   # Note that this value is not only used for health check,
								   # but also for ordinary conection to backend.
#------------------------------------------------------------------------------
# FAILOVER AND FAILBACK
#------------------------------------------------------------------------------
failover_command = ''
                                   # Executes this command at failover
                                   # Special values:
                                   #   %d = node id
                                   #   %h = host name
                                   #   %p = port number
                                   #   %D = database cluster path
                                   #   %m = new master node id
                                   #   %H = hostname of the new master node
                                   #   %M = old master node id
                                   #   %P = old primary node id
                                   #   %r = new master port number
                                   #   %R = new master database cluster path
                                   #   %% = '%' character
failback_command = ''
                                   # Executes this command at failback.
                                   # Special values:
                                   #   %d = node id
                                   #   %h = host name
                                   #   %p = port number
                                   #   %D = database cluster path
                                   #   %m = new master node id
                                   #   %H = hostname of the new master node
                                   #   %M = old master node id
                                   #   %P = old primary node id
                                   #   %r = new master port number
                                   #   %R = new master database cluster path
                                   #   %% = '%' character
fail_over_on_backend_error = on
                                   # Initiates failover when reading/writing to the
                                   # backend communication socket fails
                                   # If set to off, pgpool will report an
                                   # error and disconnect the session.
search_primary_node_timeout = 10
                                   # Timeout in seconds to search for the
                                   # primary node when a failover occurs.
                                   # 0 means no timeout, keep searching
                                   # for a primary node forever.
#------------------------------------------------------------------------------
# ONLINE RECOVERY
#------------------------------------------------------------------------------
recovery_user = 'nobody'
                                   # Online recovery user
recovery_password = ''
                                   # Online recovery password
recovery_1st_stage_command = ''
                                   # Executes a command in first stage
recovery_2nd_stage_command = ''
                                   # Executes a command in second stage
recovery_timeout = 90
                                   # Timeout in seconds to wait for the
                                   # recovering node's postmaster to start up
                                   # 0 means no wait
client_idle_limit_in_recovery = 0
                                   # Client is disconnected after being idle
                                   # for that many seconds in the second stage
                                   # of online recovery
                                   # 0 means no disconnection
                                   # -1 means immediate disconnection
#------------------------------------------------------------------------------
# WATCHDOG
#------------------------------------------------------------------------------
# - Enabling -
use_watchdog = off
                                    # Activates watchdog
                                    # (change requires restart)
# -Connection to up stream servers -
trusted_servers = ''
                                    # trusted server list which are used
                                    # to confirm network connection
                                    # (hostA,hostB,hostC,...)
                                    # (change requires restart)
ping_path = '/bin'
                                    # ping command path
                                    # (change requires restart)
# - Watchdog communication Settings -
wd_hostname = 'dockerbase113'
                                    # Host name or IP address of this watchdog
                                    # (change requires restart)
wd_port = 9000
                                    # port number for watchdog service
                                    # (change requires restart)
wd_priority = 1
									# priority of this watchdog in leader election
									# (change requires restart)
wd_authkey = ''
                                    # Authentication key for watchdog communication
                                    # (change requires restart)
wd_ipc_socket_dir = '/tmp'
									# Unix domain socket path for watchdog IPC socket
									# The Debian package defaults to
									# /var/run/postgresql
									# (change requires restart)
# - Virtual IP control Setting -
delegate_IP = ''
                                    # delegate IP address
                                    # If this is empty, virtual IP never bring up.
                                    # (change requires restart)
if_cmd_path = '/sbin'
                                    # path to the directory where if_up/down_cmd exists
                                    # (change requires restart)
if_up_cmd = 'ip addr add $_IP_$/24 dev eth0 label eth0:0'
                                    # startup delegate IP command
                                    # (change requires restart)
if_down_cmd = 'ip addr del $_IP_$/24 dev eth0'
                                    # shutdown delegate IP command
                                    # (change requires restart)
arping_path = '/usr/sbin'
                                    # arping command path
                                    # (change requires restart)
arping_cmd = 'arping -U $_IP_$ -w 1'
                                    # arping command
                                    # (change requires restart)
# - Behaivor on escalation Setting -
clear_memqcache_on_escalation = on
                                    # Clear all the query cache on shared memory
                                    # when standby pgpool escalate to active pgpool
                                    # (= virtual IP holder).
                                    # This should be off if client connects to pgpool
                                    # not using virtual IP.
                                    # (change requires restart)
wd_escalation_command = ''
                                    # Executes this command at escalation on new active pgpool.
                                    # (change requires restart)
wd_de_escalation_command = ''
									# Executes this command when master pgpool resigns from being master.
									# (change requires restart)
# - Lifecheck Setting -
# -- common --
wd_monitoring_interfaces_list = ''  # Comma separated list of interfaces names to monitor.
									# if any interface from the list is active the watchdog will
									# consider the network is fine
									# 'any' to enable monitoring on all interfaces except loopback
									# '' to disable monitoring
wd_lifecheck_method = 'heartbeat'
                                    # Method of watchdog lifecheck ('heartbeat' or 'query' or 'external')
                                    # (change requires restart)
wd_interval = 3
                                    # lifecheck interval (sec) > 0
                                    # (change requires restart)
# -- heartbeat mode --
wd_heartbeat_port = 9694
                                    # Port number for receiving heartbeat signal
                                    # (change requires restart)
wd_heartbeat_keepalive = 2
                                    # Interval time of sending heartbeat signal (sec)
                                    # (change requires restart)
wd_heartbeat_deadtime = 30
                                    # Deadtime interval for heartbeat signal (sec)
                                    # (change requires restart)
heartbeat_destination0 = 'host0_ip1'
                                    # Host name or IP address of destination 0
                                    # for sending heartbeat signal.
                                    # (change requires restart)
heartbeat_destination_port0 = 9694
                                    # Port number of destination 0 for sending
                                    # heartbeat signal. Usually this is the
                                    # same as wd_heartbeat_port.
                                    # (change requires restart)
heartbeat_device0 = ''
                                    # Name of NIC device (such like 'eth0')
                                    # used for sending/receiving heartbeat
                                    # signal to/from destination 0.
                                    # This works only when this is not empty
                                    # and pgpool has root privilege.
                                    # (change requires restart)
#heartbeat_destination1 = 'host0_ip2'
#heartbeat_destination_port1 = 9694
#heartbeat_device1 = ''
# -- query mode --
wd_life_point = 3
                                    # lifecheck retry times
                                    # (change requires restart)
wd_lifecheck_query = 'SELECT 1'
                                    # lifecheck query to pgpool from watchdog
                                    # (change requires restart)
wd_lifecheck_dbname = 'template1'
                                    # Database name connected for lifecheck
                                    # (change requires restart)
wd_lifecheck_user = 'nobody'
                                    # watchdog user monitoring pgpools in lifecheck
                                    # (change requires restart)
wd_lifecheck_password = ''
                                    # Password for watchdog user in lifecheck
                                    # (change requires restart)
# - Other pgpool Connection Settings -
#other_pgpool_hostname0 = 'host0'
                                    # Host name or IP address to connect to for other pgpool 0
                                    # (change requires restart)
#other_pgpool_port0 = 5432
                                    # Port number for othet pgpool 0
                                    # (change requires restart)
#other_wd_port0 = 9000
                                    # Port number for othet watchdog 0
                                    # (change requires restart)
#other_pgpool_hostname1 = 'host1'
#other_pgpool_port1 = 5432
#other_wd_port1 = 9000
#------------------------------------------------------------------------------
# OTHERS
#------------------------------------------------------------------------------
relcache_expire = 0
                                   # Life time of relation cache in seconds.
                                   # 0 means no cache expiration(the default).
                                   # The relation cache is used for cache the
                                   # query result against PostgreSQL system
                                   # catalog to obtain various information
                                   # including table structures or if it's a
                                   # temporary table or not. The cache is
                                   # maintained in a pgpool child local memory
                                   # and being kept as long as it survives.
                                   # If someone modify the table by using
                                   # ALTER TABLE or some such, the relcache is
                                   # not consistent anymore.
                                   # For this purpose, cache_expiration
                                   # controls the life time of the cache.
relcache_size = 256
                                   # Number of relation cache
                                   # entry. If you see frequently:
                                   # "pool_search_relcache: cache replacement happend"
                                   # in the pgpool log, you might want to increate this number.
check_temp_table = on
                                   # If on, enable temporary table check in SELECT statements.
                                   # This initiates queries against system catalog of primary/master
                                   # thus increases load of master.
                                   # If you are absolutely sure that your system never uses temporary tables
                                   # and you want to save access to primary/master, you could turn this off.
                                   # Default is on.
check_unlogged_table = on
                                   # If on, enable unlogged table check in SELECT statements.
                                   # This initiates queries against system catalog of primary/master
                                   # thus increases load of master.
                                   # If you are absolutely sure that your system never uses unlogged tables
                                   # and you want to save access to primary/master, you could turn this off.
                                   # Default is on.
#------------------------------------------------------------------------------
# IN MEMORY QUERY MEMORY CACHE
#------------------------------------------------------------------------------
memory_cache_enabled = on
								   # If on, use the memory cache functionality, off by default
memqcache_method = 'shmem'
								   # Cache storage method. either 'shmem'(shared memory) or
								   # 'memcached'. 'shmem' by default
                                   # (change requires restart)
#memqcache_memcached_host = '10.1.8.113'
								   # Memcached host name or IP address. Mandatory if
								   # memqcache_method = 'memcached'.
								   # Defaults to localhost.
                                   # (change requires restart)
memqcache_memcached_port = 11211
								   # Memcached port number. Mondatory if memqcache_method = 'memcached'.
								   # Defaults to 11211.
                                   # (change requires restart)
memqcache_total_size = 536870912
								   # Total memory size in bytes for storing memory cache.
								   # Mandatory if memqcache_method = 'shmem'.
								   # Defaults to 64MB.
                                   # (change requires restart)
memqcache_max_num_cache = 1000000
								   # Total number of cache entries. Mandatory
								   # if memqcache_method = 'shmem'.
								   # Each cache entry consumes 48 bytes on shared memory.
								   # Defaults to 1,000,000(45.8MB).
                                   # (change requires restart)
memqcache_expire = 1800
								   # Memory cache entry life time specified in seconds.
								   # 0 means infinite life time. 0 by default.
                                   # (change requires restart)
memqcache_auto_cache_invalidation = on
								   # If on, invalidation of query cache is triggered by corresponding
								   # DDL/DML/DCL(and memqcache_expire).  If off, it is only triggered
								   # by memqcache_expire.  on by default.
                                   # (change requires restart)
memqcache_maxcache = 409600
								   # Maximum SELECT result size in bytes.
								   # Must be smaller than memqcache_cache_block_size. Defaults to 400KB.
                                   # (change requires restart)
memqcache_cache_block_size = 1048576
								   # Cache block size in bytes. Mandatory if memqcache_method = 'shmem'.
								   # Defaults to 1MB.
                                   # (change requires restart)
memqcache_oiddir = '/var/oiddir'
				   				   # Temporary work directory to record table oids
                                   # (change requires restart)
white_memqcache_table_list = ''
                                   # Comma separated list of table names to memcache
                                   # that don't write to database
                                   # Regexp are accepted
black_memqcache_table_list = ''
                                   # Comma separated list of table names not to memcache
                                   # that don't write to database
                                   # Regexp are accepted

Заметьте порт у нас 5432, а сам постгрес крутится на 5433, т.е. pgpool2 можно ставить на нады с postgresql.
Отредактим файл подключений pool_hba.conf

# "local" is for Unix domain socket connections only
local   all         all                               trust
host    all             all             0.0.0.0/0                 md5
# IPv4 local connections:
host    all         all         127.0.0.1/32          trust
host    all         all         ::1/128               trust
host    all             all             0.0.0.0/0                 md5

Отредактим файл c паролями для подключениями к pgpool2

 nano /etc/pgpool2/pool_passwd

Туда надо вставить пользователя и его md5 пароль

postgres:md56201f7f8f806d0b40206f4559cf8f9b1
test_user:md5bf838df783fc863ba5144815e9d88a99

ВАЖНО!!! Пароль получаем из postgresql

su postgres
psql
select passwd from pg_shadow where usename = 'username';

И получим пароль. Вставим его в файл. Применяем права на каталог pgpool и рестартимся.

chown -R -v postgres:postgres /etc/pgpool2/
/etc/init.d/postgtresql restart

8.Заключение

Всё мы получили репликацию и балансировку.

2 комментария к “Репликация и балансировка в Postgresql 9.5

  1. Очень хорошая статья, спасибо большое. есть несколько вопросов: правильно ли я поняла, что pg pool используется только для балансировки нагрузки? и здесь не рассматривается пример автоматической смены слейва на мастер, в случае падения мастера и обратного восстановления ? Нет ли такой же стать на эту тему?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

 

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.