Neste artigo trataremos sobre as estruturas de memória que compõem uma instância Oracle, iniciando com foco na SGA - Área Global do Sistema.

Instância Oracle

Uma instância Oracle nada mais é do que a alocação de memória principal (RAM) feita pelo servidor Oracle para interagir com a estrutura física (arquivos em disco) e interface de usuário, juntamente com os processos em segundo plano (Process Monitor PMON, System Monitor SMON, Database Writeer DBWn, Log Writer LGWR, Checkpoint CKPT entre outros).

Figura 1

A Área Global do Sistema - SGA

Nos termos do sistema operacional, a Área Global de Sistema (SGA) é uma memória compartilhada.

A SGA se divide em diversas estruturas de memória a saber:

Estruturas Obrigatórias

  • O pool compartilhado;
  • O buffer de log;
  • O cache de buffer.

Estruturas Opcionais

  • O pool extenso;
  • O pool de streams;
  • O pool Java;
  • O pool de retenção do cache de buffer;
  • O pool de reciclagem do cache de buffer;
  • Os pools com tamanho de bloco nK do cache de buffer.

As estruturas de memória da SGA são controladas por parâmetros de instância, muitos deles dinâmicos, significando que até certo ponto a SGA pode ser reconfigurada sem precisar tirar o servidor do ar.

Alguns desses parâmetros podem até ser controlados automaticamente, habilitando-se o recurso de gerenciamento automático de memória compartilhada. Outros são estáticos, ou seja, não podem ser modificados sem que se finalize a instância.

A partir da versão 10g, temos disponíveis alguns assistentes que nos auxiliam a determinar quais tamanhos são apropriados para algumas das estruturas de memória da SGA, considerando que a configuração da SGA é crítica para um bom desempenho.

Podemos consultar o tamanho real da SGA em Megabytes consultando a visão V$SGASTAT conforme exemplo abaixo, que em nosso caso exibe um tamanho de 264 megabytes para a SGA.

Figura 2

O parâmetro de instância que define o tamanho limite da SGA é o SGA_MAX_SIZE. No exemplo abaixo, o tamanho limite da SGA está definido como 276MB.

Figura 3

O tamanho real da SGA sempre será igual ou menor do que SGA_MAX_SIZE, nunca excedendo este limite. Se o parâmetro SGA_MAX_SIZE não for configurado, o servidor assumirá o tamanho padrão para este parâmetro, que é o tamanho da SGA no momento da inicialização da instância.

Com exceção do buffer de log, todos os outros componentes da SGA são dimensionados em grânulos. Um grânulo é uma área de memória contígua. O tamanho dos grânulos depende da plataforma utilizada (Windows, Línux, Solaris) e varia de acordo com o tamanho total da SGA.

Para descobrirmos o tamanho de grânulos que estão sendo utilizados por uma instância, podemos consultar a visão V$SGAINFO conforme exemplo abaixo:

Figura 4

No exemplo acima descobrimos que a instância está utilizando grânulos de tamanho de 4MB.

Isto significa que, se tentarmos iniciar uma instância com a configuração do parâmetro db_cache_size com tamanho de 5MB, o tamanho real do cache de buffer será de 8MB, pois será preciso alocar 2 grânulos de 4MB.

Porém, se tentarmos iniciar uma instância com a configuração do parâmetro log_buffer com tamanho de 1MB o tamanho real do buffer de log será 1MB, pois conforme já foi dito, este é o único componente da SGA que não é dimensionado em grânulos.

O Pool Compartilhado

Figura 6

O Pool Compartilhado (Shared Pool) é uma das estruturas de memória obrigatória que compõe a SGA. No Pool Compartilhado é onde são armazenados os objetos compartilhados globalmente pela instância.

Dentre os objetos compartilhados globalmente armazenados no pool compartilhado temos os planos de execução de instruções SQL, pacotes PL/SQL, procedimentos, funções...

O parâmetro de instância que define o tamanho limite do Pool Compartilhado é o SHARED_POOL_SIZE.

Figura 7

No exemplo acima, o Pool Compartilhado foi definido com tamanho de 50Mb. Porém, ao consultarmos o tamanho do Pool Compartilhado para a instância através do comando 'show parameter', foi apresentado um tamanho de 52Mb para o Pool Compartilhado. Isso ocorre porque a instância está utilizando um tamanho de grânulo de 4Mb. Logo, para alocar 50Mb para o Pool Compartilhado, foram necessários 13 grânulos de 4Mb, totalizando 52Mb de espaço para o Pool Compartilhado.

É importante lembrar que o parâmetro de instância SHARED_POOL_SIZE é dinâmico, ou seja, podemos alterar o tamanho do Pool Compartilhado sem precisar tirar o servidor do ar.

O Pool Compartilhado divide-se em uma série de estruturas de memória. Para visualizá-las, podemos consultar a visão V$SGASTAT conforme exemplo abaixo:

Figura 8

O DBA não tem controle sobre o tamanho desta série de estruturas que compõe o Pool Compartilhado, pois o próprio Oracle gerencia as estruturas dinamicamente, dentro do limite especificado pelo parâmetro de instância SHARED_POOL_SIZE.

Veremos agora algumas das estruturas mais importantes que compõem o Pool Compartilhado.

O Cache de Biblioteca

O cache de biblioteca é dividido em duas estruturas a saber:

  • A área de SQL compartilhado: que são todas as instruções SQL que podem ser usadas por qualquer sessão do usuário.
  • A área de PL/SQL compartilhado: que são as instruções da linguagem procedural compartilhadas pelas sessões.

Quando executamos uma instrução SELECT, o resultado retornado por esta instrução fica armazenado no cache de biblioteca, mais especificamente na área de SQL compartilhado. Caso uma outra sessão necessite das mesmas informações retornadas pela instrução SELECT recentemente executada, o servidor Oracle não precisa buscar essas informações em disco, pois as mesmas já estão em memória. Este mecanismo aumenta a performance do servidor Oracle.

A consulta abaixo nos exibem um tamanho da área de SQL compartilhado de aproximadamente 5Mb e um tamanho da área de PL/SQL compartilhado de aproximadamente 148Kb respectivamente.

Figura 8

O Cache de Dicionário de Dados

O cache de dicionário de dados compõe-se de informações do dicionário de dados(estruturas de tabelas, usuários, restrições, concessões, nome dos data files, entre outros) que estão sendo usadas para se interpretar as instruções SQL.

Os Buffers ASH

Os buffers ASH (Active Session History, ou Histórico da Sessão Ativa) armazenam informações relativas às atividades recentes dos usuários. Essas informações são utilizadas para diagnósticos de desempenho do servidor e são enviadas regularmente para o AWR (Repositório Automático de Carga de Trabalho do Oracle 10g) no tablespace SYSAUX.

Figura 9

Vale reforçar que todos os componentes do pool compartilhado são dimensionados automaticamente pela instância Oracle, ou seja, não temos controle sobre o tamanho de nenhum componente a não ser definindo o tamanho limite do pool compartilhado através do parâmetro dinâmico SHARED_POOL_SIZE.

Devemos ter em mente que um pool compartilhado pequeno demais prejudica o desempenho do servidor, porém um pool compartilhado excessivamente grande também prejudica o desempenho do servidor. Para determinarmos o tamanho ideal para o pool compartilhado podemos utilizar a visão V$SHARED_POOL_ADVICE conforme exemplo abaixo:

Primeiramente, temos que garantir que o parâmetro de instância STATISTICS_LEVEL esteja definido com o valor 'TYPICAL' para que o assistente esteja habilitado.

Figura 10

Depois consultamos a visão V$SHARED_POOL_ADVICE conforme consulta abaixo:

Figura 11

A consulta acima nos mostra a quantidade de tempo de parsing do cache de biblioteca que seria economizado se o pool compartilhado tivesse um determinado tamanho. A leitura é feita da seguinte forma: primeiro encontramos a linha onde a coluna 'Fator' é igual a 1. Esta linha define o tamanho atual do pool compartilhado, que em nosso exemplo é de 152Mb. A visão nos mostra estimativas que vão desde a metade do tamanho atual até o dobro do tamanho do pool compartilhado.

Em nosso exemplo, o pool compartilhado é claramente muito maior do que o necessário; ele poderia ser diminuído para 88Mb sem nenhuma deteriorização significativa no tempo economizado.

Figura 12