[firebase-br] FW: Tamanho do DB

Elton da Motta Barbosa embarbosa em gmail.com
Seg Maio 31 15:13:07 -03 2010


Olá Marcelo,

> Elton,
>
> As informações do IBOConsole são as mesmas do gstat:
>

Ahh legal. Eu não costumo usá-lo como mencionei antes. Mas
provavelmente ele use algum componente administrativo IBO para acessar
os dados.

> Database header page information:
> 	Flags			0
> 	Checksum		12345
> 	Generation		157093
> 	Page size		4096
> 	ODS version		11.1
> 	Oldest transaction	157084
> 	Oldest active		157085
> 	Oldest snapshot		157085
> 	Next transaction	157087
> 	Bumped transaction	1
> 	Sequence number		0
> 	Next attachment ID	2162
> 	Implementation ID	16
> 	Shadow count		0
> 	Page buffers		0
> 	Next header page	0
> 	Database dialect	3
> 	Creation date		Dec 3, 2009 12:03:18
> 	Attributes		force write
>

Não achei a informação sobre o sweep.
Costuma aparecer assim
    Variable header data:
        Sweep interval:         20000
        *END*

 Ele está desativado? Se estiver desativado, você precisa executá-lo
manualmente. Assim então está explicado o motivo de seu Banco de dados
não diminuir.

> A TABELA_A (dados a cada 5 minutos, para 1 ano):
>
>     Primary pointer page: 210, Index root page: 211
>     Data pages: 1593, data page slots: 1593, average fill: 60%
>     Fill distribution:
> 	 0 - 19% = 1
> 	20 - 39% = 0
> 	40 - 59% = 1587
> 	60 - 79% = 5
> 	80 - 99% = 0
>
> A TABELA_B (1 dado a cada dia do ano)
>
>     Primary pointer page: 227, Index root page: 228
>     Data pages: 365, data page slots: 697, average fill: 8%
>     Fill distribution:
> 	 0 - 19% = 365
> 	20 - 39% = 0
> 	40 - 59% = 0
> 	60 - 79% = 0
> 	80 - 99% = 0
>
> E a TABELA_C (1 dado a cada mês do ano)
>
>     Primary pointer page: 231, Index root page: 232
>     Data pages: 3, data page slots: 3, average fill: 13%
>     Fill distribution:
> 	 0 - 19% = 3
> 	20 - 39% = 0
> 	40 - 59% = 0
> 	60 - 79% = 0
> 	80 - 99% = 0
>
> Agora pergunto...por que a média de preenchimento da página é tão baixo? Há
> alguma coisa a fazer para aumentar isto? Somente considerando o tamanho dos
> dados, cada record deveria ter 20 bytes (igual em todas as tabelas), mas
> ocupa 62 na TABELA_A e muito mais nas demais tabelas.
>
Embora vale lembrar que há outros dados na página além dos dados da
tabela, Note NÃO ocupam 62 bytes na página.
As páginas não estão totalmente cheias. Algo está impedindo o
preenchimento total das tabelas. Mas eu não tenho certeza do que possa
ser. Talvez problemas com o GC ou Sweep. Veja a resposta anterior.
Também os artigos na Firebase:




> > Considerando que você tenha um número "X" (xis) de páginas alocadas,
> > isso significa certamente que sua taxa de bytes/record vai variar
>
> 	Concordo, mas porque teria um número maior que o necessário de
> páginas alocadas? Por que a tabela B aloca 365 páginas e preenche na média
> 8% delas? O DB não deveria tentar utilizar o máximo possível da página antes
> de alocar outra?

Sim. Concordo. Mas não posso afirmar com 100% de certeza o motivo de
não estar fazendo isso. No entanto, um Backup seguido de restore
resolveria. Veja meus comentários mais abaixo.

> 	Estes dados para teste foram gerados através de um aplicativo (único
> acessando a base de dados) para o período de 1 ano.
> 	Nenhum dado foi apagado da base, deixando páginas vazias...a
> inserção de todos os dados foi feito em uma única execução do aplicativo,
> sem ninguém mais conectado ao DB.
>

Uma única conexão? Mesmo assim o gstat mostra 157085 transações?

> > Não tenho certeza sobre o que disse, mas ao finalizar a inserção, você
> > também finaliza a transação ou faz o commit do tipo CommitRetaining?
>
> 	As procedures que geram os dados da TABELA_B e C, após a inserção na
> TABELA_A, antigamente usavam o DELETE e depois um INSERT. Isso duplicava o
> tamanho dos dados, pois era necessário manter duas versões do record.
> 	Ao alterar as procedures para usar o "INSERT OR UPDATE", este
> problema foi resolvido.
>

Embora eu concorde com sua alteração, a antiga forma de trabalho, para
tabelas com tão pouca moviemtação não era lá de grande disperdício.
Isso de ter duas versões do record não é problema para o Firebird. Ele
utilizaria o espaço marcado como antigo assim que possível.

> 	Quanto ao Commit, o aplicativo que gerou os dados usava um único
> Commit ao final das milhares de inserções. Alterei ele para CommitRetaining
> após cada inserção e não fez diferença alguma. Na operação normal do
> sistema, pretendo alterar para um Commit, forçando a 	inicialização de uma
> nova transação para cada inserção. Utilizo o IBComponents do C++Builder e
> todos já sabem a lambança que fazem com as transações. Pretendo alterar isso
> futuramente ou utilizar alguma outra solução.
>

Não sei se você compreendeu bem a diferença entre um Commit e um
CommitRetaining. Essa alteração de 1 Commit para 1 CommitRetaining
após cada inserção não altera o número de transações abertas, e não
acho que faria alguma diferença para o que você procura. (Corrijam me
outros caso eu esteja errado)

A melhor forma de implementar várias inserções é criar uma SQL
parametrizável e fazer um Commit após um certo número de inserções (de
200 em 200 por exemplo). Mas no caso do seu programa que faz inserção
a cada 5 minutos, o melhor me parece ser:

1. AbreTransação
2. Insere Dado
3. Commit;

Passa 5 minutos

1. abreTransação
2. Insere Dado
3. Commit;
Passa 5 minutos

1. abreTransação
2. Insere Dado
3. Commit;

E por aí vai...

> > Outra coisa que me ocorreu, o que acontece se você fizer um
> > Backup/Restore? Qual o seu "Sweep interval" (olhe no gstat -h)?
>
> 	Não consigo fazer um backup/restore...estranhamente ocorre um erro
> em algum trigger durante o restore. Não tive tempo para verificar isso
> ainda.
>
> Abraço,
>
> Marcelo Richter

Rapaz se você não consegue fazer um Backup/Restore essa devia ser sua
PRINCIPAL preocupação no momento. Isso significa que você tem um Banco
de dados INCONSISTENTE e possivelmente COM FALHAS!

Seu problema de páginas mal utilizadas pode ser justamente esse.

Mande aí um outro e-mail postando os erros que acontecem no
backup/restore, suas opções usadas no gbak, que o pessoal aqui vai ter
prazer em ajudar no que for possível.

Não esqueça de verificar o Sweep Interval. Você não me respondeu sobre
ele quando perguntei no email anterior.

abraço,




Mais detalhes sobre a lista de discussão lista