Tutorial PostgreSQL em alta disponibilidade com replicação síncrona e balanceamento de carga usando PgPool-II sobre Debian GNU / Linux

Nem toda aplicação em produção precisará de todas as vantagens e custos associados. Para estas, uma solução para replicação assíncrona seria suficiente e com menores custos em complexidade, compatibilidade e desempenho.

Neste tutorial, testado sobre Debian GNU/Linux 5.x, analisaremos implantação com o Pgpool-II. Lembre que são publicadas configurações sem segurança de ambientes de produção, apenas para laboratório. Para implantações, tome todas as medidas para garantir segurança de seu ambiente.

Pgpool-II em modo replicação síncrona com balanceamento de carga

As versões a partir de 2010 , v2.3.x, do pgpool2 resolveram alguns problemas críticos da replicação síncrona de sgbd PostgreSQL.
Notoriamente, as seqüências seriais e as funções de tempo.

O pgpool2 v2.3.x permite uma solução de replicação não intrusiva aos backends.

Não é necessário modificar código fonte do PostgreSQL.

Os servidores backend nem sequer precisam ser alterados em configuração (claro que configurações de segurança são recomendadas). Os backends conversam com um "cliente" que lhes envia as queries.

As leituras podem ser balanceadas entre os servidores backend. Cada cliente se conecta a um servidor backend até o fim das suas transações.

As escritas são serializadas, escrevendo em cada um dos servidores backend seqüencialmente. Isso implica em escritas cada vez mais lentas, e leituras cada vez mais rápidas, à medida que se acrescentam servidores e clientes.

O pgpool2 v2.3.x intercepta as queries e as reescreve, se necessário, antes de enviá-las aos servidores backend.

As versões 2.3.x adotam a abordagem de eleger um "master" e enviam as funções de tempo originais a esse, recolhem os resultados e reescrevem as queries embutindo os resultados prontos aos outros backends.

Para garantir consistência de seqüências entre servidores, ativamos a opção de travar tabelas inteiras caso seja detetada uma função dessas enquanto durar a replicação da transação.

Nos primeiros testes das configurações abaixo optamos por configurações conservadoras para garantir máxima consistência.

Mais adiante, optamos por uma abordagem menos agressiva e implantamos travamento de registros em grupos críticos de transações.

http://lists.pgfoundry.org/pipermail/pgpool-general/2010-December/003171.html

O sgbd PostgreSQL utiliza MVCC para resolver o acesso concorrente a dados num backend.

Excelente desempenho e confiabilidade num servidor.

Mas como resolver o acesso concorrente a um mesmo dado entre vários servidores backend? A solução encontrada foi

begin;
lock table phpgw_preferences in share row exclusive mode;

sql statements.....

commit;
discard all;

Durante os testes identificamos a necessidade de alterar código do pgpool2 para que processasse corretamente campos de tempo e timestamps com valores default com cast para big int. "Peculiaridade" da modelagem do banco de dados do Expresso Livre.

Nossa equipe da divisão SUPSI/SIETE/SITCE PAE apresentou esse problema ao projeto na threadhttp://lists.pgfoundry.org/pipermail/pgpool-general/2010-August/002888.html que resultou em alteração de código no repositório de desenvolvimento do pgpool-II.

À época da tomada de decisão, a base de código 2.3.x era já bastante estável e a base de código 3.x ainda nem havia sido lançada. Mesmo após lançamento, acreditamos que a base de código 3.x deverá atingir estabilidade aproximadamente após julho de 2011.

Assim, estávamos utilizando uma versão não lançada oficialmente, a 2.3.4, que tem poucas mas críticas para oExpresso em Nuvem modificações sobre a versão 2.3.3 e que empacotamos para Debian GNU / Linux 5.x.

 

Quando escolher replicação síncrona com pgpool-II para o PostgreSQL

A replicação síncrona master-master de bancos de dados é um problema de solução nada trivial mas que com o uso do pgpool-II viabilizou vantagens atraentes ao contexto do Expresso em Nuvem.

  • Transparência para a aplicação cliente (Expresso Livre).
  • Chaveamento (failover) automatizado em caso de falha, com temporização configurável.
  • Tempo de indisponibilidade próximo de zeroconfigurável.
  • Nenhuma perda de dados em caso de falhas individuais dos backends.
  • Nenhuma janela de tempo para perdas de dados, como em replicação assíncrona.
  • Não modificação do código do PostgreSQL, viabilizando atualizações tranqüilas de backends.
  • Balanceamento de carga de leitura (90% no caso do Expresso).
  • Garantia de consistência de leitura de dados entre qualquer dos backends, mesmo sob carga máxima. Uma leitura sempre receberá dados atualizados e consistentes em qualquer momento.
  • Boa escalabilidade horizontal para perfil de leitura.
  • Replicação da carga de escrita, eliminando Ponto Único de Falhas (SPOF) nesse nível hierárquico da arquitetura.
  • Maior aderência aos conceitos de nuvem computacional.
  • Simplificação do plano de contingências.
  • Backup e restore simplificados.
  • Viabilização de acordos de nível operacional com requisitos bastante restritivos de disponibilidade e continuidade.
  • Mínima carga e uso de recursos de hardware para processamento de queries que envolvam muitos registros, ao contrário da replicação assíncrona por triggers.
  • Maior simplicidade e agilidade de manutenção por equipes de produção.
  • Deteção automática de inconsistências entre backends e descomissionamento de servidores.
  • Replicação completa (master-master) permitindo que qualquer backend possa imediata e automaticamente ser utilizado como referência de consistência de dados após falha de outro backend.
  • Recomissionamento de servidores backend mais simplificado por equipes de produção.
  • Arquitetura modular que possibilita ter replicação síncrona e assíncrona num mesmo cluster de servidores, se necessário, em níveis hierárquicos e até distribuição geográfica para os níveis assíncronos.

A deficiência principal da replicação síncrona na versão 2.3.x do pgpool2 é que as escritas são serializadas em tempo.

Cada novo servidor backend adiciona seu tempo de resposta ao tempo final para ter concluída uma operação de escrita ao cluster de servidores.

As leituras são balanceadas entre os backends.

Portanto, quanto mais servidores backends, aparentam mais lentas as escritas e mais rápidas as leituras.

Dependendo do perfil da aplicação, pode ou não ser uma solução adequada.

Também é necessário que os backends estejam conectados por redes de alta velocidade e muito baixa latência, para mínimo impacto ao usuário.

/etc/hosts

O pgpool2 precisa encontrar os backends por nome das máquinas. Se o DNS não está configurado, pode-se editar o /etc/hosts para incluir as máquinas necessárias. Faça algo SIMILAR ao exemplo abaixo, adequando a sua necessidade.

127.0.0.1 localhost
127.0.1.1 debian.pae.serpro debian
10.200.27.40 debian.pae.serpro debian
10.200.240.153 debian240153
10.200.240.154 debian240154

# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

Configuração do PostgreSQL para o banco de dados de sistema pgpool-II

/etc/postgresql/8.3/main/postgresql.conf

Trecho do arquivo. Outras configurações no mesmo preservadas. Configurações sem as restrições de segurança para ambientes de produção.

#------------------------------------------------------------------------------
# CONNECTIONS AND AUTHENTICATION
#------------------------------------------------------------------------------

# - Connection Settings -

#AFM 27jul2010
listen_addresses = '*'

#listen_addresses = 'localhost' # what IP address(es) to listen on;
# comma-separated list of addresses;
# defaults to 'localhost', '*' = all
# (change requires restart)
port = 5432 # (change requires restart)

/etc/postgresql/8.3/main/pg_hba.conf

Trecho do arquivo. Outras configurações no mesmo preservadas. Configurações sem as restrições de segurança para ambientes de produção.

# DO NOT DISABLE!
# If you change this first entry you will need to make sure that the
# database
# super user can access the database using some other method.
# Noninteractive
# access to all databases is required during automatic maintenance
# (autovacuum, daily cronjob, replication, and similar tasks).
#
# Database administrative login by UNIX sockets
local all postgres ident sameuser

# TYPE DATABASE USER CIDR-ADDRESS METHOD

# "local" is for Unix domain socket connections only
#local all all ident sameuser
# AFM 17set2009 for bucardo tests trust
local all all trust
# IPv4 local connections:
# AFM 27jul2009
#host all all 127.0.0.1/32 md5
#host all all 127.0.0.1/32 password
# AFM 17set2009 for bucardo tests trust
host all all 127.0.0.1/32 trust
# IPv6 local connections:
host all all ::1/128 md5

#AFM 27jul2010
host all all 10.200.27.40/32 trust

Criação do banco de dados de sistema pgpool-II

É necessário criar o banco de dados de sistema pgpool na máquina frontend seguindo instruções do tutorial.

http://pgpool.projects.postgresql.org/pgpool-II/doc/tutorial-en.html#system-db

Também é necessário configurar usuários e permissões para tal banco de sistema.

http://pgpool.projects.postgresql.org/pgpool-II/doc/pgpool-en.html

andremachado@debian:~$ su -
Senha:
debian:~# apt-get install postgresql-contrib
debian:~# find / -name dblink.sql
debian:~# find / -name system_db.sql
debian:~# su postgres
postgres@debian:/root$ createuser --superuser --pwprompt pgpool
postgres@debian:/root$ createdb --owner pgpool pgpool
postgres@debian:/root$ psql -f /usr/share/postgresql/8.3/contrib/dblink.sql -p 5432 pgpool
postgres@debian:/root$ psql -f /usr/share/pgpool-II/system_db.sql -p 5432 -U pgpool pgpool

/etc/pgpool2/pcp.conf

O string de senha não é real.

Como estamos usando um usuário específico para o gerenciamento, que já exista para o sgbd, precisamos fazer o comando abaixo que gerará o string para colocarmos no arquivo de configuração

andremachado@debian:~$ /usr/sbin/pg_md5 andremachado
da09d8fapidfapdfy8adfadfa0dfadauad

# PCP Client Authentication Configuration File
# ============================================
#
# This file contains user ID and his password for pgpool
# communication manager authentication.
#
# Note that users defined here do not need to be PostgreSQL
# users. These users are authorized ONLY for pgpool
# communication manager.
#
# File Format
# ===========
#
# List one UserID and password on a single line. They must
# be concatenated together using ':' (colon) between them.
# No spaces or tabs are allowed anywhere in the line.
#
# Example:
# postgres:e8a48653851e28c69d0506508fb27fc5
#
# Be aware that there will be no spaces or tabs at the
# beginning of the line! although the above example looks
# like so.
#
# Lines beginning with '#' (pound) are comments and will
# be ignored. Again, no spaces or tabs allowed before '#'.

# USERID:MD5PASSWD
#AFM 27jul2010
andremachado:da09d8fapidfapdfy8adfadfa0dfadauad

/etc/pgpool2/pool_hba.conf

O controle de autenticação no pool é bem similar ao do postgresql. Nesse estudo, usamos configuração delaboratório inicial, sem restrições de segurança. O pgpool é bastante crítico para essas configurações.

# pgpool Client Authentication Configuration File
# ===============================================
#
# The format rule in this file follows the rules in the PostgreSQL
# Administrator's Guide. Refer to chapter "Client Authentication" for a
# complete description. A short synopsis follows.
#
# This file controls: which hosts are allowed to connect, how clients
# are authenticated, which user names they can use, which databases they
# can access. Records take one of these forms:
#
# local DATABASE USER METHOD [OPTION]
# host DATABASE USER CIDR-ADDRESS METHOD [OPTION]
# hostnossl DATABASE USER CIDR-ADDRESS METHOD [OPTION]
#
# (The uppercase items must be replaced by actual values.)
#
# The first field is the connection type: "local" is a Unix-domain socket,
# "host" is a plain TCP/IP socket since pgpool currently doest not support
# SSL connection. "hostnossl" is also a plain TCP/IP socket.
#
# DATABASE can be "all", "sameuser", a database name, or a comma-separated
# list thereof. Note that "samegroup" like in PostgreSQL's pg_hba.conf
# file is not supported, since pgpool does not know which group a user
# belongs to. Also note that the database specified here may not exist in
# the backend PostgreSQL. pgpool will authenticate based on the database's
# name, not based on whether it exists or not.
#
# USER can be "all", a user name, or a comma-separated list thereof. In
# both the DATABASE and USER fields you can also write a file name prefixed
# with "@" to include names from a separate file. Note that a group name
# prefixed with "+" like in PostgreSQL's pg_hba.conf file is not supported
# because of the same reason as "samegroup" token. Also note that a user
# name specified here may not exist in the backend PostgreSQL. pgpool will
# authenticate based on the user's name, not based on whether he/she exists.
#
# CIDR-ADDRESS specifies the set of hosts the record matches.
# It is made up of an IP address and a CIDR mask that is an integer
# (between 0 and 32 (IPv4) that specifies the number of significant bits in
# the mask. Alternatively, you can write an IP address and netmask in
# separate columns to specify the set of hosts.
#
# METHOD can be "trust", "reject", or "pam". Note that "pam" sends passwords
# in clear text.
#
# OPTION is the name of the PAM service. Default service name is "pgpool"
#
# Database and user names containing spaces, commas, quotes and other special
# characters must be quoted. Quoting one of the keywords "all" or "sameuser"
# makes the name lose its special character, and just match a database or
# username with that name.
#
# This file is read on pgpool startup. If you edit the file on a running
# system, you have to restart the pgpool for the changes to take effect.

# Put your actual configuration here
# ----------------------------------
#
# If you want to allow non-local connections, you need to add more
# "host" records. In that case you will also need to make pgpool listen
# on a non-local interface via the listen_addresses configuration parameter.
#

# TYPE DATABASE USER CIDR-ADDRESS METHOD

# "local" is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust

#AFM 27jul2010
host all all 10.200.27.40/32 trust

/etc/pgpool2/pgpool.conf

Nesses laboratórios não usamos

enable_query_cache = true

para não mascarar desempenho.

#
# pgpool-II configuration file sample
# $Header: /cvsroot/pgpool/pgpool-II/pgpool.conf.sample,v 1.32 2010/01/31 02:22:24 t-ishii Exp $

# Host name or IP address to listen on: '*' for all, '' for no TCP/IP
# connections
#listen_addresses = 'localhost'
#AFM 27jul2010 = '*'

# Port number for pgpool
port = 5433

# Port number for pgpool communication manager
pcp_port = 9898

# Unix domain socket path. (The Debian package defaults to
# /var/run/postgresql.)
socket_dir = '/var/run/postgresql'

# Unix domain socket path for pgpool communication manager.
# (Debian package defaults to /var/run/postgresql)
pcp_socket_dir = '/var/run/postgresql'

# Unix domain socket path for the backend. Debian package defaults to /var/run/postgresql!
backend_socket_dir = '/var/run/postgresql'

# pgpool communication manager timeout. 0 means no timeout, but strongly not recommended!
pcp_timeout = 10

# number of pre-forked child process
num_init_children = 32

# Number of connection pools allowed for a child process
max_pool = 4

# If idle for this many seconds, child exits. 0 means no timeout.
child_life_time = 300

# If idle for this many seconds, connection to PostgreSQL closes.
# 0 means no timeout.
connection_life_time = 0

# If child_max_connections connections were received, child exits.
# 0 means no exit.
child_max_connections = 0

# If client_idle_limit is n (n > 0), the client is forced to be
# disconnected whenever after n seconds idle (even inside an explicit
# transactions!)
# 0 means no disconnect.
#AFM 10ago2010 from 0 to 60
client_idle_limit = 60

# Maximum time in seconds to complete client authentication.
# 0 means no timeout.
authentication_timeout = 60

# Logging directory
logdir = '/var/log/postgresql'

# pid file name
pid_file_name = '/var/run/postgresql/pgpool.pid'

# Replication mode
#AFM 27jul2010
replication_mode = true

# When set to true, pgpool-II waits for the Master DB for all
# queries to be processed before moving on to the next backend.
# This option eliminates the risk of deadlocks, but the performance
# may degrade due to the lack of a parallelism. Default value is true.
#AFM 09ago2010 saiu do fonte 2.3.x, arquivo pool_process_query linha 3344 depreciou opcao
#replication_strict = true

# Set this to nonzero (in milliseconds) to detect this situation and
# resolve the deadlock by aborting current session.
#AFM 09ago2010 saiu do fonte 2.3.x, arquivo pool_process_query linha 3344 depreciou opcao
#replication_timeout = 5000

# Load balancing mode, i.e., all SELECTs are load balanced.
# This is ignored if replication_mode is false.
#AFM 27jul2010
load_balance_mode = true

# if there's a data mismatch between master and secondary
# start degeneration to stop replication mode
#AFM 27jul2010
replication_stop_on_mismatch = true

# If true, replicate SELECT statement when load balancing is disabled.
# If false, it is only sent to the master node.
#AFM 27jul2010
replicate_select = true

# Semicolon separated list of queries to be issued at the end of a
# session
reset_query_list = 'ABORT; DISCARD ALL'
# for 8.2 or older this should be as follows.
#reset_query_list = 'ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT'

# If true print timestamp on each log line.
print_timestamp = true

# If true, operate in master/slave mode.
master_slave_mode = false

# If true, cache connection pool.
connection_cache = true

# Health check timeout. 0 means no timeout.
#health_check_timeout = 20
#AFM 27jul2010
health_check_timeout = 10

# Health check period. 0 means no health check.
#health_check_period = 0
#AFM 27jul2010
health_check_period = 2

# Health check user
#health_check_user = 'nobody'
#AFM 27jul2010
health_check_user = 'andremachado'

# Execute command by failover.
# special values: %d = node id
# %h = host name
# %p = port number
# %D = database cluster path
# %m = new master node id
# %M = old master node id
# %% = '%' character
#
#failover_command = ''
#AFM 27jul2010
failover_command = 'echo $(date), host:%h, new master id:%m, old master id:%M port number:%p >> /tmp/failover.log'

# Execute command by failback.
# special values: %d = node id
# %h = host name
# %p = port number
# %D = database cluster path
# %m = new master node id
# %M = old master node id
# %% = '%' character
#
#failback_command = ''
#AFM 27jul2010
failback_command = 'echo $(date), host:%h, new master id:%m, old master id:%M, port number:%p >> /tmp/failback.log'

# If true, trigger fail over when writing to the backend communication
# socket fails. This is the same behavior of pgpool-II 2.2.x or
# earlier. If set to false, pgpool will report an error and disconnect
# the session.
fail_over_on_backend_error = true

# If true, automatically locks a table with INSERT statements to keep
# SERIAL data consistency. If the data does not have SERIAL data
# type, no lock will be issued. An /*INSERT LOCK*/ comment has the
# same effect. A /NO INSERT LOCK*/ comment disables the effect.
insert_lock = true

# If true, ignore leading white spaces of each query while pgpool judges
# whether the query is a SELECT so that it can be load balanced. This
# is useful for certain APIs such as DBI/DBD which is known to adding an
# extra leading white space.
ignore_leading_white_space = true

# If true, print all statements to the log. Like the log_statement option
# to PostgreSQL, this allows for observing queries without engaging in full
# debugging.
#AFM 28jul2010
log_statement = false

# If true, print all statements to the log. Similar to log_statement except
# that prints DB node id and backend process id info.
#AFM 28jul2010
log_per_node_statement = false

# If true, incoming connections will be printed to the log.
log_connections = false

# If true, hostname will be shown in ps status. Also shown in
# connection log if log_connections = true.
# Be warned that this feature will add overhead to look up hostname.
#AFM 28jul2010
log_hostname = false

# if non 0, run in parallel query mode
parallel_mode = false

# if non 0, use query cache
#AFM 10ago2010 problems with replication mode if enabled
enable_query_cache = false

#set pgpool2 hostname
pgpool2_hostname = ''

# system DB info
system_db_hostname = 'localhost'
system_db_port = 5432
system_db_dbname = 'pgpool'
system_db_schema = 'pgpool_catalog'
system_db_user = 'pgpool'
system_db_password = ''

#AFM 28jul2010
# backend_hostname, backend_port, backend_weight
# here are examples
backend_hostname0 = 'debian240153'
backend_port0 = 5432
backend_weight0 = 1
#backend_data_directory0 = '/data'
backend_hostname1 = 'debian240154'
backend_port1 = 5432
backend_weight1 = 1
#backend_data_directory1 = '/data1'

# - HBA -

# If true, use pool_hba.conf for client authentication. In pgpool-II
# 1.1, the default value is false. The default value will be true in
# 1.2.
#enable_pool_hba = false
#AFM 27jul2010
enable_pool_hba = true

# - online recovery -
# online recovery user
recovery_user = 'nobody'

# online recovery password
recovery_password = ''

# execute a command in first stage.
recovery_1st_stage_command = ''

# execute a command in second stage.
recovery_2nd_stage_command = ''

# maximum time in seconds to wait for the recovering node's postmaster
# start-up. 0 means no wait.
# this is also used as a timer waiting for clients disconnected before
# starting 2nd stage
recovery_timeout = 90

# If client_idle_limit_in_recovery is n (n > 0), the client is forced
# to be disconnected whenever after n seconds idle (even inside an
# explicit transactions!) 0 means no disconnect. This parameter only
# takes effect in recovery 2nd stage.
client_idle_limit_in_recovery = 0

# Specify table name to lock. This is used when rewriting lo_creat
# command in replication mode. The table must exist and has writable
# permission to public. If the table name is '', no rewriting occurs.
lobj_lock_table = ''

# If true, enable SSL support for both frontend and backend connections.
# note that you must also set ssl_key and ssl_cert for SSL to work in
# the frontend connections.
ssl = false
# path to the SSL private key file
#ssl_key = './server.key'
# path to the SSL public certificate file
#ssl_cert = './server.cert'

# If either ssl_ca_cert or ssl_ca_cert_dir is set, then certificate
# verification will be performed to establish the authenticity of the
# certificate. If neither is set to a nonempty string then no such
# verification takes place. ssl_ca_cert should be a path to a single
# PEM format file containing CA root certificate(s), whereas ssl_ca_cert_dir
# should be a directory containing such files. These are analagous to the
# -CAfile and -CApath options to openssl verify(1), respectively.
#ssl_ca_cert = ''
#ssl_ca_cert_dir = ''

Configuração dos backends PostgreSQL

/etc/postgresql/8.3/main/pg_hba.conf backends

Trecho do arquivo. Outras configurações no mesmo preservadas. Configurações sem as restrições de segurança para ambientes de produção.

# DO NOT DISABLE!
# If you change this first entry you will need to make sure that the
# database
# super user can access the database using some other method.
# Noninteractive
# access to all databases is required during automatic maintenance
# (autovacuum, daily cronjob, replication, and similar tasks).
#
# Database administrative login by UNIX sockets
local all postgres ident sameuser

# TYPE DATABASE USER CIDR-ADDRESS METHOD

# "local" is for Unix domain socket connections only
#local all all ident sameuser
#AFM 27jul2010
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 md5
# IPv6 local connections:
host all all ::1/128 md5

#AFM 27jul2010
host all all 10.200.27.40/32 trust

/etc/postgresql/8.3/main/postgresql.conf backends

Trecho do arquivo. Outras configurações no mesmo preservadas. Configurações sem as restrições de segurança para ambientes de produção.

#------------------------------------------------------------------------------
# CONNECTIONS AND AUTHENTICATION
#------------------------------------------------------------------------------

# - Connection Settings -

#AFM 27jul2010
listen_addresses = '*'

#listen_addresses = 'localhost' # what IP address(es) to listen on;
# comma-separated list of addresses;
# defaults to 'localhost', '*' = all
# (change requires restart)
port = 5432 # (change requires restart)

Teste da replicação

andremachado@debian:~$ createdb -p 5433 -h localhost bench_replication
andremachado@debian:~$ /usr/lib/postgresql/8.3/bin/pgbench -i -p 5433 bench_replication
andremachado@debian:~$ /usr/lib/postgresql/8.3/bin/pgbench -t 1000 -h localhost -p 5433 -c 8 bench_replication
andremachado@debian:~$ /usr/lib/postgresql/8.3/bin/pgbench -t 1000 -h localhost -p 5433 -c 8 -S bench_replication
andremachado@debian:~$ /usr/lib/postgresql/8.3/bin/pgbench -t 1000 -h localhost -p 5433 -c 4 bench_replication
andremachado@debian:~$ /usr/lib/postgresql/8.3/bin/pgbench -t 10000 -h localhost -p 5433 -c 2 bench_replication
andremachado@debian:~$ /usr/lib/postgresql/8.3/bin/pgbench -t 10000 -h localhost -p 5433 -c 4 bench_replication
andremachado@debian:~$ /usr/lib/postgresql/8.3/bin/pgbench -t 10000 -h localhost -p 5433 -c 8 bench_replication
andremachado@debian:~$ dropdb -p 5433 -h localhost bench_replication

Exemplos de pcp commands para verificar, excluir e inserir backends no pool

Para maiores informações consultar "pcp commands" na página: http://pgpool.projects.postgresql.org/pgpool-II/doc/pgpool-en.html

debian.pae.serpro:~# pcp_node_count 10 localhost 9898 postgres postgres
2
debian.pae.serpro:~# pcp_node_info 10 localhost 9898 postgres postgres 0
debian240153 5432 2 715827882.333333
debian.pae.serpro:~# pcp_node_info 10 localhost 9898 postgres postgres 1
debian240154 5432 2 715827882.333333