Compressão de Dados no SQL Server 2008

Luciano Palma
Especialista em Infraestrutura – Microsoft Brasil
Junho 2009

Conteúdo

arrow_px_down.gif Introdução
      arrow_px_down.gif Um pouco de Teoria sobre Compressão de Dados
      arrow_px_down.gif Exemplo de algoritmo simples de compressão
      arrow_px_down.gif Outros algoritmos famosos
arrow_px_down.gif Tipos de Compressão de Dados
      arrow_px_down.gif Compressão sem perdas (“lossles”)
      arrow_px_down.gif Compressão com perdas (“lossy”)
arrow_px_down.gif Benefícios e Custos da Compressão de Dados
arrow_px_down.gif Como o SQL Server 2008 implementa Compressão de Dados
arrow_px_down.gif Colunas Esparsas
      arrow_px_down.gif Como fazer?
arrow_px_down.gif Compressão aplicada a toda a Tabela
arrow_px_down.gif Compressão por Linha (ROW)
     arrow_px_down.gif Como fazer?
arrow_px_down.gif Compressão por Página (PAGE)
     arrow_px_down.gif Compressão por Prefixo
     arrow_px_down.gif Compressão por Dicionário
     arrow_px_down.gif Como fazer?
arrow_px_down.gif Estimando a eficiência da compressão
      arrow_px_down.gif Como fazer?
arrow_px_down.gif Compressão de Backup
     arrow_px_down.gif Como fazer?
arrow_px_down.gif Edições do SQL Server 2008 que implementam Compressão
arrow_px_down.gif Conclusão
arrow_px_down.gif O Autor
arrow_px_down.gif Agradecimentos
arrow_px_down.gif Bibliografia e Recursos Adicionais

Introdução

Uma das novidades do Microsoft SQL Server 2008 é a implementação da compressão de dados de forma transparente para o usuário, otimizando a autilização do espaço em disco e consequentemente reduzindo os custos associados ao sistema de armazenamento.

Este artigo tem como objetivo explicar como funciona este processo e mostrar como as técnicas de compressão de dados foram implementadas no Microsoft SQL Server 2008.

Um pouco de Teoria sobre Compressão de Dados

A teoria de compressão de dados está intimamente ligada à Teoria da Informação e o artigo tido como sua “pedra fundamental” foi escrito pelo engenheiro e matemático Claude E. Shannon em 1948. Seu texto é recheado de matemática, estatística e integrais – um bom desafio para quem gosta de estudar teorias a fundo! O artigo está disponível no link: http://cm.bell-labs.com/cm/ms/what/shannonday/shannon1948.pdf).

A informação é a base para o processo de Comunicação, que consiste no envio de uma Mensagem do Emissor para o Receptor através de um Meio de Comunicação.

Figura 1 - Componentes do Processo de Comunicação.

Uma mensagem é nada mais que um conjunto de Símbolos que devem ser transmitidos do emissor para o receptor.

Os sistemas de codificação que estamos acostumados a usar (como o ASCII, por exemplo) utilizam o mesmo número de bits para codificar um símbolo. O caracter “a”, por exemplo, é codificado com 8 bits em ASCII ou 16 bits em Unicode.

Figura 2 - Codificação de alguns caracteres em ASCII.

Na Teoria da Informação, a “quantidade de informação” contida em uma mensagem é chamada de  “entropia”. O cálculo utilizado para definir este valor leva em conta a Probabilidade (p) com que cada símbolo aparece na mensagem.
O sistema de codificação mais eficiente é aquele que consegue codificar a mensagem com a quantidade de bits mais próxima à entropia da mensagem.

Voltando ao caso da codificação ASCII, o uso de um número fixo de bits para codificar cada símbolo faz com que sejam utilizados mais bits do que os necessários para armazenar ou transmitir a mensagem, pois cada símbolo tem uma probabilidade diferente. Uma codificação que utilize poucos bits para símbolos com maior probabilidade e mais bits para símbolos com menor probabilidade será mais eficiente do que a codificação ASCII.

Todos os bits utilizados numa mensagem além daqueles equivalentes à entropia da mensagem são considerados informação redundante, pois não adicionam informação.

O papel dos algoritmos de compressão é eliminar a redundância da mensagem, sem prejuízo ao seu conteúdo. Para isso, é necessário codificá-la com o menor número possível de bits, aproximando-se da entropia da mensagem. O benefício é a redução da quantidade de bits que devem ser transmitidos ou armazenados.

Exemplo de algoritmo simples de compressão

Um método simples e rápido para a compressão de dados é o RLE (Run Length Encoding), que elimina a redundância existente em sequências de símbolos iguais. Consiste em contar o número de vezes que o mesmo símbolo se repete ao invés de transmiti-lo repetidamente. Considere a sequência “XXXXXXXXXXXXXXX”. Em codificação ASCII, seriam necessários 15 caracteres  para representar esta sequência. Com RLE, bastaria armazenar/transmitir o contador (15) e o símbolo que se repete (“X”).

Outros algoritmos famosos

Para conhecer mais sobre algoritmos de compressão, alguns recursos valiosos são os códigos de Huffman (http://en.wikipedia.org/wiki/David_A._Huffman), o algoritmo LZW (Lempel-Ziv-Welch, http://en.wikipedia.org/wiki/Lzw) e o livro “The Data Compression Book”, de Mark Nelson (http://marknelson.us/about/tdcb).

Tipos de Compressão de Dados

Existem 2 tipos de compressão de dados: sem perdas (lossles) e com perdas (lossy).

Compressão sem perdas (“lossles”)

Os conceitos citados na introdução aplicam-se à compressão sem perdas, onde a mensagem original (antes da compressão) é exatamente igual à mensagem final (após a descompressão).
No processo de compressão/descompressão sem perdas nenhum bit é descartado ou modificado.

Compressão com perdas (“lossy”)

Em alguns casos, porém, variações mínimas na mensagem podem ser aceitas/toleradas. É o caso de transmissão (ou armazenamento) de sinais de áudio, vídeo ou imagens.

arrow_px_up.gif Início da página

Benefícios e Custos da Compressão de Dados

Vimos até agora que através de algoritmos de compressão podemos armazenar ou transmitir mensagens utilizando somente os bits equivalentes à entropia da mensagem, ou ir além disso introduzindo alguma perda de detalhes “irrelevantes” da mensagem.

Obviamente, existem algoritmos e algoritmos. Alguns são mais eficientes e outros menos, mas tudo vem a um preço.

No caso de compressão de dados, o principal recurso consumido quando buscamos eficiência num algoritmo é o processador do sistema. Para atingir níveis melhores de compressão, precisamos processar mais a mensagem. Isto porque é necessário criar estatísticas mais precisas, particulares àquela mensagem e porque precisaremos implementar técnicas mais avançadas para a codificação da mensagem. Dependendo do algoritmo utilizado, pode haver também um consumo considerável de memória.

No caso de compressão com perdas, a eficiência da compressão é determinada também pela tolerância em relação à variação entre a mensagem original e a final.

Existem algoritmos simples que normalmente proporcionam um menor grau de compressão. Por outro lado, existem algoritmos que se aproximam muito da entropia da mensagem, porém ao custo de muito tempo de processamento para atingir essa eficiência na compressão.

Em todos os casos, o conhecimento das características da mensagem e do tipo de redundância que ocorre é fundamental para atingirmos a melhor taxa de compressão ao menor custo.

Como o SQL Server 2008 implementa Compressão de Dados

Um sistema de gerenciamento de dados como o SQL Server 2008 não pode perder um único bit sequer em sua operação, então é imediato dizer que o único tipo de compressão de dados viável é aquela sem perdas (lossles). Pode-se notar pela discussão acima que este tipo impõe os maiores desafios. Para garantir eficiência é necessário conhecer muito bem a natureza da informação que se está querendo transmitir/armazenar, pois somente assim se pode chegar a algoritmos que reduzam o número de bits necessários para armazenamento/transmissão sem comprometer o poder de processamento do sistema.

O SQL Server 2008 é também um sistema que implementa diversas funções distintas onde se pode aplicar compressão. Ele precisa manipular páginas de dados com informações referentes às tabelas, processando as informações no menor intervalo de tempo possível. Neste caso, um algoritmo complexo causaria impacto no desempenho. Por outro lado, durante o processo de backup, o tempo de processamento pode não ser tão crítico, principalmente se ele for eficiente a ponto de reduzir drasticamente o tempo de escrita em disco (serão escritos menos bytes após a compressão), compensando o tempo utilizado para a compressão.

Vamos analisar como o SQL Server implementa 4 tipos de compressão para aumentar a eficiência de seu sistema:

  • Colunas Esparsas
  • Compressão por Linha (ROW)
  • Compressão por Página (PAGE)
  • Compressão de Backup

Colunas Esparsas

Apesar das Colunas Esparsas não serem normalmente citadas nos artigos sobre compressão de dados do SQL Server, este recurso implementa um tipo de compressão muito simples, porém extremamente eficiente quando aplicado na massa de dados correta.

Quando uma coluna é definida como “esparsa”, valores “NULL” simplesmente não ocupam espaço de armazenamento, independentemente da definição do tipo da coluna. No entanto, para saber quais colunas contém dados e quais estão “preenchidas com NULL”, são necessários 4 bytes extra para aquelas colunas que contém alguma informação.

Novamente, o conhecimento da natureza da informação é fundamental, pois ao mesmo tempo que utilizar “Colunas Esparsas” em casos onde a maioria dos valores será “NULL” pode trazer enormes benefícios, declarar colunas como “esparsas” sem critério pode levar à utilização de até mais espaço.

Como fazer?

Uma vez realizada esta análise e tomada a decisão de declarar uma coluna como “esparsa”, no comando de criação da tabela adicione “SPARSE” na definição da(s) coluna(s), conforme o exemplo a seguir:

CREATE TABLE TabelaDeTeste

( IDCliente int PRIMARY KEY,

  NomeCliente varchar(50) NOT NULL,

  Empresa varchar(50) SPARSE NULL,

  PontosCliente smallint SPARSE NULL,

  ProfissaoCliente varchar(20) SPARSE NULL );

Note que você pode definir colunas de diversos tipos como “esparsas”, exceto:

  • geography
  • geometry
  • image
  • ntext
  • text
  • timestamp
  • Tipos de dados definidos pelo usuário

A mesma sintaxe pode ser utilizada na alteração da estrutura de uma tabela com o comando “ALTER TABLE”.

Para obter maiores informações sobre Colunas Esparsas e conferir algumas restrições de uso, acesse a seguinte página nos Manuais Online do SQL Server 2008: https://technet.microsoft.com/pt-br/library/cc280604.aspx

Compressão aplicada a toda a Tabela

Além da possibilidade de definir Colunas Esparsas, o SQL Server 2008 permite também utilizar métodos de compressão para toda uma tabela (ou índices, ou views).

Os métodos disponíveis são: Compressão por Linha (ROW) e Compressão por Página (PAGE).

A compressão pode ser aplicada aos seguintes objetos:

  • Tabelas (heaps ou com índice clustered)
  • Índice nonclustered
  • View indexada
  • Para tabelas e índices particionados, a compressão pode ser ativada para cada partição, não sendo necessário utilizar a mesma configuração de compressão para cada uma das partições

As configurações de compressão não são aplicadas automaticamente a índices nonclustered da tabela. Cada índice deve ser configurado individualmente.

A seguir vamos analisar individualmente os métodos de compressão por Linha e por Coluna.

Compressão por Linha (ROW)

Neste método de compressão, o SQL Server 2008 adota 3 técnicas para reduzir o espaço de armazenamento dos dados:

1.  Redução da sobrecarga introduzida pela necessidade de armazenar “metadados”, que são informações sobre as colunas, seus tamanhos e suas posições na estrutura de armazenamento do arquivo. No caso dos metadados, nem sempre existe redução da sobrecara a eles associada, podendo haver, em alguns casos, uso de mais espaço;

2.  Utilização de estruturas de tamanho variável para o armazenamento de dados numéricos (como integer, decimal ou float), ou de estruturas baseadas em dados numéricos (como datetime ou money);

3.  Armazenamento de sequências de caracteres utilizando estruturas de tamanho variável, evitando armazenar caracteres “em branco” quando colunas de tamanho fixo são utilizadas.

Seguem alguns exemplos para que as técnicas fiquem mais claras:

- Quando um número entre 0 e 255 é armazenado em colunas definidas como smallint, int ou bigint, o SQL Server 2008 utiliza um único byte para armazená-lo (mesmo utilizando tipos que ocupariam 2 bytes [smallint], 4 bytes [int] ou 8 bytes [bigint]).

- Quando uma coluna é definida como char ou nchar, os caracters “não preenchidos”, que seriam armazenados originalmente como caracteres “padding”, não são armazenados, evitando consumo desnecessário de espaço em disco.

Como fazer?

Para ativar a compressão por Linha para uma tabela, utilize a sintaxe conforme o exemplo a seguir:

CREATE TABLE TabelaDeTeste

( IDCliente int,
  NomeCliente nvarchar(50) )

WITH (DATA_COMPRESSION = ROW) ;

Para maiores detalhes sobre o efeito da Compressão por Linha, acesse a seguinte página nos Manuais Online do SQL Server 2008: https://technet.microsoft.com/pt-br/library/cc280576.aspx.

arrow_px_up.gif Início da página

Compressão por Página (PAGE)

Quando a compressão por Página é ativada em uma tabela ou em índice, 3 etapas* são realizadas na implementação da compressão:

  • Compressão por Linha (discutida anteriormente)
  • Compressão por Prefixo
  • Compressão por Dicionário

* Páginas de nível “non-leaf” de índices sofrem somente a primeira etapa; compressão por Linha.

Compressão por Prefixo

Conforme discutido anteriormente, uma boa técnica de compressão avalia quais símbolos ocorrem com maior frequência em uma mensagem.

Na compressão por prefixo, o SQL Server 2008 analisa cada uma das colunas, e identifica a sequência que apresenta maior redundância em cada uma das colunas (dentro da página analisada).

Esta sequência é armazenada em uma estrutura especial, chamada de “Compression Information” (CI), localizada imediatamente após o cabeçalho da página.

Cada vez que uma sequência aparece na coluna, ela é substituída por uma referência ao prefixo armazenado na estrutura especial (CI). O interessante da implementação é que não é necessário que TODA a sequência seja identificada. Se houver uma coincidência parcial (partial match), ou seja, se somente parte da sequência de caracteres do prefixo forem identificados, uma referência também é utilizada.

Vamos recorrer novamente a exemplos para facilitar o entendimento.

No caso ilustrado abaixo, a sequência “Silva” foi identificada como o prefixo a ser armazenado na estrutura CI para a primeira coluna da tabela.

Figura 4 - Escolha do prefixo com maior redundância em cada coluna.

Os dados armazenados nesta coluna serão substituídos por:

- Silvana -> ”Silva” + “na” ->  5na (5 primeiros caracteres do prefixo + “na”)

- Silva -> 5 (5 primeiros caracteres do prefixo)

- Silvina -> “Silv” + “ina” ->  4ina (4 primeiros caracteres do prefixo + “ina”)

A tabela após a compressão seria armazenada da seguinte forma:

Figura 5 -. Substituição das sequências redundantes por referências para a estrutura CI.

Desta forma, ao invés de armazenar 24 caracteres para a primeira coluna (7 de “Silvana”, 5 de “Silva”, 7 de “Silvina” e 5 de “Jorge”), o SQL Server 2008 armazenará somente 13 caracteres (3 de “5na”, 1 de “5”, 4 de “4ina” e 5 de “Jorge”). Para a segunda coluna, a redução seria de 23 para 13 caracteres, e na terceira, de 24 para 15 caracteres (no total, de 71 para 41 caracteres).

 Compressão por Dicionário

Após a compressão por prefixo, a compressão por Dicionário procura por sequências repetidas em qualquer lugar da página (ao contrário da compressão por Linha, que analisa uma coluna por vez) e armazena-as na estrutura CI - Compression Information.

Com isso, além de eliminar redundância que ocorre entre colunas distintas, a compressão por Dicionário ainda tira proveito da compressão já realizada pela compressão por Prefixo. Note, no exemplo abaixo, que o valor “4ina” já foi comprimido por Prefixo e é “reutilizado” na compressão por Dicionário.

Figura 6 - Escolha das sequências com maior redundância na página (montagem do dicionário).

Ao final do processo, a tabela teria os seguintes valores armazenados, reduzindo a somente 20 caracteres os 71 originais.

Figura 7 - Substituição das sequências redundantes por referências para o dicionário.

Como fazer?

Para ativar a compressão por Página para uma tabela, utilize a sintaxe conforme o exemplo a seguir (note que a sintaxe é idêntica à sintaxe da compressão por Linha, porém utilizando o argumento “PAGE” ao invés de “ROW”:

CREATE TABLE TabelaDeTeste

( IDCliente int,
  NomeCliente nvarchar(50) )

WITH (DATA_COMPRESSION = PAGE);

Para maiores detalhes sobre o efeito da Compressão por Página, acesse a seguinte página nos Manuais Online do SQL Server 2008: https://technet.microsoft.com/pt-br/library/cc280464.aspx.

arrow_px_up.gif Início da página

Estimando a eficiência da compressão

Antes de alterar a configuração de uma tabela, você pode estimar a eficiência da compressão sobre os seus dados.

A Stored Procedure “sp_estimate_data_compression_savings” permite que você avalie os benefícios de ativar a compressão de dados.

Como fazer?

Para avaliar os benefícios da compressão de dados em uma tabela, utilize a sintaxe conforme o exemplo a seguir:

EXEC sp_estimate_data_compression_savings 'Producao', 'TabelaDePedidos', 
NULL, NULL, 'ROW';

Onde os parâmetros são (na ordem):

- O nome do schema

- O nome do objeto

- O nome do índice

- O ID da partição

- O tipo de compressão (pode ser “ROW” ou “PAGE”)

Para maiores detalhes sobre a estimativa da eficiência da compressão, acesse a seguinte página nos Manuais Online do SQL Server 2008: https://technet.microsoft.com/en-us/library/cc280574.aspx.

Compressão de Backup

No início deste artigo, discutimos o compromisso entre eficiência do processo de compressão de dados e consumo de recursos de processamento.

Vimos que os mecanismos utilizados na manipulação de tabelas e índices, apesar de bastante eficientes, são relativamente simples. Isto acontece porque no momento em que o “engine” (ou motor) do SQL Server está manipulando dados, o processador é um recurso valioso e não pode ser comprometido pelo processo de compressão.

No entanto, quando falamos de backup o cenário é outro. Normalmente, o backup é realizado em períodos de baixa ou nenhuma utilização do sistema. O desafio aqui é finalizar o backup o mais rápido possível, reduzindo a “janela de tempo” utilizada nesta tarefa. Nesta fase, I/O passa a ser o maior gargalo do sistema, pois o volume de dados a copiar do disco e escrever em fita ou disco é normalmente muito grande. O processador tende a estar mais ocioso.

Por conta destas características, a técnica utilizada para realizar a compressão do backup é outra. Um algoritmo mais eficiente é utilizado, similar aos mecanismos de compressão de arquivos, que fazem uma análise mais complexa dos dados, implementam algoritmos mais avançados para achar a melhor codificação e assim se aproximar da entropia da informação.
Caso o cenário demande a determinação de um limite máximo de uso para a CPU, isto é possível  através de outro recurso do Microsoft SQL Server 2008: O Resource Governor.

Qual a vantagem deste esforço? Mesmo consumindo um pouco mais de CPU (que – de novo – não costuma ser gargalo nesta hora), quanto mais eficiente a compressão, menor o tamanho da massa de dados a ser escrita em fita ou disco, ou seja: menos I/O (este sim, o gargalo da operação!). Uma boa troca, não?

Normalmente, a janela de tempo necessária para realizar o backup acaba sendo reduzida com a ativação da compressão do backup, pois o volume das [demoradas] operações de I/O é bastante reduzido (e o tempo economizado com isto pode ser muito maior do que o tempo de processamento adicional para realizar a compressão).

Não existem parâmetros de configuração para o algoritmo de compressão do backup. Você pode ativá-lo ou não.

Como fazer?

Para ativar a compressão do backup, utilize a sintaxe conforme o exemplo a seguir:

BACKUP DATABASE NomeDoDataBase

TO DISK = 'D:\PastaDeBackup\ArquivoDeBakcup.bak'

WITH COMPRESSION

Para maiores detalhes sobre o efeito da compressão do backup, acesse a seguinte página nos Manuais Online do SQL Server 2008: https://technet.microsoft.com/pt-br/library/bb964719.aspx.

Edições do SQL Server 2008 que implementam Compressão

Vale lembrar que a compressão de dados só está disponível nas versões Enterprise e Developer do SQL Server 2008.

Conclusão

Vimos neste artigo como funcionam os 4 tipos de compressão implementados no Microsoft SQL Server 2008: Colunas Esparsas, Compressão por Linha, Compressão por Página e Compressão de Backup.

Conhecer a natureza da informação que será armazenada no banco de dados é fundamental para decidir qual tipo de compressão deve ser utilizado em cada situação (ou até mesmo decidir pela não utilização de compressão).

- Colunas Esparsas são eficientes quando um grande número de registros não terá valores atribuídos às colunas em questão. É o caso de campos opcionais que normalmente não são preenchidos. É interessante também utilizar Colunas Esparsas em conjunto com Índices Filtrados. Neste caso, os Índices Filtrados armazenarão somente registros que contém dados, resultando em Índices menores e portanto mais eficientes.

- A Compressão por Linha é indicada quando se deseja compressão com o mínimo de sobrecarga para o processador. Esta opção também é interessante quando já existe uma grande massa de dados armazenada e não se quer “reprocessar” toda a informação para implementar a compressão. Novos registros inseridos na tabela serão comprimidos com consumo bastante reduzido de CPU.

- A Compressão por Página é aconselhável quando se quer tirar o máximo proveito da compressão durante a manipulação de tabelas. Esta opção oferece a maior taxa de compressão, no entanto consome mais CPU do que o uso de Colunas Esparsas ou Compressão por Linha. Vale lembrar que o consumo extra de CPU pode ser compensado pela redução da quantidade de escritas/leituras em disco proporcionada pela compressão.

- A Compressão de Backup é bastante específica e via de regra traz vantagens, pois no momento em que são executados os backups, o grau de processamento é normalmente bastante baixo - o que pode tornar a redução da quantidade de I/O muito mais significativa do que o consumo extra de CPU.

O Autor

Luciano Palma é Evangelista Técnico de Infraestrutura na Microsoft do Brasil, onde também já atuou como Consultor e Engenheiro de Campo Senior, somando 8 anos na empresa. Dos 22 anos de experiência em TI, 4 deles foram adquiridos na Inglaterra e na Itália. Em 2000, Luciano publicou o Guia do TCP/IP pela Editora Novatec.
Você pode entrar em contato com ele através do blog https://blogs.technet.com/lpalma e acompanhá-lo no twitter: http://twitter.com/lucianopalma.

Agradecimentos

Aos colegas e amigos que revisaram este documento, fornecendo críticas e sugestões de enorme valor. Obrigado!

  • Markus Christen, Arquiteto de Infraestrutura da Microsoft do Brasil
  • Otávio Pecego Coelho, Gerente do Grupo de Arquitetos e Evangelistas da Microsoft do Brasil
  • Suzi Suguiyama, Consultora Principal da Microsoft do Brasil
  • Waldemir Cambiucci, Arquiteto de Desenvolvimento da Microsoft do Brasil

Bibliografia e Recursos Adicionais

Artigo de Teoria da Compressão (Claude E. Shannon) http://cm.bell-labs.com/cm/ms/what/shannonday/shannon1948.pdf

Código de Huffman http://en.wikipedia.org/wiki/David_A._Huffman

Algoritmo LZW (Lempel-Ziv-Welch)* *http://en.wikipedia.org/wiki/Lzw

The Data Compression Book”, Mark Nelson
http://marknelson.us/about/tdcb

***Colunas Esparsas
***https://technet.microsoft.com/pt-br/library/cc280604.aspx

Compressão por Linha https://technet.microsoft.com/pt-br/library/cc280576.aspx

**Compressão por Página
**https://technet.microsoft.com/pt-br/library/cc280464.aspx

Estimativa de Compressão https://technet.microsoft.com/en-us/library/cc280574.aspx

***Compressão e Backup
***https://technet.microsoft.com/pt-br/library/bb964719.aspx

Não deixe de assistir o vídeo realizado por Vitor Maurício de N. Silva sobre o tema, no site do SQLServerExperience:
https://www.microsoft.com/sql/experience/ITPros.aspx?loc=pt&filters=sdgo&clink=http%3a%2f%2fedge.technet.com%2fMedia%2fCOMPRESSAOPortugese%2f&rpage=itpros&v=http%3a%2f%2fmschnlnine.vo.llnwd.net%2fd1%2fedge%2f7%2f1%2f7%2f1%2fCOMPRESSAO.wmv.

arrow_px_up.gif Início da página