O erro ORA-00845 é disparado sempre no startup de uma instância Oracle 11g, falhando com a seguinte mensagem de erro:
ORA-845: MEMORY_TARGET not supported on this system
O parâmetro MEMORY_TARGET define o tamanho a área que o Automatic Memory Management (AMM) irá poder trabalhar. O AMM permite o banco de dados Oracle realizar a redução e aumento das áreas SGA ou PGA como necessário, fazendo assim um tuning online do seu banco de dados.
Como esse artigo não se destina a explicar o que é AMM, você pode conferir mais detalhes na própria documentação Oracle: http://docs.oracle.com/cd/E11882_01/server.112/e25494/memory003.htm
O erro ORA-845 acontece quando você define um valor para o MEMORY_TARGET além do que o sistema consegue gerênciar. Vamos a um exemplo para ficar mais fácil
Em uma máquina de teste, tenho 5G de memória RAM:
[oracle@oracle11g ~]$ grep MemTotal /proc/meminfo MemTotal: 5079856 kB
Meu banco de dados, está com o MEMORY_TARGET para 1984M (quase 2G).
[oracle@oracle11g ~]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.2.0 Production on Tue Oct 16 23:13:59 2012 Copyright (c) 1982, 2010, Oracle. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing options SQL> show parameter memory NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ hi_shared_memory_address integer 0 memory_max_target big integer 1984M memory_target big integer 1984M shared_memory_address integer 0
Uma outra informação importante (você vai entender logo mais), o meu espaço em disco:
[oracle@oracle11g ~]$ df -h Filesystem Size Used Avail Use% Mounted on /dev/sda1 19G 9.0G 8.5G 52% / tmpfs 2.5G 1.2G 1.3G 48% /dev/shm
Quero agora aumentar 500M da minha AMM, vamo mudarentão o parâmetro MEMORY_TARGET para 2500M:
SQL> alter system set memory_max_target=2500M scope=spfile; System altered. SQL> alter system set memory_target=2500M scope=spfile; System altered. SQL> shut immediate Database closed. Database dismounted. ORACLE instance shut down. SQL> SQL> startup ORA-00845: MEMORY_TARGET not supported on this system SQL>
A primeira vez que vi o erro não consegui entender muito bem do que se tratava. Já que tenho memória livre de sobra, como pode 500M interferir no startup da minha instância?
Tudo ficou ainda mais confuso, quando li uma note no site do supporte da Oracle:
ORA-00845 When Starting Up An 11g Instance With AMM Configured. [ID 460506.1]
A nota diz claramente que o valor do parâmetro memory_target está relacionado com o tamanho da partição /dev/shm, e que para resolver o problema tenho que aumentar a partição /dev/shm para um valor maior:
# mount -t tmpfs shmfs -o size=7G /dev/shm
Feito isso minha instância subiu sem problema algum.
Ok … Perfeito, tudo funcionando …
Porém …
Surge agora o objetivo desse post, explicar o que o AMM tem q ver com a partição /dev/shm?!
A dúvida inicial era, por onde começar?
Bom … Existe um utilitário chamado sysresv sobre o diretório $ORACLE_HOME/bin para obter status da instância. Algumas vezes quando uma instância Oracle é abortada ou simplesmente um crash acontece, existe alguns “semaphores” ou “shared memory” que continuam ativados mesmo sem a instância no ar. Quando esses lixos (vamos dizer assim) ficam na memória a instância não consegui iniciar.
Para resolver esse problema a partir do 8i, a Oracle começou a fornecer o sysresv como um utilitário que limpa shared memory e sempahores além de visualizar processos IPC alocados, que é o que queremos. Mais detalhes veja a nota: Semaphores and Shared Memory – An Overview [ID 153961.1]
Em nosso ambiente:
[oracle@oracle11g ~]$ sysresv IPC Resources for ORACLE_SID "dbtst" : Shared Memory: ID KEY 3506180 0x3c8e282c Semaphores: ID KEY 688129 0x00fadcd4 Oracle Instance alive for sid "dbtst"
Ok, já temos a informação do Oracle que contém somente um segmento de memory shared definida pelo ID: 3506180
E no Linux? Como ele pode me falar?
No Linux assim como no Unix, é possível de obter detalhes das shared memories através do comando ipcs:
[oracle@oracle11g ~]$ ipcs -m ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x00000000 3080192 root 644 80 2 0x00000000 3112961 root 644 16384 2 0x00000000 3145730 root 644 280 2 0x3c8e282c 3506180 oracle 660 4096 0
Opa! Uma informação importante, o segmento 0x3c8e282c está sendo utilizado … porém existe somente um segmento de 4k (4096 bytes), valor muito pequeno comparado com outras versões.
Na versão 9i por exemplo esse valor é bem maior bem maior veja:
[oracle@oracle9i ~]$ ipcs -m ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x90129508 65537 oracle 640 337641472 9
Com isso, percebemos que o segmento de memória do 11g, tornou-se muito menor em relação as outras versões. Mais isso nos leva a uma pergunta: Porque ele mudou isso?
A unica conclusão que cheguei foi que ele precisava desalocar e alocar rapidamente (função do AMM) e com segmentos menores isso se torna mais rápido. Precisava confirmar isso, e iniciei uma busca de como obter mais detalhes como tamanho e endereço dos segmentos de memória.
Em busca disso encontrei a resposta no “mapeamento dos segmentos de memória” que é visualizada através do comando pmap.
oracle@oracle11g ~]$ pmap `pgrep -f lgwr` 5601: ora_lgwr_dbtst 0000000000400000 180232K r-x-- /u01/app/oracle/product/11.2.0/dbhome_1/bin/oracle 000000000b602000 1820K rwx-- /u01/app/oracle/product/11.2.0/dbhome_1/bin/oracle 000000000b7c9000 300K rwx-- [ anon ] 000000000d775000 276K rwx-- [ anon ] 0000000060000000 4K r-xs- /dev/shm/ora_dbtst_3506180_0 0000000060001000 16380K rwxs- /dev/shm/ora_dbtst_3506180_0 0000000061000000 16384K rwxs- /dev/shm/ora_dbtst_3506180_1 0000000062000000 16384K rwxs- /dev/shm/ora_dbtst_3506180_2 ... 00000000da000000 16384K rwxs- /dev/shm/ora_dbtst_3506180_122 00000000db000000 16384K rwxs- /dev/shm/ora_dbtst_3506180_123 00000000dc000000 16384K rwxs- /dev/shm/ora_dbtst_3506180_124 00000000dd000000 16384K rwxs- /dev/shm/ora_dbtst_3506180_125 00007f962c052000 1088K rwx-- /dev/zero 00007f962c162000 1088K rwx-- /dev/zero 00007f962c272000 1920K rwx-- /dev/zero 00007f962c452000 1088K rwx-- /dev/zero 00007f962c562000 1088K rwx-- /dev/zero ... 00007f962cfe0000 128K rwx-- /dev/zero 00007f962d000000 8K rwx-- /dev/zero 00007f962d142000 40K r-x-- /lib64/libnss_files-2.5.so 00007f962d14c000 2044K ----- /lib64/libnss_files-2.5.so 00007f962d34b000 4K r-x-- /lib64/libnss_files-2.5.so 00007f962d34c000 4K rwx-- /lib64/libnss_files-2.5.so 00007f962e062000 2048K ----- /lib64/libdl-2.5.so (deleted) 00007f962e262000 4K r-x-- /lib64/libdl-2.5.so (deleted) 00007f962e263000 4K rwx-- /lib64/libdl-2.5.so (deleted) ... 00007f962feec000 4K rwx-- /lib64/ld-2.5.so (deleted) 00007fff02cdf000 84K rwx-- [ stack ] 00007fff02d8d000 4K r-x-- [ anon ] ffffffffff600000 4K r-x-- [ anon ]
A saída do comando pmap para o processo LGWR mostra que o Oracle usa o /dev/shm para o compartilhamento de memória. De fato, os arquivos realmente existem na partição /dev/shm
oracle@oracle11g ~]$ ls -ltr /dev/shm/ total 1210004 -rw-r----- 1 oracle oinstall 16777216 Oct 16 23:38 ora_dbtst_3506180_125 -rw-r----- 1 oracle oinstall 16777216 Oct 16 23:38 ora_dbtst_3506180_107 -rw-r----- 1 oracle oinstall 16777216 Oct 16 23:38 ora_dbtst_3506180_108 -rw-r----- 1 oracle oinstall 16777216 Oct 16 23:38 ora_dbtst_3506180_109 -rw-r----- 1 oracle oinstall 16777216 Oct 16 23:38 ora_dbtst_3506180_110 -rw-r----- 1 oracle oinstall 16777216 Oct 16 23:38 ora_dbtst_3506180_105 -rw-r----- 1 oracle oinstall 16777216 Oct 16 23:38 ora_dbtst_3506180_104 -rw-r----- 1 oracle oinstall 16777216 Oct 16 23:38 ora_dbtst_3506180_106 -rw-r----- 1 oracle oinstall 0 Oct 16 23:38 ora_dbtst_3506180_9 -rw-r----- 1 oracle oinstall 0 Oct 16 23:38 ora_dbtst_3506180_8 -rw-r----- 1 oracle oinstall 0 Oct 16 23:38 ora_dbtst_3506180_7 ... -rw-r----- 1 oracle oinstall 0 Oct 16 23:38 ora_dbtst_3506180_13 -rw-r----- 1 oracle oinstall 0 Oct 16 23:38 ora_dbtst_3506180_12 -rw-r----- 1 oracle oinstall 0 Oct 16 23:38 ora_dbtst_3506180_11 -rw-r----- 1 oracle oinstall 0 Oct 16 23:38 ora_dbtst_3506180_10 -rw-r----- 1 oracle oinstall 0 Oct 16 23:38 ora_dbtst_3506180_1 -rw-r----- 1 oracle oinstall 16777216 Oct 16 23:38 ora_dbtst_3506180_116 -rw-r----- 1 oracle oinstall 16777216 Oct 16 23:43 ora_dbtst_3506180_92 -rw-r----- 1 oracle oinstall 16777216 Oct 16 23:43 ora_dbtst_3506180_87 .. -rw-r----- 1 oracle oinstall 16777216 Oct 17 00:14 ora_dbtst_3506180_120 -rw-r----- 1 oracle oinstall 16777216 Oct 17 00:14 ora_dbtst_3506180_0 -rw-r----- 1 oracle oinstall 16777216 Oct 17 00:14 ora_dbtst_3506180_124
Existem aí vários arquivos de 16M de tamanho, o que responde nossa primeira dúvida. O Oracle utiliza desses pequenos arquivos para armazenar os dados de segmentos compartilhados, isso é feito devida a implementação POSIX onde tudo, inclusive um “segmento de memória compartilhada” é um arquivo.
A grande sacada do AMM é permitir deslocar memória compartilhada da SGA para a memória privada da PGA e com esses pequenos segmentos de 16M torna a operação rápida e tudo isso acontece na partição /dev/shm.
Na medida que aumento ou diminuo o tamanho da PGA através do parâmetro PGA_AGGREGATE_TARGET, os arquivos dentro da partição /dev/shm vão se movimentando de acordo com o valor passado, mostrando assim o deslocamento das memórias compartilhadas e privadas.
Um outro exemplo interessante acontece quando eu baixo a instância:
SQL> shut immediate Database closed. Database dismounted. ORACLE instance shut down. SQL> exit
Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing options [oracle@oracle11g ~]$ ll /dev/shm/ total 0
Como era de imaginar, nenhum arquivo existe mais na /dev/shm
Ficou mais claro agora, porque do erro ORA-00845?
Statspack tem sido utilizado desde a versão do Oracle 8i para análise e monitoramento de performance. Não muito diferente da versão Oracle 11g (mais nova até o momento), ele fornece um relatório rápido de seu ambiente afins de processos de tuning do seu banco de dados Oracle
Para mais informações do Statspack consulte o arquivo no seu ORACLE HOME: $ORACLE_HOME/rdbms/admin/spdoc.txt
É verdade sim, que o AWR fornece um relatório melhor comparado com o Statspack, porém usuário que não possuem licença para utilizar Enterprise Manager, devem continuar utilizando o Statspack.
StatsPack tem sido construido para ser instalado somente com uma conexão SYSDBA. A instalação é simples e trivial, uma vez conectado como SYSDBA no SQLPLUS basta executar o script:
FSOARES@oracle11g> @spcreate Choose the PERFSTAT user's password ----------------------------------- Not specifying a password will result in the installation FAILING Enter value for perfstat_password: ...
Alguns perguntas serão feitas como:
- Senha do usuário PERSTATS
- Tablespace Default do usuário PERSTATS
- Tablespace Temporário do usuário PERFSTATS
Caso queria remover Statspack basta executor o spdrop.sql encontrado no $ORACLE_HOME/rdbms/admin. Qualquer falha na execução do script no momento da criação ou algum cancelamento inadequado, deve-se primeiro remover o StatsPack com o script spdrop.sql depois sim criar com o spcreate.sql.
Na criação do script, um arquivo spckg.list é criado, reveja o arquivo para qualquer possível erro que encontrar.
Está vai para quem sempre quis usar TAB no momento de fazer aquele comando no SQL*Plus.
Já imaginou digitar sel no prompt, apertar a tecla TAB e ele automaticamente completar a palavra select? Bom … isso é totalmente possível, graças ao pacote rlwrap. Além de auto completar é possível deixar um histórico de comandos no SQL*Plus. O histórico eu já mostrei a algum tempo atrás como fazer, veja aqui.
Após de você ter instalado o pacote rlwrap(é possível instalar através do yum [Red Hat, Oracle Linhx, Fedora] ou wget [Ubuntu, Debian, Suse]), veja que ele é super simples de usar. Antes de fazer a chamada para o sqlplus, basta colocar o comando rlwrap na frente, dessa forma:
oracle@oracle11g:~$ rlwrap sqlplus / as sysdba SQL*Plus: Release 11.2.0.3.0 Production on Wed Feb 29 22:53:44 2012 Copyright (c) 1982, 2011, Oracle. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production With the Partitioning and Real Application Testing options SYS@dbtst>
Pronto, a partir de agora você tem o poder de ter o histórico de todas as suas chamadas no SQL*Plus. Faça um teste você mesmo, digite o comando abaixo:
SYS@dbtst> select count(*) from dba_tables;
COUNT(*)
----------
2806
1 row selected.
Agora, aperta a seta para cima ? do seu teclado para ver o seu último comando digitado.
SYS@dbtst> (tecla seta de cima)
SYS@dbtst> select count(*) from dba_tables;
COUNT(*)
----------
2806
1 row selected.
Muito bom né?! Ok … Essa eu já tinha mostrado no último artigo do rlwrap, mais e como auto completar meus comandos? Super simples também, mais primeiro temos que criar nosso catalogo de palavras chaves que rlwrap lerá para saber o que auto completar.
Vamos então criar o arquivo chamado $ORACLE_BASE/sql.dict e nesse arquivo, vamos colocar as seguintes palavras:
select update delete create number table
Feito isso, vamos fazer o sqlplus da seguinte forma:
[oracle@oracle11g ~]$ rlwrap -b "" -f $ORACLE_BASE/sql.dict sqlplus SQL*Plus: Release 11.2.0.3.0 Production on Wed Feb 29 23:01:49 2012 Copyright (c) 1982, 2011, Oracle. All rights reserved. Enter user-name: system@dbtst Enter password: Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production With the Partitioning and Real Application Testing options SYSTEM@dbtst>
Ótimo, agora basta digitar sel, aperte a tecla TAB e veja o rlwrap auto completar o comando select
SYSTEM@dbtst> sel [TAB] SYSTEM@dbtst> select
O segredo aqui está no arquivo $ORACLE_BASE/sql.dict, que funciona como um catalogo de palavras, qual comando você colocar lá o rlwrap vai auto completar.
Lembrando que o rlwrap não funciona somente com o SQL*Plus, ele também faz a mesma coisa com o rman por exemplo:
[oracle@oracle11g ~]$ rlwrap -b "" -f $ORACLE_HOME/sql.dict rman target/
Recovery Manager: Release 11.2.0.2.0 - Production on Wed Feb 29 23:07:08 2012
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
connected to target database: DBTST (DBID=2992708500)
RMAN>
Para não ter que ficar digitando esse comando enorme, gosto de criar um alias dele e colocar no meu arquivo ~/.bashrc:
alias sql='rlwrap -b "" -f $ORACLE_BASE/sql.dict sqlplus'
Feito isso basta agora executar o alias sql que o sqlplus irá abrir com o rlwrap.
[oracle@oracle11g ~]$ . .bashrc [oracle@oracle11g ~]$ sql SQL*Plus: Release 11.2.0.3.0 Production on Wed Feb 29 23:10:12 2012 Copyright (c) 1982, 2011, Oracle. All rights reserved. Enter user-name:
Uma dica que já é bem antiga, mais que para muitos pode ser algo novo … o SQLPROMPT.
Se você já se cansou de ver nosso amigo de guerra SQL*Plus o prompt “SQL >”, realmente faltou você conhecer o comando sqlprompt.
Ele simplesmente tem a ação de mudar o nome de exibição do prompt SQL*Plus.
Não acredita? Pois bem, experimente …
SQL> set sqlprompt “Novo Prompt> ” Novo Prompt> prompt funcionou funcionou Novo Prompt> set sqlp “Mudando prompt> ” Mudando prompt>
E isso não é tudo, você pode usar com variables, veja meu exemplo
SQL> set sqlp '[ &MeuNome@SQL*Plus ] ‘ Enter value for meunome: Flavio [ Flavio@SQL*Plus ]
E se você pensa que acabou, errado! Que tal usar sqlprompt com variáveis de runtime do SQL*Plus para ajudar a identificar a instância em que você está conectado.
SQL> set sqlprompt "_user'@'_connect_identifier> " SYS@orcl> set sqlprompt "_user' '_privilege> " SYS AS SYSDBA>
E se eu sair do SQL*Plus?
SYS AS SYSDBA> exit [oracle@orcl ~]$ sqlplus / as sysdba SQL>
Sim, você perde suas alterações feitas. Mas a grande notícia é que se editar o arquivo glogin.sql localizado em:
$ORACLE_HOME/sqlplus/admin/glogin.sql
Você poderá deixar permanente suas alterações do SQL*Plus.
Infelizmente, para quem usa SQLPlus no Linux sabe como é frustrante não ter o histórico dos comandos executados assim como é possível fazer no bash do Linux.
O RLWRAP é um ferramenta free e muito simples de utilizar que permite vizualizar os históricos executados através do SQL*Plus.
Passo 1: Instale o RLWRAP através do YUM, ou abaixe e instale (arquivo rpm) através do site http://utopia.knoware.nl/~hlub/uck/rlwrap/.
$ yum install rlwrap
Passo 2: Mude seu .bashrc e adicione as seguintes linhas.
alias sqlplus='rlwrap sqlplus' alias rman='rlwrap rman'
Pronto, após o logout do seu usuário os históricos do SQLPlus estarão habilitados.
Nos testes que realizei ele funcionou legal, somente em alguns casos a ação “CONTROL + C”, para cancelar alguma solicitação não funcionou, mas mesmo assim eu o recomendo. Essa é uma dica simples que garanto que vai ser de grande ajuda para muitos.
