EEEEEE Jão!!!

#!/bin/bash aventuras de um Nerd disfarçado de bombado…

Configurando o Slony na manha…

Publicado por joaocosme em Setembro 22, 2008

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;

Enviado em Postgresql | 2 Comentários »

Grant *.* to usuário……

Publicado por joaocosme em Julho 4, 2008

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!!

Enviado em Postgresql | 2 Comentários »

Começando com o PLPROXY….

Publicado por joaocosme em Julho 3, 2008

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.

Enviado em Postgresql | 8 Comentários »

Automatizando deleção de databases…

Publicado por joaocosme em Julho 1, 2008

Hoje surgiu uma situação um pouco que anormal. O banco de desenvolvimento estava gigantesco com vários databases que sinceramente mais pareciam um depósitco de lixo em vez de repositório de dados. O mais interessante é que todos os databases que deveriam ser apagados tinham uma maneira de serem identificados pelo nome: começavam com bd e terminavam com old.

ex: bd_sistema1_old

Então vamos lá:

PS: Logicamente eu utilizo GNU/linux

psql -U postgres -h servidor -t -c “select datname from pg_database where datname ~ ‘^bd.*old$’ ” postgres | while read databases

do

psql -U postgres -h servidor -c “drop database $databases;” postgres

done

Enviado em Postgresql | 1 Comentário »

Shell script para backup de Wal Files!

Publicado por joaocosme em Junho 27, 2008

Esse é um simples shell script que eu utilizo juntamente com o crontab para realizar meus backups de arquivos wal. Para que não sabe do que se trata depois eu posto como se configura!!!

PS: Eu agendo uma fez por semana!

#!/bin/bash

#### Diretório de dados do postgresql ######
PGDATA=/data
SAVE_BASE_DIR=/home/postgres/arquivosbase
data=$(date +’%d%m%y’)

#### Diretorio setado para o Wal Files no postgresql.conf ####
WAL_DIR=/wallfiles

### A cada novo backup ele remove Diretorio $WAL_DIR/anterior ###
rm $WAL_DIR/wal_anterior/*

### Move os Wal gerados anterior e salva para caso de falha #####
mv /$WAL_DIR/* /$WAL_DIR/wal_anterior

export PGPASSWORD=”password”
psql -U postgres -h localhost -c ’select pg_start_backup(‘$data’);’ template1 && \
tar -czvf $SAVE_BASE_DIR/$data.tar.gz $PGDATA && psql -U postgres -h localhost -c ’select pg_stop_backup();’ template1

Enviado em Postgresql | Tagged: | Deixar um comentário »

Tricks on BASH!

Publicado por joaocosme em Junho 26, 2008

É 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!!!

Enviado em Linux | Tagged: | Deixar um comentário »

Rapidinhas do pg_dump + SED

Publicado por joaocosme em Junho 24, 2008

Hoje um desenvolvedor pediu que eu copiasse uma determinada tabela de um banco de dados ,criasse a bendita em outro banco de dados com outro nome . Tarefa simples, principalmente quando utilizamos o poderoso SED.

pg_dump -U usuario -h servidor1 -t tabela banco1 | sed ’s/tabela/tabela_temp/g’ | psql -U usuario -h servidor2 banco2

:)

Enviado em Postgresql | Deixar um comentário »

Uma pequena introdução sobre Buffer Cache!

Publicado por joaocosme em Junho 24, 2008

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.

Enviado em Banco de dados | 1 Comentário »