Arquivo da categoria: Linux

HA em Postgresql = Warm Stand By + HeartBeat + HAPM

Prefácio hehehe

Ja faz um bom tempo que eu gostaria de postar novamente, ando muito ocupado não sei se vocês sabem, mas estou no SERPRO em Porto Alegre agora envolvido não mais com o desenvolvimento em si do EXPRESSO  mas com a  a PRODUÇÃO!! Maravilha tudo o que eu queria….

AAAAA como é bom o cheiro dos servidores, aquele lindo terminal e finalmente Postgresql novamente …. O bom filho a casa retorna! Finalmente retornei com postgresql , não com a mesma exclusividade mas já é uma ótima!!

Mandando o SALVE!!

Galera gostaria de mandar um salve pros amigos que reencontrei no PGCON2009 e para os novas amizades que foram conquistadas , depois posto sobre o PGCON!!

Um salve pro meu brother Euler… esse já é irmão!!!

Um salve pro Minerin “Cara de coveiro”…

Um salve pro Léo Lindo e para a Cris….

Um salve pro Jovem “J”

Um salve pro Telles

Um salve pro Zé do Cleyssom de BSB (Agora convertido em Postgresql 😛 )

Um salve pro Diogo Biazus

Um salve pro pequeno inseto (Ele sabe quem é)

Um salve pro Roberto Mello (Cara 10 ….. PRAZER do Ca!@#$$# conhecer esse cabra)

Um salve pro Francisco , (Outro cara 10 …. que conheci tb em mais um evento)

Um salve pro GUTO de BSB….

Um salve pro “Rolon Boy” (Esse tb sabe quem é hehhe)

Um salve pro DUTRA.

Um salve pra Marisa (Valeu Marisaaaaaaaa……….. )

Um salve pro …. pra……

Um salve pro  Galera do MEC ( O Rodrigão e o Marcelo)

Um salve pros brothers da CELEPAR( esqueci o nome foi mal)

Um salve pro Emanuel “EL Aprendiz” da Argentina !

Um salve pra geral que prestigiou o evento e a minha palestra!!

2009-09-14-153739

Voltando ao Post….

Vejo muita gente comentando sobre Replicação , alta disponibilidade, balanceamento de carga. Em vários eventos de SL são debatidos esses temas e como está na semana do PGCON 3 edição , acho que seria uma boa soltar um post de interesse de muita gente, pois é galera ai vai …. Vamos ganhar um dinheirinho com consultoria ai….

Cenário

Não irei entrar em conceitos como PITR, WAL , pá e bola…. Então são pré-requisitos para um bom entendimento!! Não que não consiga implementar sem esses conceitos mas véio de boa…. Estuda!! 😛

Um servidor primário e um servidor secundário.

O  servidor  primário recebe as requisições  feliz da vida  e tranquilo , o servidor secundário fica em Stand-By em modo seca pimenteiro = on hehehe , pois ele não pode ser não pode ser acessado. Em um determinado momento meu servidor primário deixa de prover o serviço e…..

Meu servidor em Stand-by cheio de moral e doido para mostrar serviço, assume a posição  do servidor primário de maneira  “transparente” ao usuário… pois é … nem tudo é perfeito e o afobado jovem em stand by pode deixar um dado ou outro de lado 😛

Nessa brincadeira ai  já traçamos alguns conceitos importantes : Alta-disponibilidade , Replicação Síncrona e uma característica importante na implementação do stand-by (Não pode ser acessado nem para consulta)

HA-PG

Para alcançar o objetivo iremos utilizar  como coadjuvantes os softwares HAPM e o HeartBeat que nos possibilitaram a Alta-disponibilidade do serviço.

Configurando o Ambiente!

Anota ai jovem…

Postgresql-8.3
postgresql-contrib-8.3
heartbeat-2
nfs-kernel-server
hapm

Vamos utilizar o Debian Lenny como exemplo e instalar os pacotes acima nas duas máquinas:

apt-get install postgresql-8.3 heartbeat-2 nfs-kernel-server hapm  postgresql-8.3-contrib

Uma vez instalados os pacotes nos dois servidores criaremos um local para arquivar os segmentos WAL. É altamente recomentados gravar os segmentos WAL remotamente do servidor primário, pois se o servidor primário cair , não teremos acesso aos segmentos WAL, o que comprometeria a replicação e consequentemente a disponibilidade do sistema.

Os arquivos devem ter permissões de escrita e leitura para ambos os servidores. No exemplo que estamos demonstrando a técnica, criaremos um compartilhamento NFS no servidor Stand By e o servidor primário exportará os arquivos WAL(cansei de colocar o Wal em negrito) para este determinado local. Tenha a certeza que o diretório pertença ao usuário postgres. Entendeu??

Criação do diretório na máquina slave  para arquivamento  no qual o usuário PostgreSQL pode escrever e ler:

Como usuário root:

mkdir /psql-archive

chown postgres.postgres /pgsql-archive

echo “/psql-archive IP_MASTER (rw,sync,no_subtree_check)” >> /etc/exports

exportfs -a

su postgres -c “touch /psql-archive/mounted”


O que os comandos acima fazem??

Criamos um diretório chamado /psql-archive cujo o dono é o safadinho do usuário postgres e permitimos que a máquina PRIMÁRIA possa montar o diretório remotamente podendo escrever e ler nele… já ia esquecer ,também criamos de ante-mão um arquivo lá no diretório chamado mounted… (aí está a mágica!!)

Agora na máquina primária

mkdir /psql-archive

chown postgres.postgres /psql-archive

mount IP_SLAVE:/psql-archive /psql-archive


O que os comandos acima fazem??

Agora na máquina primária criamos um diretório chamado /psql-archive cujo o dono  é o postgres montamos remotamente o diretório da máquina slave psql-archive no /psql-archive do primário.


Ainda na máquina primária iremos ativar o recurso de WALs :

no arquivo /etc/postgresql/8.3/main/postgresql.conf alterar as seguintes linhas:

archive_mode = on

archive_command = “test -f /psql_archive/mounted && test ! -f /psql_archive/%f && rsync -a %p /psql_archive/%f”

Que lindo o archive_command!!! Fandásdigo como diria tiririca, confesso esse eu copiei  hehehhe mas eu sei o que ele faz 🙂

Vamos por partes!!!

arvhice command = (condicao 1) && (condicao 2)

Condição 1 = teste -f /psql/mounted

Lembra do comando touch /psql/mounted no servidor seca pimenteiro, ops .. escravo?? O que ele faz é verificar se o arquivo mounted existe, se ele existir significa que a partição remota está montada  🙂

Condição 2 = test ! -f /psql_archive/%f && rsync -a %p /psql_archive/%f

Verifica se já existe o arquivo Wall no secundário , se não existir ele copia o Wal file para lá 🙂

o “&&”,  elementar meu caro as duas condições tem que serem válidas ou seja

(particao tem que estar montada ) e (nao deve existir o arquivo no diretorio la no escravo)

Reiniciar o serviço do PostgreSQL

/etc/init.d/Postgresql-8.3 restart

A Partir deste momento meu caro parabéns, já está gerando arquivos Wals e o mais legal, lá no diretório do escravo… nossa imagina o cabra ter que suportar ter que ser secundário e neguin escrevendo no diretório dele hehehh.

Prova dos 9!

Vamos lá…

Agora devemos fazer o backup básico do diretório $PGDATA, sem a necessidade de parar o banco de dados , isso no servidor primário logicamente.

psql -U postgres

Bem vindo ao psql 8.3.3, o terminal iterativo do PostgreSQL.

Digite: \copyright para mostrar termos de distribuição

\h para ajuda com comandos SQL

\? para ajuda com comandos do psql

\g ou terminar com ponto-e-vírgula para executar a consulta

\q para sair


postgres=# select pg_start_backup(‘meu_backup’);

pg_start_backup

2/CE005F40

(1 registro)

postgres=# \q

# su – postgres

# cd /var/lib/Postgresql/8.3/

$ tar -czf /psql-archive/base_backup.tar.gz *

tar: Removendo `/’ inicial dos nomes dos membros

tar: main/pg_xlog/0000000100000002000000CF: arquivo alterado enquanto estava sendo lido

…..

…..

…..

Estamos gerando um backup a fisico do diretório de dados e colocando no diretório compartilhado /psql-archive . Uma vez terminado o backup, conectar no banco de dados e efetuar o seguinte comando:

psql -U postgres -h localhost

Bem vindo ao psql 8.3.3, o terminal iterativo do Postgresql.


Digite: \copyright para mostrar termos de distribuição

\h para ajuda com comandos SQL

\? para ajuda com comandos do psql

\g ou terminar com ponto-e-vírgula para executar a consulta

\q para sair


conexão SSL (cifra: DHE-RSA-AES256-SHA, bits: 256)

postgres=# select pg_stop_backup();

pg_stop_backup

—————-

2/D000BC0C

(1 registro)


postgres=# \q


Na máquina secundária novamente

mv /var/lib/Postgresql/8.3/main /var/lib/Postgresql/8.3/main.old

Estamos renomeando o $PGDATA da máquina secundária para $PGDATA.old

mv /psql-archive/base_backup.tar.gz /var/lib/Postgresql/8.3

Copiando o backup do servidor primário para o diretório /var/lib/Postgresql;8.3

tar -xzvf /var/lib/Postgresql/8.3

Mandando bala descompactando o danado…

cd /var/lib/Postgresql/8.3/main/

Entrando no diretório $PGDATA novo do secundário…

rm -Rf ./pg_xlog/*

Removendo os arquivos do pg_xlog do primário…. Cansei…

Vamos vamos…. Vamos !!!!!

Criação do arquivo recovery.conf na máquina para o modo contínuo de recovery dentro do $PGDATA ( /var/lib/Postgresql/8.3/main/) com a seguinte linha:

restore_command = ‘/usr/lib/postgresql/8.3/bin/pg_standby -d -l -r 3 -s 60 -t /psql_archive/trigger.done /psql_archive %f %p %r 2>>/tmp/pg_standby.log’

Essa linha basicamente indica o Postgresql para continuar o recovery até encontrar um arquivo chamado /psql-archive/trigger.done, ou seja , quando o servidor primário cair, um arquivo trigger.done será criado e o procedimento da subida do servidor slave é iniciado.


Iniciando o servidor Stand by

#  /etc/init.d/Postgresql-8.3 start

* Starting Postgresql 8.3 database server

[ OK ]

# tail -f /tmp/pg_standby.log

Keep archive history : 000000000000000000000000 and later

running restore : OK

Trigger file : /psql-archive/trigger.done

Waiting for WAL file : 000000020000000200000088

WAL file path : /psql-archive/000000020000000200000088

Restoring to… : pg_xlog/RECOVERYXLOG

Sleep interval : 60 seconds

Max wait interval : 0 forever

Command for restore : ln -s -f “/psql-archive/000000020000000200000088” “pg_xlog/RECOVERYXLOG”

Keep archive history : 000000000000000000000000 and later

Que lindo Que lindo …. Vamos Vamos…

Criação do arquivo recovery.conf na máquina para o modo contínuo de recovery dentro do $PGDATA ( /var/lib/Postgresql/8.3/main/) com a seguinte linha:

restore_command = ‘pg_standby -d -l -r 3 -s 60 -t /psql_archive/trigger.done /psql_archive %f %p %r 2>>/tmp/pg_standby.log’

Essa linha basicamente indica o Postgresql para continuar o recovery até encontrar um arquivo chamado /psql-archive/trigger.done, ou seja , quando o servidor primário cair, um arquivo trigger.done será criado e o procedimento da subida do servidor slave é iniciado.


#psql -U postgres -h localhost

psql: FATAL: o sistema de banco de dados está iniciando ou seja esta em restore continuo.

????? Num intindi nada!!!???

O servidor está em restore constante!!!! Não temos como acessar o servidor (WARM Stand by Falei isso lá em cimaaa nocomeço do Post)

Gerando arquivos Wals para serem replicados a partir do host primário

Começaremos a gerar alguns arquivos Wals .

# psql -U postgres

Bem vindo ao psql 8.3.3, o terminal iterativo do Postgresql.


Digite: \copyright para mostrar termos de distribuição

\h para ajuda com comandos SQL

\? para ajuda com comandos do psql

\g ou terminar com ponto-e-vírgula para executar a consulta

\q para sair


postgres=# create table teste as select * from pg_class, pg_attribute;

SELECT

postgres=# create table teste1 as select * from pg_class, pg_attribute;

SELECT


postgres=#\q

Vários arquivos Wals foram gerados e gravados no diretório especificado no archive_command, configuração do servidor que no caso, mais uma vez pra não se perder  o tal /psql-archive que está montado na máquina primária .

# ls -l /psql-archive

total 738184

-rw——- 1 postgres postgres 16777216 2009-10-06 16:31 0000000100000002000000CE

-rw——- 1 postgres postgres 246 2009-10-06 16:35 0000000100000002000000CE.00005F40.backup

-rw——- 1 postgres postgres 16777216 2009-10-06 16:33 0000000100000002000000CF

-rw——- 1 postgres postgres 16777216 2009-10-06 16:35 0000000100000002000000D0

-rw——- 1 postgres postgres 16777216 2009-10-06 16:37 0000000100000002000000D1

-rw——- 1 postgres postgres 16777216 2009-10-06 16:39 0000000100000002000000D2

-rw——- 1 postgres postgres 16777216 2009-10-06 16:41 0000000100000002000000D3

-rw——- 1 postgres postgres 16777216 2009-10-06 16:43 0000000100000002000000D4

-rw——- 1 postgres postgres 16777216 2009-10-06 16:45 0000000100000002000000D5

-rw——- 1 postgres postgres 16777216 2009-10-06 16:47 0000000100000002000000D6

-rw——- 1 postgres postgres 16777216 2009-10-06 16:49 0000000100000002000000D7

-rw——- 1 postgres postgres 16777216 2009-10-06 16:51 0000000100000002000000D8

-rw——- 1 postgres postgres 16777216 2009-10-06 16:51 0000000100000002000000D9

-rw——- 1 postgres postgres 16777216 2009-10-06 16:51 0000000100000002000000DA

-rw——- 1 postgres postgres 16777216 2009-10-06 16:51 0000000100000002000000DB

-rw——- 1 postgres postgres 16777216 2009-10-06 16:51 0000000100000002000000DC

-rw——- 1 postgres postgres 16777216 2009-10-06 16:51 0000000100000002000000DD

-rw——- 1 postgres postgres 16777216 2009-10-06 16:51 0000000100000002000000DE

-rw——- 1 postgres postgres 16777216 2009-10-06 16:51 0000000100000002000000DF

-rw——- 1 postgres postgres 16777216 2009-10-06 16:51 0000000100000002000000E0

-rw——- 1 postgres postgres 16777216 2009-10-06 16:51 0000000100000002000000E1


Testando a replicação para a máquina em Stand By

Agora criaremos o arquivo /tmp/trigger.done.

touch /psql-archive/trigger.done

Neste momento, o servidor Stand By detectará que deve sair do modo recovery e levantar o serviço. Ou seja, quando o arquivo /psql-archive/trigger.done existir, o servidor em Stand By sai do modo recovery e passa a operar normalmente. Você pode logar no servidor Stand By e verificar as tabelas criadas.

To be continued…

Até agora implementamos o Warm Stand by… Sem alta disponibilidade…..  o próximo post mostro como garantir a disponibilidade de forma que o servidor escravo assuma o ip do outro servidor mantendo a disponibilidade do serviço…



Apache + Load Balance + Lenny

Por curiosidade, fui atrás de uma solução de balanceamento de carga entre servidores  apache. Aqui no trampo,  o  balanceamento de carga em cima dos servidores apache é feita através de hardware  …. eu queria ver como seria possível utilizando o próprio apache como proxy reverso, vi que era possível utilizando o mod_proxy do apache

Após dois dias, alguns   HOWTOS que não funcionam devido ao problema de balanceamento de sessões (sticksessions) e uma aula de boxe perdida, obtive a solução, BINGO!

Apache como Proxy Reverso

Segundo o Wiki …. “Proxy reverso é um servidor proxy que é fica na frente de outros servidores. Tipicamente proxy reverso  é usado na frente de servidores web. Todas as conexões vindo da internet endereçadas para um dos servidores web são roteadas  pelo proxy server… ”

Ou seja, toda e qualquer conexão passa pelo proxy server, que é o ponto de contato entre o cliente e os servidores.

Razões para utilizar um proxy reverso

  • Segurança: o proxy server provê uma camada adicional de segurança separando ou mascarando os tipos de servidores que estão atrás do proxy.
  • Encripitação/ SSL acceleration: Quando sites seguros são criados, a encriptação SSL as vezes não é realizada pelo servidor web e sim pelo proxy reverso que é equipado por um hardware de aceleração SSL.
  • Balanceamento de carga:  Proxy reverso pode distribuir a carga em vários servidores .
  • Caching: Um proxy reverso pode diminuir a carga dos servidores web promovendo cache, diminuindo consideravelmente o  número de requisições nos servidores web.
  • Compressão : O proxy  pode otimizar e comprimir o conteúdo aumentando assim a velocidade.

Cenário

basicClustered.preview

Cenário bem simples: Um proxy reverso na frente dos servidores apache. Toda e qualquer requisição é feita diretamente no proxy que realiza o balanceamento de carga.

Beleza… ele realiza o balanceamento de carga mas… meu site não é estático… tb faço uso de   seções e aí? ele é capaz de saber em qual apache está minha seção??

Calma jovem, a solução a seguir contempla esse tipo de dúvida!! No proxy será criado um coockie balanceado  que será roteado para o servidor web correto!  That's the point!!

Esse foi o grande lance da solução. todos os HowTo espalhados exigiam modificações tanto no proxy quanto nos apaches que estão em baixo e esta solução não... só a configuração no proxy.

Instalação:

Com os pacotes do apache e php já instalados devemos ativar o modúlos mod_proxy , mod_headers .
A maneira Debian de ser… Digite!

# a2enmod proxy

Module proxy  installed; run /etc/init.d/apache2 force-reload to enable.

# a2enmod header

Module headers installed; run /etc/init.d/apache2 force-reload to enable.

Configuração:

No virtual host do proxy adicione as seguintes configurações

———————————————————————————————————————

Header add Set-Cookie “MYCOOKIE=SOMEVALUE.%{BALANCER_WORKER_ROUTE}e; path=/;” env=BALANCER_ROUTE_CHANGED

ProxyPass / balancer://cluster/ lbmethod=byrequests stickysession=MYCOOKIE

<Proxy balancer://cluster>
BalancerMember http://192.168.1.24 route=www1
BalancerMember http://192.168.1.25  route=www2
</Proxy>

ProxyPassReverse / http://192.168.1.24/
ProxyPassReverse / http://192.168.1.25/

—————————————————————————————————————————–

lbmethod : método de balanceamento entre os servidores.

byrequests |bytraffic| bybusyness : o default é byrequest , vide documentação do  mod_proxy do apache.

stickysession=MYCOOKIE

nome do cookie balanceado:  O valor é geralmente setado como: JSESSIONID ou  PHPSESSIONID

BalancerMember: Cada host que compões os servidores web que serão balanceado

Testando…

Utilizando o browser acessamos o nosso proxy http://ip_do_proxy.  Agora para matar a curiosidade veja os cookies no browser mais precisamente a variavel MYCOOkIE nos cookies do proxy!

Tricks on BASH!

É aquela velha história, vivendo e aprendendo!!!!

Ontem em um dos meus estudos em busca da tão tardia LPI, me deparei com uma muito funcionalidade interessante( não sei se bem exclusiva do bash, confesso que nunca mechi Intensamente em outros shells (sh,ksh….) )
Bem… Todo mundo cansa de utilzar os recursos de history do bash usando as teclas para cima e para baixo para acessar os ultimos comandos digitados. O que ocorre que digitei uma determinada linha de comando e gostaria de executar novamente ,somente mudando alguma string.
Então utilizo a seta para cima , e com a seta <- -> vou navegando no comando até onde desejo modificar a string e depois mando um belo <ENTER>:

ex: psql -U postgres -h servidor1 bd_producao

Essa foi uma linha que eu havia digitado anteriormente e gostaria de utilizar o mesmo comando , modificando a string postgres por usuario1
então usaria a tecla para cima ,as teclas de <- até a palavra postgres e backspace para apagar a palavra e digitar usuario1

Beleza!!

é bem mais simples utilizar

^postgres^usuario1

Parece tolice mas economiza um tempo considerável!!!