Arquivo da categoria: Banco de dados

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…



Uma pequena introdução sobre Buffer Cache!

O nível mais baixo de software na arquitetura do banco de dados é chamado gerenciador de espaço de disco, ele gerencia o espaço em disco. Asbtraindo, o gerenciador de espaço de disco suporta o conceito de página como unidade de dados, e prove comandos para alocar ou desalocar uma página quando é lida ou escrita. O tamanho de uma página é escolhido para ser o mesmo tamanho de um bloco, e as páginas são gravadas como blocos de maneira que uma leitura ou escrita de uma página é feita em uma operação de I/O de disco.

A grande maioria das vezes é útil alocar páginas em sequencias de blocos, dados que são acessados sequencialmente. Essa caracteristica e muito explorada como vantagens de um acesso sequencial nos blocos do disco. O gerenciador de espaço de disco esconde os detalhes mais baixos do hardware e possivelmente do sistema operacional e possibilita as aplicações de alto nivel pensar como um dado uma colecao de paginas.

Mapeando os blocos vazios

O banco de dados cresce , registros sao inseridos e deletados ao longo do tempo. O gerenciador de espaço de disco gerencia quais blocos estão em uso, e quais páginas estão em quais blocos. Inicialmente todos os blocos sao alocados sequencialmente no disco, com alocações e desalocações são criados buracos no disco.

Uma maneira de gerenciar os blocos e manter uma lista de blocos livres. Quando os blocos sao desalocados eles sao adicionados na lista de blocos livres para uso futuro. Um ponteiro para o primeiro bloco da lista de blocos livres e armazenado em uma localidade conhecida do disco.
Uma segunda maneira e manter um mapa de bits. um bit para cada bloco de disco indicando quais os bloco estao em uso e quais nao estao.

Buffer mananger

Para entender o papel do gerenciador de buffer, considere o seguinte exemplo: Suponha que um banco de dados contém 1.000.00 de paginas, mas somente 1.000 paginas da memoria principal está disponivel para cache dos dados. Considere uma query que requer um scan em todo um arquivo. Como ele nao pode ser deslocado para a memoria principal de uma so vez, o SGBD deve trazer as páginas dentro da memoria principal a medida que elas sao necessitadas, e nesse processo, decide quais páginas existentes na memoria principal irá sair para as novas páginas que foram solicitadas entrarem. A politica usada para decidir qual página irá sair da memoria principal e chamado de politica de substituição.
O gerenciador de buffer é uma camada de software que é responsável por trazer páginas do disco para a memória principal quando necessário. O gerenciador de buffer gerencia a memoria principal disponivel particionando ela em coleções de páginas, coletivamente chamadas de buffer pool. As páginas da memória principal que fazem parte do buffer pool sao chamados de frames, é mais fácil imagina-las como slots que contém as páginas,que usualmente residem no disco.
As aplicações de alto nivel sao escritas sem se preocupar se as páginas estão ou não em memória, elas perguntam ao gerenciador de buffer pela página, e ele se encarrega do resto, se a página nao está no buffer pool o gerenciador solicita a página e a coloca no buffer pool.
Obiviamente as aplicações de alto nível que fazem a requisição das páginas devem descartar a página quando nao mais necessário, informando o gerenciador de buffer, para que ela possa ser reutilizada. Também devem-ser informada ao gerenciador de buffer se a página requisitada foi alterada, entao o gerenciador propagara as mudanças copiando a página para os discos

———————————————–
|||||||||||||X|X|X|X||||||||||||||||||||||||X| | | páginas livres
———————————————–
||||||||||||||||||||||X|X|X|X|X|X|X|||||||| |X| |X| páginas ocupadas
———————————————–
||||X|X|X|X|X|X|X|X|||||||||||||||||||||||||||
_______________________________________________

Se uma página requisitada nao se encontra no buffer pool
e o buffer pool esta cheio, o buffer deve executar a politica
de realocação de paginas para serem realocadas.

|
Banco de dados

O gerenciador de buffer mantem duas varivaeis para cada frame no buffer pool: pin_count e dirty
pin count: número de vezes que uma página é requisitada concorrentemente.
Dirty indica se a página sofreu modificações desde que ela foi trazida do disco para o buffer pool.
Inicialmente o pin_count para todos os frames é 0 e o dirt bit está off. Se a página nao esta no pool o gerenciador do buffer age do seguinte modo:

Escolhe um frame para ser substituido, usando a a politica de substituição, e incrementa o pin_count
Se o dirty bit do frame a ser substituido estiver on, escrever a página no disco.(Substituir a página que esta no disco pela página
que esta no buffer)
Ler a página requisitaca dentro do buffer pool no lugar da outra.
Retonanar o endereço do frame que contém a página requisitada.

Aumentar o pin_count é chamado de pinning. Quando uma determinada página do buffer é solicitada e depois ela e devolvida ao buffer o pin_count do frame e decrementado. Isso é chamado unpining. Se a página solicitada e alterada, quando a página e devolvida ao buffer ocorre o unpining e o dirty bit e setado para on. O gerenciados do buffer nao irá colocar uma página no disco em lugar de outro no buffer até que o pin_count seja != 0, ou seja ate que todos as requisições de determinada página tenham devolvidos.

Se uma determinada página não se encontra no buffer pool,e se não existem frames livros no buffer pool, um frame com pin_count =0 é escolhido para substituição, segundo a política de realocação do gerenciamento de buffer.Quando uma página e eventulmente escolhida para set substituida, e se o seu dirt bit não esta setado, isso significa que a página não foi modificada desde que foi trazida do disco para a memória principal. Entao nao há a necessidade de escrever a página novamente no disco. Se o dirty bit estiver setado entao e necessário copia-lo ao disco novamente.
Se nao existir nenhuma pagina no buffer pool com pin_count =0 e a pagina requisitada nao estiver no pool, o gerenciador do buffer pool ira esperar ate que uma página e desalocada.Na pratica a transação é abortada. Entao as paginas requisitadas tem que ser desalocadas o mais rápido possível

Politica de substituicao do gerenciador de buffer

A politica usada para escolher uma página para ser substituida pode afetar o tempo de um banco de dados consideravelmente. Algumas alternativas de politicas podem existir, e cada uma cabe em uma situação diferente.
A policia mais conhecida e a LRU (lest recently used). Isso pode ser implementada no buffer mananger usando uma fila de ponteiros apontando para frames com pin_count 0.Um frame é adicionado ao final da fila quando ele se torna candidato para ser substituido.(quando o pin_count vai a 0). A página escolhida para ser substituida esta na cabeça da fila.
Outra variante chamada clock.

Gerenciador de buffer X Sistema operacional

Obiviamente existem similiaridades entre memoria virtual nos SO e o gerenciador de buffer em SGBDs. Nos dois casos o objetivo e prover acesso a mais dados que cabem na memoria, e a ideia basica e trazer as paginas de disco para a memoria principal quando solicitado.Porque o banco de dados nao utiliza o sistema de memoria virtual do SO? O SGBD pode prever a ordem em que as paginas vao ser acessadas, definidos por padroes melhor do que o gerenciamento de memoria virtual
do SO.SGBD necessita de mais controle sobre as paginas do que o Proprio SO.
O SGBD pode as vezes prever baseado em padrões, quais páginas futuras vão ser requisitadas, podendo usar uma estrategia chamada como prefetching. o gerenciador de buffer pode antecipar as proximas paginas e coloca-las no buffer antes de serem requisitadas. Isso tem dois beneficios:
As paginas disponiveis no buffer pool quando requisitadas
Ler blocos continuos de paginas e muito mais rapido do que ler a mesma pagina em tempos diferentes.