Archives for julho, 2008
Posted on jul 31, 2008 under Dicas Linux, Sem categoria |
Para administrar a rede em linux existe muitas ferramentas gráficas, neste post falo sobre o comando shell para administrar as placas de redes de um servidor ou de seu Desktop.
O comando utilizado para gerenciar a placa de rede chama-se ifconfig esse comando linux possui muitas opções. Este comando pertence ao pacote net-tools.
Listando as interfaces
ifconfig -a
eth0 Encapsulamento do Link: Ethernet Endereço de HW 00:16:36:08:A1:F0
inet end.: 169.254.3.2 Bcast:169.254.255.255 Masc:255.255.0.0
UP BROADCASTMULTICAST MTU:1500 Métrica:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
colisões:0 txqueuelen:1000
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
IRQ:10 Endereço de E/S:0x2000
...
...
...
Com a opção -a será listada todas as interfaces de rede.
Mais sobre o resultado do comando
Encapsulamento do Link: Ethernet – Informa qual é o protocolo utilizado para encapsular os dados pode assumir valores como: Point-to-Point, local, …
Endereço de HW Mostra o endereço MAC da placa de rede
inet end.: Informa o endereço IP associado a placa de rede
Bcast: Endereço de Broadcast da rede
Masc: Mascara de rede
UP Informa que a interface está levantada e está apta a enviar e receber pacotes
BROADCAST Informa que a interface suporta broadcast.
MULTICAST Permite a entrega de informações para vários clientes ao mesmo tempo. Mais sobre Multicast
MTU: significa Maximum Transmission Unit expressa o tamanho máximo de cada pacote o valor padrão é 1500, esse valor pode ser aumentado ou diminuído mas pode causar fragmentação de pacotes ou buffer overflow.
TX e RX packets: Informa a quantidade de pacotes enviados e recebidos com erro, quantos pacotes foram descartados. É muito útil para diagnosticar defeito na placa de rede.
colisões: Este valor também é interessante pois informa a quantidade de colisões que estão ocorrendo na rede.
txqueuelen: Este parâmetro informa o tamanho da fila de transmissão em bytes.
RX bytes,TX bytes: Demonstra a quantidade de dados transferidos respectivamente.
IRQ, Endereço de E/S São definidos pelo sistema operacional.
Colocando um ip e a mascara de rede na interface
ifconfig eth0 192.168.1.2 netmask 255.255.255.0 up
ou
ifconfig eth0 192.168.1.2/24 up
Alterando o endereço MAC através do ifconfig no Linux
ifconfig eth0 hw ether 112233445566 up
Colocando a interface em modo promíscuo com ifconfig
Estando a interface em modo promíscuo irá capturar todos os pacotes que trafegam na rede.
ifconfig eth0 promisc
Retirando a interface de modo promíscuo
ifconfig eth0 -promisc
Já o comando ifstat que pertence ao pacote iproute2, é útil para monitorar as interfaces da rede.
ifstat
#kernel
Interface RX Pkts/Rate TX Pkts/Rate RX Data/Rate TX Data/Rate
RX Errs/Drop TX Errs/Drop RX Over/Rate TX Coll/Rate
lo 12 0 12 0 216 0 216 0
0 0 0 0 0 0 0 0
eth0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
eth1 2775 0 2690 0 1614K 0 531578 0
0 0 0 0 0 0 0 0
Por hoje era isso.
Posted on jul 30, 2008 under Sem categoria |
Depois de umas merecidas férias retorno ao trabalho.
Nessas férias fizemos uma viagem de moto para o Mato Grosso Do Sul para conhecer as cidades de Campo Grande, Aquidauana, Jardim e Bonito. Estarei contando o postando as fotos da viagem no blog demoto.
Posted on jul 17, 2008 under C |
Olhando os trabalhos que realizei na faculdade. Encontrei uma AVL desenvolvida para a cadeira de estutura de dados. Implementei utilizando como interface gráfica NCURSES, para mostrar a árvore.
Irei compartilhar o código. Com certeza será bastante util para quem está estudando.
Este código tem alguns conceitos interessantes como:
- Não utiliza variáveis globais
- Os dados são inseridos na árvore quando ficar desbalanceada é informado e solicitado ao usuário se deseja balancear a árvore
- Informe como a árvore esta desbalanceada em quatro casos: EE,ED,DD e DE
- Calcula a altura da árvore
- Menu em Ncurses
- Visualização da árvore com Ncurses
/*
* Nome: Marlon Luis Petry
* Description: AVL
compilacao
gcc "Avl-Marlon.c" -o "Avl-Marlon" -g -lncurses -w
Data: 20/10/2005
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include
#include
#include
#include
#define CENTERX COLS/2
#define CENTERY LINES/2
#define DIST 5
typedef char string[50];
typedef struct t {
string info;
int alt;
struct t *pai;
struct t *left;
struct t *right;
}tree;
int tipoBal = -1;
string bal[4] = {"Caso EE","Caso ED","Caso DD","Caso DE"};
tree *bal_esq(tree *aux);
tree *bal_dir(tree *aux);
tree *rotacaoRR(tree *aux);
tree *rotacaoLL(tree *aux);
tree *rotacaoLR(tree *aux);
tree *rotacaoRL(tree *aux);
tree *insere(tree **root, string info, int h) {
char ch;
tree *aux;
if (*root == NULL)
{
aux = (tree *) malloc(sizeof(tree));
strcpy(aux->info,info);
aux->left = NULL;
aux->right = NULL;
aux->pai = NULL;
aux->alt = 0;
h = 1;
*root = aux;
}
else
{
if (strcmp(info,(*root)->info) < 0)
{
insere(&(*root)->left, info, h);
//Atualiza PAI do nó inserido
if ((*root)->left->pai == NULL)
(*root)->left->pai = *root;
if (h)
switch((*root)->alt)
{
//Estava mais alto à direita e inseriur mais um nó à esquerda
case -1:
(*root)->alt = 0;
h = 0; //Não propaga os ajustes nos fatores de balanceamento
break;
case 0:
(*root)->alt = 1; //o lado esquerdo fica maior e os fatores de
//balanceamento acima deverao ser ajustados
break;
case 1:
mvprintw(8,10,"Arvore Desbalaceou a esquerda A = %s Y = %s",(*root)->info,info);
mvprintw(9,10,"Baleancear (S)im (N)nao: ");
scanw("%c",&ch);
if(ch == 'S' || ch == 's')
{
*root = bal_esq(*root); //FB == 2 -> retorna a sub-árvore balanceada
h = 0; //não propaga a atualização dos fatores de
} //balanceamento
break;
}
}
else
{
insere(&(*root)->right, info, h);
//Atualiza PAI do nó inserido
if ((*root)->right->pai != NULL)
(*root)->right->pai = *root;
if (h)
switch ((*root)->alt)
{
//estava mais alto à esquerda e inseriu mais um nó à direita
case 1:
(*root)->alt = 0;
h = 0; //não propaga os ajustes nos fatores de balanceamneto
break;
case 0:
(*root)->alt = -1; // o lado direito fica maior do que o esquerdo e
// o ajuste deve ser propagado
break;
case -1:
//FB == -2 -> retorna a sub-árvore balanceada
mvprintw(8,10,"Arvore Desbalaceou a direita A = %s Y = %s",(*root)->info,info);
refresh();
mvprintw(9,10,"Baleancear (S)im (N)nao: ");
scanw("%c",&ch);
if(ch == 'S' || ch == 's')
{
*root = bal_dir(*root);
h = 0; //não propaga a atualização dos fatores de
} //balanceamento
break;
}
}
}
return(*root);
}
tree *bal_esq(tree *aux)
{
tree *p;
p = aux->left;
if (p->alt == 1)
{ //sinais iguais e positivo
tipoBal = 1;
aux = rotacaoLL(aux);
}
else
{
tipoBal = 2;
aux = rotacaoLR(aux); //sinais diferentes
}
aux->alt = 0;
return(aux);
}
/*
* O novo nó foi inserido à direita. Ocorreu desbalanceamento (fb == 2)
*/
tree *bal_dir(tree *aux)
{
tree *p;
p = aux->right;
if (p->alt == -1) //Sinais iguais e negativo
{
tipoBal = 3;
aux = rotacaoRR(aux);
}
else
{
tipoBal = 4;
aux = rotacaoRL(aux); //Sinais diferentes
}
aux->alt = 0;
refresh();
return(aux);
}
//rotacoes
tree *rotacaoRR(tree *aux) {
tree *p;
p = aux->right;
aux->right = p->left;
if (p->left != NULL)
p->left->pai = aux;
p->left = aux;
p->pai = aux->pai;
aux->pai = p;
aux->alt = 0;
return(p);
}
tree *rotacaoLL(tree *aux) {
tree *p;
p = aux->left;
aux->left = p->right;
if (p->right != NULL)
p->right->pai = aux;
p->right = aux;
p->pai = aux->pai;
aux->pai = p;
aux->alt = 0;
return(p);
}
tree *rotacaoLR(tree *aux) {
tree *pai; //ponteiro para depois atualizar o pai após a rotação
tree *no_left; //ponteiro para o filho esquerdo para atualizar o FB após a rotação
tree *novo_no; //ponteiro à ser retornado
int FB_fright; //fator de balanceamento do no à direita do filho esquerdo
pai = aux->pai;
no_left = aux->left;
FB_fright = no_left->right->alt;
aux->left = rotacaoRR(no_left);
novo_no = rotacaoLL(aux);
novo_no->pai = pai;
aux->alt = (FB_fright == 1)?-1:0; //Atualiza FB do nó rotacionado
no_left->alt = (FB_fright == -1)?1:0; // Atualiza FB do nó à esquerda do nó rotacionado
return(novo_no);
}
/*
* Atualização do FB e balanceamento para a raÃz esquerda
*/
tree *balanceamento_esquerdo(tree *no, int h) {
tree *f_dir;
int fb_dir;
switch (no->alt) {
case 1:
no->alt = 0;
break;
case 0:
no->alt = -1;
h = 1;
break;
case -1:
f_dir = no->right;
fb_dir = f_dir->alt;
if (fb_dir <= 0) {
f_dir = rotacaoRR(no);
if (fb_dir == 0) {
no->alt = -1;
f_dir->alt = 1;
h = 0;
}
else {
no->alt = 0;
f_dir->alt = 0;
}
no = f_dir;
}
else {
no = rotacaoRL(no);
no->alt = 0;
}
}
return(no);
}
/*
* Atualização do FB e balanceamento para a raiz direita
*/
tree *balanceamento_direito(tree *no, int h) {
tree *f_esq;
int alt_esq;
switch (no->alt) {
case -1:
no->alt = 0;
break;
case 0:
no->alt = 1;
h = 0;
break;
case 1:
f_esq = no->left;
alt_esq = f_esq->alt;
if (alt_esq >= 0) {
f_esq = rotacaoLL(no);
if (alt_esq == 0) {
no->alt = 1;
f_esq->alt = -1;
h = 0;
}
else {
no->alt = 0;
f_esq->alt = 0;
}
no = f_esq;
}
else {
no = rotacaoLR(no);
no->alt = 0;
}
}
return(no);
}
/*
* Busca nó substituto e realizada a remoção (busca o mais à direita do nó esquerdo
*/
tree *busca_remove(tree *no, tree *no_chave, int h) {
tree *no_removido;
if (no->right != NULL) {
no->right = busca_remove(no->right, no_chave, h);
if (h)
no = balanceamento_direito(no, h);
}
else {
strcpy(no_chave->info,no->info);
no_removido = no;
no = no->left;
if (no != NULL)
no->pai = no_removido->pai;
h = 1; //Deve propagar a atualização dos FB
free(no_removido);
}
return(no);
}
/*
* Remoção da Ãrvore AVL
*/
tree *removeTree(tree **raiz, int info, int h) {
if (*raiz == NULL) {
printf("Chave não localizada !");
h = 0;
}
else {
if (strcmp((*raiz)->info, info) > 0)
{
removeTree(&(*raiz)->left, info, h);
if (h)
*raiz = balanceamento_esquerdo(*raiz, h);
}
else if (strcmp((*raiz)->info , info) < 0)
{
removeTree(&(*raiz)->right, info, h);
if (h)
*raiz = balanceamento_direito(*raiz,h);
}
else { //Encontrou o elemento a ser removido
if ((*raiz)->right == NULL) {
if ((*raiz)->left != NULL) //Escolhe o nó à esquerda como substituto
(*raiz)->left->pai = (*raiz)->pai;
*raiz = (*raiz)->left;
h = 1;
}
else
if ((*raiz)->left == NULL) {
if ((*raiz)->right != NULL) //Escolhe o nó à direita como substituto
(*raiz)->right->pai = (*raiz)->pai;
*raiz = (*raiz)->right;
h = 1;
}
else { // Busca o elemento mais à direita do nó esquerdo
(*raiz)->left = busca_remove((*raiz)->left, *raiz, h);
//Se necessário efetua balanceamento (Esquerdo pois a função
//busca_remove foi para o nó esquerdo)
if (h)
*raiz = balanceamento_esquerdo(*raiz, h);
}
}
}
return(raiz);
}
tree *rotacaoRL(tree *aux) {
tree *pai; //ponteiro para depois atualizar o pai após a rotação
tree *no_right; //ponteiro para o filho direito para atualizar o FB após a rotação
tree *novo_no; //ponteiro à ser retornado
int FB_fleft; //fator de balanceamento do no à esquerda do filho direito
pai = aux->pai;
no_right = aux->right;
FB_fleft = no_right->left->alt;
aux->right = rotacaoLL(no_right);
novo_no = rotacaoRR(aux);
novo_no->pai = pai;
aux->alt = (FB_fleft == -1)?1:0; //Atualiza FB do nó rotacionado
no_right->alt = (FB_fleft == 1)?-1:0; // Atualiza FB do nó à direita do nó rotacionado
return(novo_no);
}
int maxDepth(tree *node) {
if (node==NULL) {
return(0);
}
else {
int lDepth = maxDepth(node->left);
int rDepth = maxDepth(node->right);
if (lDepth > rDepth) return(lDepth+1);
else return(rDepth+1);
}
}
//print
int print(tree *r,int x, int y)
{
int TotalWidth = width(r)*DIST;
int centerWidth = (x + TotalWidth/2);
int tamStr;
int d = 0;
//int centerWidthLinen= centerWidth +20;
char t;
if(r != NULL)
{
int leftWidth = width(r->left) * DIST;
int rigtWidth = width(r->right) * DIST;
tamStr = strlen(r->info);
mvprintw(y + (DIST/20),(centerWidth -1- (tamStr/2)),"%s", r->info);
if (r->left != NULL)
{
int leftX = print(r->left, x , y + DIST);
}
if (r->right != NULL)
{
int rightX = print(r->right, x + leftWidth, y + DIST);
}
}
return centerWidth;
}
int width(tree *root)
{
if(root == NULL)
return 1;
else if(root->left == NULL && root->right == NULL)
return 1;
else
return width(root->left) + width(root->right);
}
main()
{
tree *root = NULL;
char ch;
string msg;
string info;
int opt;
int d=0;
initscr();
bkgd(COLOR_PAIR(4));
strcpy(msg,"Pressione Qualquer Tecla");
while(1)
{
clear();
mvprintw(1,10,"%s","(1) - Inserir novo valor ");
mvprintw(2,10,"%s","(2) - Mostrar");
mvprintw(3,10,"%s","(3) - Remove");
mvprintw(4,10,"%s","(4) - Altura");
mvprintw(5,10,"%s","(5) - Sair");
mvprintw(6,10,"[ ]");
move(6,11);
scanw("%d",&opt);
refresh();
switch(opt)
{
mvprintw(10,10,"%d",opt);
case 1:
mvprintw(7,10,"%s","Informe Valor: ");
refresh();
getstr(info);
insere(&root,info,1);
break;
case 2:
clear();
print(root,CENTERX,0);
mvprintw(LINES -2,CENTERX,"%s",bal[tipoBal]);
tipoBal = -1;
mvprintw(LINES -1,CENTERX,"%s",msg);
getch();
break;
case 3:
mvprintw(7,10,"%s","Informe Valor: ");
refresh();
getstr(info);
removeTree(&root,info,1);
break;
case 4:
//mvprintw(LINES - 1,CENTERX,"%s","f para sair ");
mvprintw(7,10,"%s","Nivel");
refresh();
d = maxDepth(root);
mvprintw(8,10,"%d",d);
refresh();
break;
case 5:
//mvprintw(LINES - 1,CENTERX,"%s","f para sair ");
ch = 'f';
break;
}
refresh();
if(ch == 'f')
break;
}
endwin();
}
Não se esqueça este código é GPL pode ser usado desde que mantido os direitos autorais.
Assinem os FEEDS é de graça. Só essa semana
Posted on jul 14, 2008 under Segurança, Sem categoria |
Para corrigir bugs e falhas de segurança recorremos as atualizações fornecidas pelos gerenciador de pacote da distribuição que utilizamos.
Mas se o gerenciador de pacotes não é seguro !!
Gerenciadores de pacotes rodam normalmente com acesso irrestrito, ou seja, como root para permitir modificação críticas no sistema. O gerenciador de pacote afeta o sistema inteiro e torna-se vital para a segurança e bom funcionamento do mesmo.
A universidade de Arizona analisou 10 gerenciadores de pacotes (APT, YUM, YaST, etc.).
E descobriu que é possível realizar um ataque conhecido como Replay Attacks.
Com esse ataque um invasor pode reproduzir corretamente as assinaturas dos pacotes ou metadados a partir de uma versão anterior. Fazendo com que os usuários instalem um pacote com BUG para o invasor explorar. Podendo abrir backdoors, ler ou apagar arquivos, sem comprometer senhas ou chaves de segurança.
Como se proteger
- Usar Repositórios Confiáveis:. Use somente mirrors que pertencem a organização de confiança. Não escolha os repositórios randomicamente em uma lista de mirrors.
- Atualiza manualmente seus sistemas (local e mirror caches):. Conheça o pacote e descubra quando as atualizações disponíveis e quais devem ser as versões. Verifique e instale manualmente os pacotes atualizados ao invés de utilizar atualizações automáticas.
- Use repositórios com metadados assinados: Se o gerenciador de pacotes ou a distro ainda não assina os metadados, mas apenas pacotes, pelo menos exiga pacotes assinados até suportar metadados assinados.
- Use HTTPS para comunicar com o mirror:Infelizmente suporte a HTTPS geralmente só está disponível para suporte pago (mas só protege contra um ataque conhecido como man-in-middle, não protege contra mirrors maliciosos).
Segundo a universidade do Arizona o problema pode ocorrer em ferramentas como yum e apt.
Referências:
Attacks On Package Managers
Study: Attacks on package managers
Posted on jul 13, 2008 under Sem categoria |
Para todos que utilizam o BIND.
O Gentoo liberou a atualização para corrigir a falha Dns Cache Poisoning.
Comando para atualizar:
# emerge –sync
# emerge –ask –oneshot –verbose “>=net-dns/bind-9.4.2_p1″
Recomendações:
Para solucionar o BIND implementou a randomização da porta de pesquisa (source ports for query)
Então você precisa ter certeza que sua rede permite randomização de portas e que não tenha fixado a porta de pesquisa através da diretiva “query-source port” na configuração do BIND.
Referência
Gentoo alert 200807-08 (bind)
Posted on jul 13, 2008 under Tutoriais |
Postgresql suporta uma variedade de linguagens procedurais, podemos programar uma store procedure na linguagens de nossa preferência como exemplos: Pl/Perl, Pl/Python, Pl/Java, Pl/PHP, Pl/Ruby e muitas outras. Para utilizar estas linguagens primeiro é necessário habilitar na base de dados.
O comando para habilitar a linguagem na base de dados não é complicado. Nesse post iremos utilizar a linguagem nativa do PostgreSQL que PL/PGSQL.
Habilitando a linguagem em uma bases de dados.
create lang plpgsql nomedabasededados
Por exemplo na base de dados book
create lang plpgsql book
Este comando deve ser executado no shell.
O exemplo tem a finalidade de mostrar o poder de um procedimento armazenado (store procedure) da linguagem PL/PGSQL está linguagem somente irá atuar dentro da base de dados, então não será possível executar comandos externos. Caso seja necessário é possível desenvolver uma função externa em C ou usar uma linguagem procedural não confiável a qual pode inserir algum risco de segurança a base de dados.
Voltando ao exemplo vamos desenvolver o algoritmo da torre de hanoi em PL/PGSQL.
CREATE FUNCTION towerHanoi(ndisk INTEGER,src INTEGER,dst INTEGER, tmp INTEGER) RETURNS void AS '
Declare
BEGIN
IF ndisk = 1 THEN
RAISE NOTICE '' DISK % Move da haste % para haste % '', ndisk,src,dst;
ELSE
perform towerHanoi(ndisk - 1,src,dst,tmp);
RAISE NOTICE '' DISK % Move da haste % para haste % '', ndisk,src,tmp;
perform towerHanoi(ndisk - 1,src,tmp,src);
END IF;
END;
' LANGUAGE 'plpgsql';
Executando a função
select towerHanoi(3,1,2,3);
Veja o resultado da função
NOTA: DISK 1 Move da haste 1 para haste 2
CONTEXT: comando SQL “SELECT towerHanoi( $1 – 1, $2 , $3 , $4 )”
PL/pgSQL function “towerhanoi” line 7 at perform
comando SQL “SELECT towerHanoi( $1 – 1, $2 , $3 , $4 )”
PL/pgSQL function “towerhanoi” line 7 at perform
NOTA: DISK 2 Move da haste 1 para haste 3
CONTEXT: comando SQL “SELECT towerHanoi( $1 – 1, $2 , $3 , $4 )”
PL/pgSQL function “towerhanoi” line 7 at perform
NOTA: DISK 1 Move da haste 1 para haste 3
CONTEXT: comando SQL “SELECT towerHanoi( $1 – 1, $2 , $3 , $2 )”
PL/pgSQL function “towerhanoi” line 9 at perform
comando SQL “SELECT towerHanoi( $1 – 1, $2 , $3 , $4 )”
PL/pgSQL function “towerhanoi” line 7 at perform
NOTA: DISK 3 Move da haste 1 para haste 3
NOTA: DISK 1 Move da haste 1 para haste 3
CONTEXT: comando SQL “SELECT towerHanoi( $1 – 1, $2 , $3 , $4 )”
PL/pgSQL function “towerhanoi” line 7 at perform
comando SQL “SELECT towerHanoi( $1 – 1, $2 , $3 , $2 )”
PL/pgSQL function “towerhanoi” line 9 at perform
NOTA: DISK 2 Move da haste 1 para haste 1
CONTEXT: comando SQL “SELECT towerHanoi( $1 – 1, $2 , $3 , $2 )”
PL/pgSQL function “towerhanoi” line 9 at perform
NOTA: DISK 1 Move da haste 1 para haste 1
CONTEXT: comando SQL “SELECT towerHanoi( $1 – 1, $2 , $3 , $2 )”
PL/pgSQL function “towerhanoi” line 9 at perform
comando SQL “SELECT towerHanoi( $1 – 1, $2 , $3 , $2 )”
PL/pgSQL function “towerhanoi” line 9 at perform
Total query runtime: 2 ms.
Data retrieval runtime: 7 ms.
1 rows retrieved.
Esta simples função demonstra como usar recursividade, passagem de parâmetros e como chamar uma função em PL/PGSQL.
Estou pesquisando pra ver se consigo fazer uma árvore binária em PL/PGSQL. Quando eu conseguir coloco o algoritmo.
Abraços
Hei pessoal não se esqueçam a assinatura dos feeds é gratuita então não percam tempo.
Posted on jul 12, 2008 under Tutoriais |
A algum tempo atrás, surgiu a necessidade de saber o tamanho de cada tabela em bytes, numa base de dados (database) Postgresql. Era necessário para estimar o crescimento destas tabelas e saber quanto tempo levaria que esgotar a capacidade do HD.
Nesta pesquisa encontrei muitos dados interessantes que irei compartilhar com vocês. Claro que para alguns não terá novidade nenhuma nesta matéria, mas com certeza será valioso para alguém como foi para mim.
Antes de começar temos que entender como o postgresql gerencia os arquivos da base de dados, então vamos explora-lo.
Como PostgreSQL gerencia os arquivos da base de dados ?
O conceito fundamental do Postgresql e de outros SGBDS é que os dados são armazenados em tabelas e as tabelas agrupadas em base de dados (databases). Em um nível mais alto desta organização as base de dados são agrupadas em clusters – e um cluster de base de dados é gerenciado pelo postmaster.
E como fica essa hierarquia no disco ?
Para descobrir como funciona essa hierarquia na prática vamos fazer umas consultas (queries) , executar um comandos no shell.
Vamos começar conectando a base de dados e descobrindo o OID (Obect ID) através de uma consulta.
~$ psql book -U postgres
book=# SELECT datname, oid from pg_database;
| datname |
oid |
| postgres |
10819 |
| book |
16384 |
| template1 |
1 |
| template0 |
10818 |
(4 registros)
Na resposta da nossa query podemos ver que temos 4 base de dados (databases) no cluster. Agora podemos encontrar as base de dados no disco dentro do diretório $PG_DATA.
~$ cd $PG_DATA
~$ ls
base pg_clog pg_ident.conf pg_subtrans pg_twophase pg_xlog postmaster.opts
global pg_hba.conf pg_multixact pg_tblspc PG_VERSION postgresql.conf postmaster.pid
Dentro do subdiretório base encontra-se as base de dados no SELECT que executamos antes tem um oid 1 para a base de dados (datname) template1. Vamos entrar dentro do diretório base e ver o que tem por lá.
~$ cd base
~$ ls -la
drwx—— 2 postgres postgres 2648 Jul 11 11:17 1
drwx—— 2 postgres postgres 2648 Jul 11 11:17 10818
drwx—— 2 postgres postgres 2680 Jul 11 11:18 10819
drwx—— 2 postgres postgres 2680 Jul 11 11:39 16384
Neste exemplo temos 4 diretórios o mesmo números de registros quando executamos o SELECT então isso demonstra que o OID(object ID) corresponde ao nome do diretorio dentro da base de dados. Como exemplo o diretórios 1 corresponde a base de dados template1.
Entrando no diretório 1 podemos ver que existem vários arquivos vamos descobrir o que significa cada um deles.
~$ cd 1
~$ ls
10737 10747 10757 10767 1250 2603 2609 2615 2650 2656 2662 2668 2678 2684 690 2700 2831 2837 10739 10749 10759 10769 1255 2604 2610 2616 2651 2657 2663 2669
….
….
Para saber o que significa cada um desses arquivos temos que descobrir os OIDS dentro da base de dados template1. Vamos voltar ao psql
~$ psql -q -d template1
template1=# select oid, relname from pg_class;
| oid |
relname |
| 10762 |
sql_sizing |
| 10769 |
pg_toast_10767 |
| 10771 |
pg_toast_10767_index |
| 10767 |
sql_sizing_profiles |
| 10772 |
table_constraints |
| 10776 |
table_privileges |
| 10780 |
tables |
| 10784 |
triggered_update_columns |
| 10787 |
triggers |
Na tabela pg_class existe mais informação que pode nos ajudar a explorar a estrutura de armazenamento do PostgreSQL.
psql book -Upostgres
book=# select relname,oid,relpages, reltuples FROM pg_class ORDER BY OID;
| relname |
oid |
relpages |
reltuples |
pg_type |
1247 |
5 |
242 |
| pg_autovacuum |
1248 |
0 |
0 |
| pg_attribute |
1249 |
28 |
1628 |
| pg_autovacuum_vacrelid_index |
1250 |
1 |
0 |
| pg_proc |
1255 |
45 |
1929 |
| pg_class |
1259 |
5 |
204 |
A coluna reltuples informa quantas tuplas tem em cada tabela. Já a coluna relpages mostra quantas páginas (pages) são requiridas para armazenar o conteúdo da tabela.
Qual a correspondência entre relpages e reltuples com o tamanho do arquivo no disco ?
Vamos listar o conteúdo do diretório e pegar dois exemplos
$ ls -l 1247 1249
-rw------- 1 postgres postgres 40960 Jul 11 11:17 1247
-rw------- 1 postgres postgres 229376 Jul 11 11:17 1249
O arquivo chamado 1247 tabela pg_type ocupa um espaço em disco e 40960 bytes. Se dividirmos 40960/5 relpages = 8192 bytes, realizando o mesmo cálculo para a tabela pg_attribute que corresponde ao arquivo 1249 que possui um tamanho em disco de 229376 bytes / 28 relpages = 8192 bytes.
O tamanho 8192 refere-se ao tamanho da página este valor é fixo como podemos verificar.
Com esta matéria acho que consegui mostrar como o PostgreSQL estrutura os dados no disco.
E como descobrir o tamanho da tabela no Hd, com certeza existe outras maneiras mas escolhi está para demonstrar também como o postgresql organiza as tabelas no HD.
Referência:
Livro PostgreSQL – Korry Douglas e Susan Douglas
Posted on jul 10, 2008 under Sem categoria |
Nesta semana os seguinte post foram os mais lidos:
Posted on jul 10, 2008 under Sem categoria |
A Petição pelo veto ao projeto de cibercrimes e o Manifesto “Em defesa
da liberdade e do progresso do conhecimento na Internet Brasileira”, em
menos de 2 dias, conseguiu 5564 assinaturas de acadêmicos, professores,
jornalistas, estudantes universitários, comunicadores e pesquisadores
brasileiros.
Pessoal Vamos Fazer um broadcast deste Post do Blog do Sergio Amadeu e assinar a petição online, Divulguem nos seus blogs avisem seus amigos, mande emails.
Assinem a petição online