terça-feira, 20 de agosto de 2013

Configurando SHMMAX e SHMALL para Oracle no Linux

SHMMAX  e SHMALL são dois parâmetros chaves de memoria compartilhada que impactam diretamente a maneira pela qual a Oracle cria um SGA. Memoria compartilhada nada mais é que parte do Unix IPC SYSTEM (Inter Process Communication) mantido pelo KERNEL onde vários processos compartilham um único pedaço de memoria para se comunicar uns com os outros.

O ORACLE ao tentar criar  uma SGA durante a inicialização do banco de dados, o ORACLE escolhe entre um dos três modelos de gerenciamento de memória:

a) um segmento ou
b) multi segmentos contíguos
c) multi segmentos não contíguos

A adoção de qualquer destes modelos é relacionado ao tamanho da SGA e dos valores definidos para os parâmetros de memoria compartilhada no KERNEL do Linux, e o mais importante o SHMMAX.

O que são os parâmetros – SHMMAX E SHMALL?

SHMMAX é o tamanho máximo de um único segmento de memoria compartilhada definida em “bytes”.

matvir01:~ # cat /proc/sys/kernel/shmmax
2155769856

SHMALL é o tamanho total de memoria compartilhada disponível em (paginas).

matvir01:~ # cat /proc/sys/kernel/shmall
3145728

Obs.: é importante notar aqui é o valor de SHMMAX que é definido em “bytes”, e o valor do SHMALL que é definido em “paginas”.

Qual é o valor ideal para SHMALL?

Como SHMALL é o tamanho total de memoria compartilhada, deve ser sempre menor do que a memoria física do sistema e maior do que a soma das áreas da SGA de todas as bases de dados do ORACLE Server. Uma vez que este valor (soma da SGA) chegar no limite, isto é, o valor do SHMALL, então qualquer tentativa de iniciar um banco de dados novo ou um banco de dados existente com SGA redimensionado, resultara um erro “out of memory”, erro abaixo. Isso ocorre devido não existir mais segmentos de memoria compartilhada para o SGA ser alocado.

ORA-27102: out of memory

Linux Error: 28: no space left on device.

Esse erro pode ocorrer por duas razões. O valor de SHMALL não esta definido com um valor ideal ou o servidor já chegou no limite das configurações de memoria.

Definir um valor ideal para SHMALL é sempre um trabalho difícil, de paciência, de testes ate chegar no valor ideal. É necessário saber quanto de memoria física (excluindo Cache/Swap) existe disponível no sistema e desse valor disponível o quanto você quer deixar para o sistema operacional trabalhar e quanto deixar para o Oracle trabalhar.

Por exemplo, vamos dizer que a memoria física de um servidor é de 20GB, e desse valor você quer deixar para o Linux trabalhar uns 8GB e para o ORACLE 12GB, então aqui esta como vamos obter o valor para o SHMALL.

Vamos converter esses 12GB para bytes e dividir pelo tamanho da PAGE SIZE. Lembre-se SHMALL deve ser definido em “paginas” e não em “bytes”

então aqui vai o calculo.

Primeiramente vamos determinar o tamanho do PAGE_SIZE, pode ser feito de duas maneiras. No meu caso é de 4096 e o padrão recomendado e na maioria dos casos esse é o valor padrão dos Linux.

matvir01:~ # getconf PAGE_SIZE
4096

ou

matvir01:~ # cat /proc/sys/kernel/shmmni
4096

Agora vamos converter 12GB em bytes e dividir pelo tamanho da pagina.

matvir01:~ # echo "( 12 * 1024 * 1024 * 1024 ) / 4096 " |bc -l
3145728.00000000000000000000

Redefinir SHMALL e carrega-lo dinamicamente no KERNEL.

matvir01:~ # echo "3145728" > /proc/sys/kernel/shmall
matvir01:~ # sysctl –p

Verificar o efeito

matvir01:~ # ipcs -lm

------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 2105244
max total shared memory (kbytes) = 12582912
min seg size (bytes) = 1

Qual o Valor ideal para SHMMAX?

O ORACLE faz uso de um dos três modelos de gerenciamento de memoria para criar o SGA durante a inicialização do banco de dados e faz isso na seguinte sequencia. Primeiro a Oracle tenta usar o modelo de um segmento e se falhar ele prossegue com o próximo, que é o modelo multi segmento contíguos e se falhar também ele vai com a ultima opção, que é o modelo de multi segmentos não contíguos.

Então durante a inicialização, ele procura o parâmetro SHMMAX e compara com o parâmetro de inicialização *.SGA_TARGET. Se SHMMAX > *.SGA_TARGET, então o ORACLE vai iniciar com o primeiro modelo, criando o SGA dentro de um único segmento de memoria compartilhada.

Porem se a tentativa acima (um segmento) falhar, então o ORACLE continua com a segunda opção -  o modelo multi segmentos contíguos.  Alocações contiguas, como o nome indica, são um conjunto de segmentos de memoria compartilhada, que são contiguas dentro da memoria e se ele pode encontrar um conjunto de tais segmentos, em seguida, todo SGA é criado para caber dentro deste conjunto.

Mas se não pode encontrar um conjunto de atribuições contiguas então a ultima opção é escolhida – alocação multi segmentos não contíguos e neste caso o ORACLE pega segmentos de memorias livres fragmentadas entre espaços utilizados.

Então digamos que se nós sabemos o tamanho máximo de SGA de qualquer banco de dados no servidor permaneça abaixo de 1GB, então podemos definir SHMMAX para 1GB. Mas dizer que temos tamanhos de SGA diferentes para os bancos de dados espalhados entre 512MB a 2GB, então defina SHMMAX para 2GB e assim por diante.

Alterando o valor de SHMMAX

matvir01:/etc/sysconfig # echo "8589934592" > /proc/sys/kernel/shmmax

matvir01:/etc/sysconfig # sysctl –p

Os documentos de instalação do ORACLE 11g recomenda o valor de SHMMAX como “4GB – 1 byte” ou metade do tamanho da memoria física o que for menor. Eu acredito que 4GB esta relacionado com a limitação de sistemas de 32bits (x86) onde o espaço de endereço virtual de um processo de usuário pode ser menor do que 4GB. Como não há nenhuma limitação para sistemas de 64 bits (x86_64), você pode definir SGA maior que 4GB. Mas a ideia aqui é fazer com que o ORACLE utilize o modelo eficiente de um único segmento e para isso o SHMMAX deve ficar maior que o tamanho da SGA.

Um comentário:

  1. Muito boa a explicação. Ajudou muito.. Obrigado!

    ResponderExcluir