Tribo de Jah Orai, Vigiai, A Babilônia Vai Cair

Eu vejo os brotos dessa nova geração
Crianças, garotos, ainda em formação
Eu vejo com apreensão, vivendo nestes tempos
Tempos de dissolução, rebentos sem discernimento

Há tanta mídia, tanta desinformação
Fazendo mais e mais, escravos da ilusão
Mas o dia vai chegar, mais cedo do que se crê
E nada será como está, todos irão se render, a brutal transformação

Não pense nunca que o mal triunfará
Nada, ninguém jamais irá mudar, os rumos da criação
Jah é o único, tesouro a se buscar
Desperte, liberte-se, entregue a Jah teu coração

Orai, vigiai, clamai em nome do Senhor
Só Ele pode nos guiar, só Ele vai nos conduzir
A Babilônia em breve vai se abalar
E vai tremer, vai tremer, tremer até cair

Vai, vai, vai, vai ruir, ruir
Vai tremer até cair
Vai, vai, vai, vai ruir, ruir
A Babilônia vai cair

Todo poder transitório ruirá por sua vez
Corroído em suas próprias entranhas de desmandos e, insensatez
Assim passará a Babilônia sob o manto sombrio
Da corrupção, da fome e da guerra
Consumida em múltiplas noites de insônia
Só os mansos e pacíficos herdarão o reino da terra
Soon Babylon shall fall down

Música show de bola!!! Jah rastafari!!

Começando com o Londiste…

Mais uma vez resolvi dedicar um tempinho e mexer com as ferramentas do SkyTools, o Londiste. Esse post já tem quase um ano , estava nos seus 80% mas por motivos maiores de falta de tempo, trampo …. e vcs sabem a “caixa é uma vidinha de surpresas”…

Aproveitando a proximidade do PGDAY ,um dia dedicado ao nosso querido Postgresql  (Estou realmente pensando em bolar alguma palestra com  PL/PROXY e Londiste aqui no PGDAY de Porto Alegre) , resolvi terminar de escrever sobre o londiste, e como promessa é dívida….

Primeiro foi o plproxy agora é a vez do londiste. Não esqueci não, vou postar algumas coisinhas que eu fiquei de postar do plproxy, inclusive testes de estress em cima dele, mas como a curiosidade falou mais alto,resolvi passar para o Londiste. A intenção é a seguinte:

Pegar o básico do PLPROXY, Londiste e PGBouncer (próximo post). Depois de um how to em cima de cada um deles montar um ambiente com os 3 e meter BALA!

As primeira impressões que eu tive do do londiste foram as seguintes:

Documentação:

Se a documentação do PLPROXY não era das melhores a do Londiste xiiiiiiiiiiii, lascou tudo, sinceramente uma negação, e vi os mesmos comentários dos gringos também Muito mal documentado mesmo!!!

Instalação:

A instalação foi um tanto penosa, perdi algumas horinhas mesmo batendo cabeça e pra não cometer novamente os erros eu documentei, ou pelo menos acho que documentei hehehe. Para quem não é perseverante, é desistência na certa!!!! E mais uma vez vi gringo reclamar!

Implementação:

Colocar o londiste pra rodar e ver suas bases de dados replicando é muito, mas muito simples mesmo. Chega a ser ridículo ( depois de passar pela instalação….), é estremamente simples e chega ser recompensador!!!!

Então que comece a temporada do Londiste!!!!

O que é replicação???

Bem, como esse post não é sobre replicação em si, e mais precisamente sobre o Londiste não vamos entrar em todo o mérito!!!

O objetivo de um mecanismo de replicação de dados é permitir a manutenção de de várias cópias idênticas de um mesmo dado em vários servidores de banco de dados (SGBD).

Para que serve a replicação???

Principais benefícios da replicação de dados são:

Redundância.
Possibilidade de um balanceamento de carga.
Tornar o sistema menos sensível as falhas.

Sugiro que você jovem de uma lidinha sobre replicação ok?? hehhe eu quero é postar sobre o londiste!!!!

É Pra que serve o Londiste??

O Londiste é uma ferramenta para replicação assíncrona, master-to-slaves. Assíncrona significa que: Quando o nó master receber uma transação, existe um tempo para essa transação ser replicada nos nós slaves. O contrário disso , a replicação síncrona, ocorre quando as transações ocorrem em todos os nós on-line.

E como eu poderia usar o Londiste??

Hum deixa eu ver…. Onde não fosse necessário o espelhamento dos dados em todos os nós ao mesmo tempo?? Isso depende muito do projeto em questão. As vezes tenho somente 2 servidores de banco de dados, um servidor MASTER que recebe todas as transações e um servidorzinho na senzala, SLAVE que fica lá jogado esperando por receber os dados, depois que o Master fez uso …. As vezes tenho um servidor master e vários servidores slaves….. Então necessitou de dados repetidos em vários servidores, REPLICAÇÂO. Se não possui como pré-requisito que os dados sejam replicados instataneamente ,ASSÍNCRONO.
Nunca se esquecer que eu tenho somente um MASTER e vários SLAVES. Tudo que acontece, o Master é quem manda… já viu escravo mandar no mestre??

AAAAA mas o Slony faz isso não????

Faz sim , slony faz até mais por permitir cascateamento entre os nós e slave promotion. Ou seja no slony você tem um nó MASTER e outros nós slaves, mas esses nós slaves podem ser Providers para outros nós, cascateando assim os servidores.


Mas se o Slony tem mais recursos por que eu utilizaria o Londiste??

O londiste é muito mais simples de configurar e gerenciar, muito mesmo!!!! Antes o projeto Skype utilizava o próprio Slony, depois começaram a utilizar o Londiste, que foi desenvolvido por eles mesmos.
Motivos!!!! Como já disse, facilidade de configurar e principalmente gerenciar.

Não tá acreditando né? Então toma!!!
Trecho de uma discursão sobre Slony X londiste
….
“I have not been running slony for quite a long time. I last used it at
Skype a few years ago before we moved to our own implementation –
Londiste/pgQ from SkyTools. The main reason was that our cluster got too
big to manage with slony. ”
….

Beleza então vamos começar a instalação!!!!

Como eu disse no início do post, o grande problema do Londiste, como todos to Skytools é a documentação. Eu estou utilizando o debian 4.0.

Depois de bater muito a cabeça acabei instalando alguns pacotes a mais:

apt-get install build-essential python-psycopg libevent-dev python-all-dev python-all python-support

Uma vez instalados esses pacotes, vamos baixar o código fonte:
http://pgfoundry.org/frs/download.php/1813/skytools-2.1.7.tar.gz

baixado o código fonte no meu diretório /usr/src:
tar -xzvf skytools-2.1.7.tar.gz

./configure –with-pgconfigdir=/usr/local/pgsql/bin
(No meu caso ok?? deve-se setar o diretório do seu pg_config)

make && make install

Se o bicho não reclamou de nada beleza!!! Se reclamou aí vamos ter que sambar um pouco….
Pelo o que eu me lembre esses foram os pacotes que eu instalei, eu instalarei do zero novamente pra fazer a prova dos 9 🙂

PS: O jovenzinho, ele sabe quem é…. vai falar, já tem o pacote no debian http://packages.debian.org/sid/skytools
Olha o garotinho aí né ??? mas não ta na versão stable ainda …. Detalhe: ele mantém o pacote 🙂

Criando o Ambiente!!!

Vamos fazer o seguinte: Iremos criar inicialmente 2 databases, um master e outro slave

create database mestre;
create database escravo;

Em cada database iremos criar 2 tabelas:
create table tabela1(id serial primary key,nome text);
create table tabela2(id serial primary key,nome text);

Um detalhe muito importante!!!!! Todas as tabelas devem ter chaves primárias ok??? Não se esqueça disso. Atenção nisso jovem!

O que vai acontecer: Nós iremos realizar algumas operações no banco de dados mestre e elas vão ser replicadas ao banco de dados escravo.

Criando o primeiro CLUSTER

Como eu disse a configuração do londiste é muito simples mesmo. Vamos lá:

Crie um arquivo chamado replicacao.conf com o seguinte conteudo:

[londiste]
job_name = replic

provider_db = dbname=mestre host=localhost user=postgres
subscriber_db = dbname=escravo host=localhost user=postgres

pgq_queue_name = londiste_replic

pidfile = /tmp/pid.%(job_name)s
logfile = /tmp/log.%(job_name)s

loop_delay = 1

connection_lifetime = 30

Crie um arquivo chamado ticker.ini com o seguinte conteúdo:

[pgqadm]

job_name = ticker

db = dbname=mestre user=postgres host=localhost

maint_delay_min = 1

loop_delay = 0.5

logfile = /tmp/log.%(job_name)s
pidfile = /tmp/pid.%(job_name)s

use_skylog = 0

connection_lifetime = 21

queue_refresh_period = 10

Instalando o Londiste no sevidor mestre

Devemos instalar toda a estrutura para o londiste rodar: A instalação deve ser feita tanto no servidor mestre como no servidor escravo. Essa estrutura consiste em instalar a linguagem plpgsql,plpython…

londiste.py replicacao.conf provider install

Detalhe: provider o nó que é origem da replicação!

Instalando o Londiste no servidor escravo

<Em cada um dos nós escravos devemos também instalar toda a estrutura necessária como descrito acima.

londiste.py replicacao.conf subscriber install

Detalhe: subscriber é o nó escravo!

Colocando o PGQ pra rodar…

O Daemon pgqadm deve rodar no servidor master , ele vai ser o cara responsável pelo mecanismo de transporte para implementar a replicação!

pgqadm.py -d ticker.ini ticker
para verificar se realmente esta rodando o processo vamos dar um ps aux | grep pgq

…..
root 28190 0.0 0.2 19248 4780 ? Ssl 14:20 0:00 /usr/bin/python /usr/local/bin/pgqadm.py -d ticker.ini ticker
….

Olha que bicho danado hehehehe!!
hummm… posso também dar um pgqadmin.py -d ticker.ini status , tenta aí jovem!

Então pra encher o saco e memorizar!!! rodar o daemon pgqadmin no master utilizando o parametro -d ( o -d e pra rodar como daemon) passando o arquivo de configuracao ticker.ini e a opcao ticker.

Se eu quizer parar o daemon: pgqadmin.py  -s ticker.ini
Curioso? lista o processo novamente!
Memorize os parâmetros e como exercício levante e suba umas 1000 vezes.

Colocando o daemon de replicação no ar!

Você precisa rodar o deamon de replicação em cada host, como no nosso caso o host provider e subscriber estão na mesma máquina vamos la!

londiste.py -d replicao.ini replay

ps aux | egrep “lond|pgq”

root 28568 0.0 0.2 11332 4860 ? Ss 14:59 0:00 /usr/bin/python /usr/local/bin/londiste.py -d replicacao.ini replay
root 28693 0.0 0.2 19244 4772 ? Ssl 15:05 0:00 /usr/bin/python /usr/local/bin/pgqadm.py -d ticker.ini ticker
root 28725 0.0 0.0 3020 816 pts/0 R+ 15:06 0:00 egrep lon|pgq

Exatamente os caras que eu estava esperando o pgqadm ( que é o cara que fica no master e) o londiste.py ( que é o cara que roda em cada escravo)

Escolhendo os objetos as serem replicados

Seguindo o nosso roteiro ja temos os deamons rodando no nó provider e nos nós subscribers. Devemos informar ao Londiste quais tabelas e sequences devemos replicar.

No nosso exemplo iremos replicar 2 tabelas: tabela1 e tabela2.

No nó de origem devemos executar o seguinte comando:

londiste.py   replicacao.conf  provider add  tabela1

londiste.py  replicacao.conf  provider add tabela2

Também temos que replicar as sequences criadas pelo campo serial!!!

londiste.py replicacao.conf provider add-seq tabela1_id_seq;

londiste.py replicacao.conf provider add-seq tabela2_id_seq;

Po mas nao apareceu mensagem nenhuma pra mim? Está tudo tão obscuro!!!

beleza  jovem mancebo…. faz o seguinte

londiste.py replicacao.conf provider tables

public.tabela2
public.tabela1

londiste.py replicacao.conf provider seqs

public.tabela2_id_seq
public.tabela1_id_seq


Detalhe na palavra provider!!!

Agora o mesmo procedimento nos nós de origem!!

londiste.py   replicacao.conf  subscriber add  tabela1

londiste.py  replicacao.conf  subscriber add tabela2

londiste.py replicacao.conf  subscriber add-seq tabela1_id_seq;

londiste.py replicacao.conf  subscriber  add-seq tabela2_id_seq;

Para dar aquela conferida básica….

londiste.py replicacao.conf  subscriber tables

public.tabela2
public.tabela1

londiste.py replicacao.conf subscriber seqs

public.tabela2_id_seq
public.tabela1_id_seq

Detalhe na palavra subscriber!!

Enfim Replicando……UFA!

Vamos testar agora se a replicação vai funfar ou não, o cabra le o artigo se irrita e quer logo ver a parada funcionar, pelo menos eu sou assim 😛

Suponha que seu psql esteja no seu PATH e vc esteja usando linux :). AAAAAAAAAAAAAAA beleza então insere na mão mesmo se preferir!! 🙂

for i in $(seq 1 10000) ; do psql -U postgres -h localhost -c “insert into tabela1 values(default,’joao$i’)” mestre ; done

Com isso inserimos 10000 registros na tabela1. Após  a inserção dos registros!!

Conecte-se no banco mestre e rode um count(*) na tabela1

Conecte-se no banco de dados escravo e rode um count(*) na tabela2

psql  -U postgres -h localhost -c “select count(*) from tabela1” mestre

psql  -U postgres -h localhost -c “select count(*) from tabela1” escravo

Consideração finais…

Fica pra amanhã estou realmente cansado…. Eu prometo que faço e não vai demorar quase um ano!
🙂

Tiesto feat. Julie Thompson – Do You Feel Me

As darkness comes you sleep alone
I watch the world I’ve always known
Turning the corners of your mind
And I look, focus on your smile

Oh the summer breeze
Somehow singing softly into you
Dadada dadada dadada
Hear me whispering
Always there, no matter what you do

I can’t stop falling when my heart comes calling
Do you feel me?
Warming you like rays of sunshine
Can’t stop falling when my heart comes calling
Do you feel me?
Warming you like rays of golden light

(Summer Breeze)
(Whispering)
(Summer Breeze)
(Whispering)

In shadows hide your deepest fears
If only you knew I was here
You’re safe and seldom need my daze
You have the need to be afraid
(I am here)

I can’t stop falling when my heart comes calling
Do you feel me?
Warming you like rays of sunshine
Can’t stop falling when my heart comes calling
Do you feel me?
Warming you like rays of golden light

Oh the summer breeze
Somehow singing softly into you
Dadada dadada dadada
Hear me whispering
Always there, no matter what you do

Porto alegre la vou eu…. SERPRO

Minha vida é mesmo feito de indas e vindas…

MAceió-Brasília e agora Brasília-Porto Alegre

Pois é, alguns dias eu fui convocado para o concurso do serpro em Porto alegre que eu fiz em 2005 ainda quando estava em maceió.

A vida é mesmo uma comédia. Prestei concurso do serpro em 2005, ainda morava em maceió e não sei porque cargas d’agua escolhi Porto Alegre … (heheh na verdade eu sei)

Entao a vida foi se encaminhando e no mesmo ano vim morar em Brasília e deixei o concurso de lado.

No ano passado em meados de abril de 2008, lecionei um treinamento de Postgresql aqui em Brasília para o Serpro e tiveram alunos de vários Serpros do Brasil. Rio de Janeiro, Recife, Minas Gerais, Pará e uma galera de POA.

Foi aí então que eu comentei: ” AAA eu fiz um concurso do serpro nem sei nem o que deu … meu endereço ainda está de maceió””

Os amigos que eu acabara de fazer durante o treinamento entraram em contato com o RH do serpro de POA e bingo!! Eu era o próximo a ser chamado, detalhe todos os meus dados ainda estavam de maceió hehehehe

Nada é por acaso!!!

Pois bem, atualizado o endereço fiquei na expectativa até que recebo o telegrama do serpro!!!

Estou arrumando as malas, malinhas e maletas…. bolsas bolsinhas e luvas de boxe!

Vamos ver se eu posso contribuir com algum conhecimento em Postgresql la no serpro de POA!!!!

Configurando o Slony na manha…

Faz uns 2 anos que eu escrevi um script em shell para facilitar a vida na configuração do slony-I. Bem, para quem ja mecheu com o Slony, ele tem uma linguagemzinha propria de configuração o slonik (chamado de pequeno elefante). Então … para configurar o slony eu tenho que saber o básico do slonik hehehe!!!

O problema de se configurar o slony, na minha opinião é que se você tiver várias, tabelas, sequences no seu banco de dados, que é comum encontrarmos um banco com 300 tabelas e tanana e tanana entao no seu arquivo de CONF você terá uma entrada para cada tabela ou sequence replicada… e como ja foi dito existe uma sintaxe toda própria para tal tipo de configuracao.

PS: O Script é só um ponta-pé inicial para a configuração do slony, e não uma interface de gerenciamento do mesmo. Você pode alterar o código fonte e melhorá-lo, sim ele precisa de melhorias hehehhe, portanto sinta-se a vontade!!!! HÁAA eu nao coloquei no codigo fonte mas é GPL , vou colocar o mais rapido

Mas para que serve o danado do Script?

Bem … para faciltar!!!! 🙂

O bom do script é que ele é baseado em DIALOG, ou seja preenchendo as caixas de dialogo você vai configurando o slony intuitivamente sem a necessidade de meter as mãos nos Confs. Ou seja, Com menus e outros objetos você seleciona quais os bancos de dados deseja replicar, quais as tabelas que serão replicadas, quais as sequences, e o mais legal, qual será a topologia do seu Cluster.

Pode parecer mágica, magia negra, curandeirismo mas não é hehehhe. Sim você terá um banco de dados replicado em menos de um minuto não importanto a quantidade de objetos que devam ser replicados e ainda de brinde MAN ganhas um “OOOOO mas como você fez isso tão rápido” do seu chefe!!!

Replicando um banco de dados Postgresql em menos de 1 minuto!!!!

Pré-requisito

O pré-requisito não entra no 1 minuto hehehhe!!! Logicamente são os mesmos pré-requisitos do Slony-I

Postgresql instalado em cada nó.

slony-I instalado em cada nó.

o pacote Dialog instalado em um computador para gerar a configuração de preferência em um dos nós. (O script utiliza o Dialog como ja foi dito)

No nó que for rodar o script, certifique-se que o psql esteja no $PATH (preguiça minha mas vou alterar isso no script hehehhe)

Preparando o ambienteno seu banco de dados

crie um banco de dados chamado bd1 e bd2;

create database bd1;
create database bd2;

De suporte a plpgql em cada um dos bancos de dados… Lição de casa, se vc esta querendo mecher com slony entao isso tranquilo….

No nosso exemplo vamos replicar somente 2 bancos de dados em um mesmo computador, questões de muuuuita preguiça mesmo.

Vamos criar 20 tabelas em cada banco de dados da seguinte forma tabela1…. tabela20 com os seguinte campo tabela1(id integer primary key)…… Isso é só para ilustraaaaaaaaar gente!;

for i in $(seq 1 20)
do
psql -U postgres -h localhost -c ” create table tabela$i(id integer primary key)” bd1;
psql -U postgres -h localhost -c ” create table tabela$i(id integer primary key)” bd2;
done

Beleza bd1 e bd2 criados ambos com 20 tabelas!!!!
To com ódio na ferramenta, como diria o filósofo MC catra!!! Então bora nessa.
Com o script em maos, de permissao no danado de execução e rode ele!!

Rodando o Script!!!

./slony.sh

Informe um nome para o cluster: primeiro_cluster
Esse não é um how to sobre slony, entao nao vou explicar muito…. Ta bom….. todo um cluster do slony tem que ter um nome ok?:

O seu primeiro nó a ser cadastrado será o no de origem de toda a replicação, chamado de origin node!!!
No nosso caso o no1…

Digite um nome para o no: no1

Qual o ip do no1?? Bem como ja vamos rodar na maquina local os dois bancos colocaremos: localhost
PS: como estamos em um exemplo simples posso colocar localhost, mas prefira sempre colocar o Endereço ip correspondente da maquina.

Digite o nome do usuário para se conectar no no1: tasca o postgresql…

Qual o banco do nó no1 que eu desejo replicar?? Seria o BD1??? sim sim sim

Cadastre outro nó meu jovem!!!!

Rapaz que cabra inteligente…. Cadastrei o meu primeiro nó, o nó de origem entao todos os meus outros nós que irei cadastrar serão nós que receberam a replicação. A telinha informa: Agora meu jovem vamos cadastrar os nós que receberão a replicação.

Digite um nome para o nó: no2

Digite o ip onde esta o no2: Localhost

postgres … ( to cansando pgcon lá vou eu!!!)

Escolha o bd2, é onde os dados do b1 serão replicados para o bd2!!!

Devemos cadastrar outro nó?? Não Não…..

Eita eu posso até escolher o esquema em que meus objetos estao!!! Sim as nossas 20 tabelas estao no esquema public, entao vamos escolher o esquema publico!!!

Vamos configurar para replicar as 20 tabelas do banco bd1 para o bd2!!! Escolha as 20 tabelas!!!

Atenção, que vai ser o meu provedor para o no2?? no nosso Exemplo só temos o nó1. Se tivessemos cadastrados mais nós, é nesse menu que eu ia definir a minha topologia. Marcamos o no1. Ou seja o meu no2 irá replicar através do no1. Mais uma vez, é aqui que definimos quem vai cascatear de quem…


Beleza a configuração do slony realmente já esta feita, mas vamos colocar o trem pra funfar, que é o que interessa….

Acabou….. boa sorte………

Depois que rodamos o script ele gerou uns arquivos de configuração do slony (Aconselho dar uma bizoiada neles para ver o trabalho que dá configurar o bicho na unha):
addPath.sk createSet.sk subscribe.sk iniCluster.sk no1.slon no2.slon pg_service.conf preamble.sk

Não irei entrar em detalhes desses arquivos e sua configuração, mesmo porque o script já fez a configuração todinha…

vamos la:

copie o arquivo pg_service.conf para ../pgsql/etc no meu caso /usr/local/pgsql/etc, provavelmente não existe o diretório etc dentro do /usr/local/pgsql/, crie ele e não se esqueça de manter a permissão do diretório e do arquivo para postgres. Isso em todos os hosts, ou seja todos os nós do cluster.

chmod 750 *.sk , com isso tornarei todos os meus scripts executaveis

rode os scrips na seguinte ordem:
./iniCluster.sk
./addPath.sk
./createSet.sk iniCluster.sk
./subscribe.sk

Rode o deamon dos slony:
no caso como faremos localmente abra 2 terminais:
terminal 1: slon -f ../caminho../no1.slon
terminal 2: slon -f ../caminho../no2.slon

Para finalizar…..

Para quem quiser fazer um shell para inserir 10000 linhas na tabela1 do banco1
for i in $(seq 1 10000)
do
psql -U postgresql -h localhost -c” insert into tabela1 values($i);” bd1
done

ou insira na mao alguns registros.
Depois conecte-se no banco bd2 e:
select count(*) from tabela1;

Grant *.* to usuário……

Ontem lá pelas tantas da madruga, dando um rolé pelos sites me deparei com o site do depesz Fazia um tempinho que eu não acessava o site do cara, meu irmão o cara é #”!$%% !!! Pra quem conhece o blog do cara sabe que ele manda muito bem !!!!

Bom…. já rasguei a seda…….. Um dos artigos ,o cara comentava da dificuldades dos novos dbas postgresql em dar um GRANT/REVOKE em todas as tabelas do banco de dados.

A Saga do Guerreio Paulo César (PC Boy) !!

Me lembrei do cabra aqui do trampo, grande amigo meu que trabalha aqui detentor da seguinte fala “Deixa eu chegar chegando pra não ficar ficando , aproveitar o embalo e passar batido” :).

Um dos bancos aqui tem umas 400 tabelas e ele ia uma por uma, em uma luta infernal.

Grant select,insert,update,delete on tabela1 to usuario;
Grant select,insert,update,delete on tabela2 to usuario;
……
Grant select,insert,update,delete on tabela400 to usuario;

hehehheheehehee engraçado! Mas eu já passei por isso e pode até parecer uma coisa simples ou idiota, mas….

AAAAAAA mais o pgadmin faz isso, automaticamente!!!!

É mesmo!!! Faz, mas e se você por necessidade só tem um “SIMPLES” shell hehehe?? KD o seu pgadmin? Tipo o servidor de Banco de dados não tem ambiente gráfico e tal…

No site do DESPEZ ele tinha bolado uma stored procedure que dava um grant all *.*, muito legal, vale a pena da uma olhada!!!
Eu sempre tinha resolvido esse tipo de problema fazendo um shell scriptzinho, mas como eu nunca salvo as coisas tinha que fazer toda vez que era necessário!!

PG_grantall


Eu não vou negar, shell script RuleZ!!! Gosto do bash, me sinto acolhido naquele lugar escuro e quentinho hehehhee. Tava meio enferrujadão de shell script e resolvi escrever um script para automatizar esses grants , na verdade não foi nem muito pra ajudar o jovem PC, foi pra relembrar algumas coisas mesmo hehehhe, coloquei o nome dele de pg_grantall.

# pg_grantall -h
pg_grantall [OPTIONS]

OPTIONS
-T GRANT on tables on database
-S GRANT on sequences on database
-U login user
-H Hostname
-R Role to grant

Por exemplo: Quero dar os todos os privilegios nas tabelas do banco de dados banco1, para o jovem paulo.

pg_grantall -T -U postgres -H localhost -R paulo banco1

Por exemplo: Quero dar os todos os privilegios nas sequences do banco de dados banco1, para o jovem paulo novamente.

pg_grantall -S -U postgres -H localhost -R paulo banco1

Por exemplo: Quero dar os todos os privilegios nas sequences e também nas tabelas do banco de dados banco1, para o jovem paulo

pg_grantall -ST -U postgres -H localhost -R paulo banco1

Pra quem quizer da uma olhada, sinta-se a vontade, inclusive para adaptá-lo.
Como sempre ando meio cansado, e reconheço que o código não está essa coca-cola toda, poderia estar melhor mas ta aí.

pg_grantall


#!/bin/bash   

MENSAGEM=" $(basename "$0") [OPTIONS]
	OPTIONS:

	-T 	Grant tables in  database
	-S      Grand sequences in database
	-U      login user
	-H      hostname 
	-R      role to grant. "

while getopts ":TSU:H:hR:" opcao 
do
	case $opcao  in 
		T) TABLES="r";;
		S) SEQUENCES="S";;
		U) USERDB=$(echo "$OPTARG");;
		H) HOST=$(echo "$OPTARG");;
		R) ROLE=$(echo "$OPTARG");;
		h) echo "$MENSAGEM";exit;; 
		\?) echo "Invalid Option!!";exit;;
		: ) echo "Argument missing!!;exit";;
		
			
	esac

done

shift $((OPTIND -1))

if [   -z "$TABLES" -a  -z "$SEQUENCES" ]  
then
	echo "Missing option T  or S"
	exit
fi

if [ -z "$USERDB" ] 
then
	USERDB="postgres"

fi

if [ -z "$HOST" ]
then

	HOST="localhost"
fi

if [ -z "$ROLE" ] 
then
	echo "what role should i give the privilleges?"
	exit;
fi 

if [ -z "$*" ]
then
       echo "What database should i connect ??"
       exit;	
       
fi

echo "Password for user $USERDB: "
read -s PASSWD 

PGPASSWORD=$(echo "$PASSWD")
export  PGPASSWORD


psql -U $USERDB -h $HOST -t  -c "select relname from pg_class where relkind
 in ('$TABLES','$SEQUENCES') and relname !~ '^(pg_|sql)';"   $*  | grep -v "^$" | 
 while read linha 
do 
	psql -U $USERDB -h $HOST -c "grant all on $linha to $ROLE;"   $*
done

Eu coloquei esse script no meu /usr/local/pgsql/bin e ficou legalzin!!

Começando com o PLPROXY….

Esse post é baseado no próprio tutorial do PL/PROXY e um HOW TO do Kristo Kaiv.

Depois de muito tempo, realmente sentei e prometi pra mim mesmo que iria conhecer o plproxy. Ontem resolvi dedicar algum tempo a ele, e acho que foi um tempo muito bem aproveitado. Bem vamos lá!
A primeira vista o tutorial do próprio projeto me pareceu bastante fraco, e demorei um pouco para absorver as particularidades do projeto.

Para que serve o particionamento?

Particionamento possibilita balancear a carga e os dados em múltiplos bancos de dados.

Entendi mas não to vizualizando…

Imagine o seguinte cenário:
Você tem uma tabela de login, com milhões de registros, e diariamente milhões de usuário se conectam no seu banco de dados. Então você tem uma carga muito alta em cima desse servidor e consequentemente muitos dados em uma única tabela.

Beleza mas o que eu poderia fazer então??


Poderíamos particionar essa tabela de login em vários servidores baseados em um determinado critério , no nosso exemplo poderia ser a primeira letra do login usuário. Exemplo: usuários de A-J servidor1, usuário de K-Z servidor2. Com isso diminuiríamos o LOAD em cima de um único servidor e promoveríamos o particionamento dos dados entre os servidores.

Mas como é feito esse particionamento Hein Hein Hein?


O caso mais comum de particionamento é realizado em cima de hash na chave primário, no nosso caso o login do usuário. Usando uma função hash, a carga vai sendo balanceada entre as partições.

Exemplo: Suponhamos que temos 2 partições, ou seja dois servidores e a nossa tabelinha de login está particionada entre os servidores. Usuários de A-J no servidor1 e usuários de K-Z no servidor2.
Então é aplicada uma função hashtext(’login’) que determina a partição que o login do usuário estará:

Sugiro que o leitor entre no banco de dados e faça os seguintes testes:
select @(hashtext(’joao’)%2 = 1
selet @(hashtext(’cosme’)%2 = 0
select @(hashtext(’lindao’)%2 = 1

O número 0 corresponde a primeira partição, e o 1 a segunda.
PS: eu sei que você digitou lindão heehe 🙂
Bem, o que ta acontecendo, através de um hash aplicado em um login eu determino em que partição se encontra o dado!!!! ok!!! mais se forem 4 partições??

select @(hashtext(’joao’)%4 = 1
select @(hashtext(’cosme’)%4 = 0
selet @(hashtext(’junior’)%4 = 3
select @(hashtext(’lindao’)%4 = 2

Isso tudo é só pra explicar como vai ser particionado e balanceado os dados e as cargas nos servidores, pois na configuração isso fica transparente.

O que é um PROXY?


Bem, eu costumo dizer que um proxy faz o serviço sujo pra vocÊ!!!!! Você se conecta em um servidor que vai servir como proxy de banco de dados e esse server se conecta nas partições.

Como funciona PLPROXY?

O plproxy é uma linguagem criada dentro de um banco de dados postgresql (assim como outras linguagens como plpgsql…. ) Possibilitando um acesso remoto em outros databases assim como o dblink. Segundo Kaiv, o plproxy é um dblink ANABOLIZADO! (hehehe não foi que quem disse isso) mas concordei.

A primeira coisa quando eu vi a definição acima, sobre plproxy, que é uma linguagem lálálá lalá lálaá que possibilita que eu me conecte em outros databases remotos ,não vi nenhuma vantagem em relação ao dblink, e questionei, mas depois eu vi claramente 🙂

Instalando o plproxy

Você pode baixar os fontes na página do projeto :http://pgfoundry.org/projects/plproxy/:
Como eu estou utilizando o debian 4.0, eu já tenho instalado os pacotes de compilação (make,gcc…..)
caso você não tenha utilize:
apt-get install build-essentials:

Antes de iniciar coloque no PATH o caminho para o pg_config

PATH:=$PATH:/usr/local/pgsql/bin

Baixado o fonte, tar -xzvf plproxy…. , entre no diretório make e depois make install.
Se por acaso ocorreram erros na compilação reclamando do flex e do bison,
apt-get install flex bison
(Essa vai pro marins hehheh)

Se tudo ocorrer certinho vamos ter o arquivo /usr/loca/pgsql/share/contrib/plproxy.sql

Criando o ambiente!!!


Vamos fazer o seguinte: iremos criar 4 databases localmente:

create database bdproxy;
create database bd1;
create database bd2;
create database bd3;

Criaremos uma tabela “usuarios” que conterá o login e o mail de cada usuário do nosso sistema. Essa tabela deve ser criada no bd1, bd2, bd3.

create table usuarios(login text,mail text);

O cliente se conecta no bdproxy, e ele particiona os dados e faz o balanceamento nos outros servidores.

Criado todos os bancos de dados e a tabela usuarios em cada um deles, vamos dar suporte somente no bdproxy a linguagem plproxy:
psql -U postgres -h servidor bdproxy < /usr/local/pgsql/share/contrib/plproxy.sql

CREATE FUNCTION
CREATE LANGUAGE

Outro pré-requisito é a criação do eschema plproxy no banco bdproxy;
conectado no banco bdproxy digite:

create schema plproxy;

Criando o primeiro CLUSTER

Existem 3 funções que devem ser criadas no banco de dados que servirá como bd_proxy, no caso o bdproxy:

  • plproxy.get_cluster_version(cluster_name)

Essa função é chamada em cada requisição, e deve retornar o número da versão da configuração corrente para um cluster em particular. Se a versão retornada por essa função for maior do que a versão cacheada pelo plproxy , então a configuração e as informações sobre as partições irão sofrer um reload na configuração.

  • plproxy.get_cluster_partitions(cluster_name)

Essa função é chamada quando uma nova configuração de partição sofre um reload. Essa função deve retornar as strings de conexão para as partições no cluster. As strings de conexão devem ser retornadas na ordem correta. O número total de strings de conexão que devem ser retornadas devem ser potência de 2.

Se a string string “user=” não aparecer na string de conexão, entao a string user = CURRENT_USER irá ser adicionada na string de conexão pelo plproxy. Então o usuário que se conectou no servidor de proxy irá ser o mesmo a ser usados em outros databases. Plproxy não reconhece nenhum tipo de password, os databases que serão particionadas devem aceitar a conexão do proxy como “TRUST”, se não for requisitado nenhum password. Se a string de conexão contém explicitamente um username, então um password pode ser setado na string de conexão.

A melhor maneira de explicitar os password é adicionando eles no arquivo.pgpass no diretório home do usuário Postgres.

  • plproxy.get_cluster_config(cluster)

Deve retornar parametros de configuração como keys – valores em pares. Todas os parametros são opcionais.

Não se esqueçam , essas 3 (plproxy.get_cluster_version, plproxy.get_cluster_partitions, plproxy.get_cluster_config) funções devem ficar no banco que servirá como proxy: bdproxy

então abra uma conexão no bdproxy e criaremos essas 3 funções nele:

CREATE OR REPLACE FUNCTION plproxy.get_cluster_version(cluster_name text)
RETURNS int4 AS $$ 

BEGIN 

      IF cluster_name = 'usercluster' THEN 

           RETURN 1;

       END IF; 

    RAISE EXCEPTION 'Cluster Desconhecido';

END;

$$ LANGUAGE plpgsql; 

CREATE OR REPLACE FUNCTION plproxy.get_cluster_partitions(cluster_name text)
RETURNS SETOF text AS 

BEGIN

 IF cluster_name = 'usercluster' THEN
       RETURN NEXT 'dbname=bd1 host=127.0.0.1'; 

       RETURN NEXT 'dbname=bd2 host=127.0.0.1'; 

       RETURN NEXT 'dbname=bd3 host=127.0.0.1';

       RETURN NEXT 'dbname=bd4 host=127.0.0.1'; 

       RETURN; 

END IF;

RAISE EXCEPTION 'Cluster Desconhecido'; 

END;

$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION plproxy.get_cluster_config (cluster_name text,
out key text, out val text)
RETURNS SETOF record AS $$
BEGIN
    RETURN;
END;
$$ LANGUAGE plpgsql;

Essas são as 3 funções básicas que devem estar no banco que servirá como proxy.

Eu quero é inserir dados!!!!!

Calma jovem!!! Eu sempre fico ansioso quando começo a seguir um how to ou tutorial ( principalmente quando o cara gasta umas 2 horas e a parada não funfa), então dá uma levantada da cadeira, toma um café e VOLTA, para não errarmos nada!!!

Queremos inserir dados nos banco de dados, e logicamente isso acontecerá mediante a utilização do bdproxy, ou seja invocaremos uma função de inserção no bdproxy e ele vai fazer o balanceamento nos databases particionados.

Então vamos criar a função de insert no bdproxy.

CREATE OR REPLACE FUNCTION insert_user(username text, mail text)
RETURNS integer AS $$
     CLUSTER 'usercluster';
     RUN ON hashtext(username);
$$ LANGUAGE plproxy;

É através dessa função que os dados serão inseridos nos bancos de dados. Explicando um detalhe:

CLUSTER – é o nome do cluster que nós setamos lá no plproxy.get_cluster_version

RUN ON hashtext (username) – Agora sim…… O particionamento acontece aqui, lembra da função hash lá em cima???? ou seja baseado no username ocorre obtemos um balanceamento nos servidores :), Esse parametro é muito importante.

Agora em cada um dos servidores, bd1. bd2, bd3 , bd4

crie a seguinte função:

CREATE OR REPLACE FUNCTION insert_user(username text, mail text)
RETURNS integer AS $$
     INSERT INTO usuarios VALUES ($1,$2);
     SELECT 1;
$$ LANGUAGE SQL;


Agora vamos inserir os dados efetivamente…..

Elaborei esse shell script para automatizar a inserção, você pode inserir diretamente no bdproxy usando seu cliente de preferência.

Digite isso no shell:
for i in $(seq 1 50000)
do
psql -U postgres -h localhost -c ” select insert_user(‘usuario$i’,’usuario$i@mail.com.br’);” bdproxy
done

Então inserimos 50000 registros. Após inserirmos os registros vamos contar o número de tuplas da tabela usuarios em cada um dos databases;

bd1 —> select count(*) from usuarios = 12455
bd2 —> select count(*) from usuarios = 12528
bd3 —> select count(*) from usuarios = 12400
bd4 —> select count(*) from usuarios = 12617

Somando um total de 50000 🙂

KD meus dados??? BABY come back to meeee

Beleza, inserimos os dados e podemos observar que eles estão particionados. E agora como recuperaríamos esses dados? Bem, da mesma forma que o bdproxy particiona os dados utilizando a função hash , baseando-se no mesmo hash ele sabe em quais partições estão os dados.

Então no bdproxy vamos escrever a seguinte função:

create or replace function get_user_mail (username text) returns text as $$

        CLUSTER 'usercluster';

        RUN ON hastext(username);

        select mail from usuarios where login = username;

$$ language plproxy;


E para finalizar, (porque eu já estou cansado pra caramba…) no banco bdproxy :

select get_user_mail(‘usuario40’);

Considerações finais

Ainda faltam alguns detalhes sobre a ferramenta nesse post, mas para o começo acho que está ótimo!!! Prometo que daqui a 1/2 dias eu posto o resto!!

Uma boa lida no tutorial do plproxy e do how to do kristo são indispensáveis, acho que com esse post já possibilita um entendimento muito bom !!!

A ferramente me paraceu muito interessante, principalmente quando integramos com o pgbouncer e o londiste ou slony, mas esse post fica pra próxima.

Como eu disse no início, eu estou iniciando os estudos em cima do plproxy, ainda estou imaginando uma arquitetura bem legal pra implementar com mais maturidade e realizar alguns testes.