A implementação de tal cenário está descrita abaixo. Vale lembrar que os pré-requisitos apresentados no artigo anterior são utilizados aqui.
No servidor principal, editamos o arquivo /bd/primario/postgresql.conf:
listen_addresses = '*' wal_level = hot_standby max_wal_senders = 1 wal_keep_segments = 20
O parâmetro listen_addresses permite que o servidor secundário se conecte ao servidor principal para receber os logs de transação. O parâmetro wal_level indica o nível de log de transação armazenado no servidor principal; minimal (padrão) não permite que este tipo de replicação seja realizada. O parâmetro max_wal_senders indica o número máximo de servidores secundários permitidos. O parâmetro wal_keep_segments só é necessário se (i) for realizar a cópia dos arquivos com o servidor principal em atividade e (ii) se houverem paradas programadas do servidor secundário; este valor deve ser maior do que o número de arquivos de log de transação gerados durante a cópia dos arquivos. Neste caso, 20 é igual a 320 MB (20 * 16 MB).
A modificação desses parâmetros exige que o PostgreSQL do servidor principal seja reiniciado. Assim se a sua janela de manutenção não é flexível, programe-se. A aplicação dessas modificações não implica ter que iniciar a replicação imediatamente.
postgres@principal:~$ pg_ctl restart -D /bd/primario waiting for server to shut down.... done server stopped server starting
No servidor principal, crie uma role (usuário) para replicar os dados. O PostgreSQL exige que o usuário que realiza a replicação seja um super-usuário e possa se conectar ao servidor primário.
postgres@principal:~$ psql psql (9.0.1) Type "help" for help. postgres=# CREATE ROLE usuario SUPERUSER LOGIN; CREATE ROLE postgres=# \q
Dependendo da sua política de segurança, você pode precisar definir uma senha para este usuário. Neste caso, a senha deve ser informada no arquivo de senhas (~postgres/.pgpass ou %APPDATA%\postgresql\pgpass.conf no Windows) ou na string de conexão no arquivo /bd/secundario/recovery.conf.
postgres@principal:~$ psql psql (9.0.1) Type "help" for help. postgres=# \password usuario Enter new password: Enter it again: postgres=# \q
No servidor principal, edite o arquivo /bd/primario/pg_hba.conf. O método de autenticação vai depender da sua política de segurança. Se você decidiu colocar senha para o usuário que realiza a replicação, utilize o método de autenticação md5; caso contrário, utilize o método de autenticação trust.
host replication usuario 10.1.1.2/32 md5
A adição de uma nova regra de autenticação, exige a recarga das regras de autenticação.
postgres@principal:~$ pg_ctl reload -D /bd/primario server signaled
No servidor secundário, edite o arquivo /bd/secundario/postgresql.conf:
hot_standby = on
O parâmetro hot_standby indica se o servidor secundário aceita conexões.
No servidor secundário, crie o arquivo /bd/secundario/recovery.conf. Este arquivo conterá informações sobre a aplicação das modificações realizadas no servidor principal e transmitidas para o servidor secundário.
standby_mode = 'on' primary_conninfo = 'host=10.1.1.1 port=5432 user=usuario password=minhasenha' trigger_file = '/bd/secundario/failover.trg'
O parâmetro standby_mode especifica se o servidor PostgreSQL é um servidor secundário (standby). O parâmetro primary_conninfo especifica como se conectar ao servidor principal. A senha (especificado em password) pode ser omitida ali e especificada no arquivo de senhas (~postgres/.pgpass ou %APPDATA%\postgresql\pgpass.conf no Windows). Se o parâmetro trigger_file for utilizado, indica que a presença do arquivo citado (/bd/secundario/failover.trg), termina a recuperação, ou seja, o servidor passa a ser um servidor principal (que aceita quaisquer tipos de comandos; não somente aqueles comandos somente leitura).
No servidor principal, teremos que realizar a cópia física dos arquivos para o servidor secundário. Há duas maneiras de realizar esta cópia dependendo da disponibilidade do servidor principal:
- com o servidor principal parado;
- com o servidor principal em atividade.
postgres@principal:~$ pg_ctl stop -D /bd/primario waiting for server to shut down.... done server stopped postgres@principal:~$ rsync -av --exclude postgresql.conf \ --exclude pg_hba.conf --exclude pg_xlog/* --exclude pg_log/* \ /bd/primario/ postgres@10.1.1.2:/bd/secundario postgres@principal:~$ pg_ctl start -D /bd/primario server starting
Caso o servidor principal não possa parar, podemos fazer todo processo online. Neste caso precisamos executar os seguintes comandos no servidor principal:
postgres@principal:~$ psql psql (9.0.1) Type "help" for help. postgres=# select pg_start_backup('replicacao', true); pg_start_backup ----------------- 0/5044CB4 (1 row) postgres=# \q postgres@principal:~$ rsync -av --exclude postmaster.pid \ --exclude postgresql.conf --exclude pg_hba.conf \ --exclude backup_label --exclude pg_xlog/* --exclude pg_log/* \ /bd/primario/ postgres@10.1.1.2:/bd/secundario postgres@principal:~$ psql psql (9.0.1) Type "help" for help. postgres=# select pg_stop_backup(); NOTICE: WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup pg_stop_backup ---------------- 0/90D7950 (1 row) postgres=# \q
A primeira consulta (select pg_start_backup()) prepara o servidor para iniciar a cópia dos arquivos. O próximo passo é copiar os arquivos (utilizamos o rsync mas pode ser qualquer outro aplicativo) e, neste caso, temos que excluir alguns arquivos (postmaster.pid, postgresql.conf, pg_hba.conf, backup_label, pg_xlog/* e pg_log/*). Indicamos que a cópia já foi concluída executando a função (pg_stop_backup()). Vale lembrar que o parâmetro wal_keep_segments no servidor principal deve ser maior do que o número de arquivos de log de transação gerados durante a cópia. Isto porque o servidor secundário precisará destes arquivos (eles não podem ser reciclados) para "acompanhar" o servidor principal. Caso o parâmetro wal_keep_segments não seja suficiente, (i) você terá que aumentar o valor e realizar todo este passo novamente ou (ii) caso você esteja arquivando os arquivos de log de transação basta copiá-los para o diretório pg_xlog do servidor secundário.
Neste momento você pode iniciar o servidor secundário. Não se esqueça de criar os arquivos postgresql.conf e pg_hba.conf no servidor secundário.
postgres@secundario:~$ pg_ctl start -D /bd/secundario server starting
Caso os logs estejam habilitados (logging_collector = on) no servidor secundário, as seguintes mensagens indicam que a replicação está acontecendo com sucesso:
LOG: database system was interrupted; last known up at 2010-11-14 14:08:19 BRT LOG: entering standby mode LOG: redo starts at 0/5044CB4 LOG: restartpoint starting: xlog LOG: consistent recovery state reached at 0/A000000 LOG: database system is ready to accept read only connections LOG: streaming replication successfully connected to primary
Neste momento, espera-se que o servidor secundário esteja "acompanhando" o servidor principal mas sempre em um estado consistente. Assim, a mesma consulta em ambos servidores podem retornar resultados diferentes (lembre-se que a replicação é assíncrona).
Se você tiver perguntas, as listas de discussão pgbr-geral (português) e pgsql-general (inglês) são bons lugares para perguntar.