quinta-feira, 29 de dezembro de 2016

Renomear um banco de dados PDB


Com a utilização de banco de dados PDB, na versão 12c do Oracle ficou mais fácil a tarefa de renomear um banco de dados.

Para fazer a troca de nome de um banco de dados PDB, podemos seguir o roteiro abaixo:


1) Conectar no banco de dados 12c - Container Database

$ sqlplus / as sysdba



2) Verificar os serviços ativos (PDBs)

- Com o select abaixo, podemos verificar os serviços ativos no CDB, ou seja os bancos PDBs existentes.

SQL> select name, con_id from v$active_services order by 1;

NAME CON_ID
--------------- ----------
SYS$BACKGROUND 1
SYS$USERS 1
db12c 1
db12cXDB 1
GHMR_XTR 3


Com a identificação e confirmação do banco de dados PDB que iremos renomear (GHMR_XTR), e conectados no container database (CDB) devemos:


a) Fechar o banco de dados PDB

SQL> alter pluggable database GHMR_XTR close immediate;


b) Abrir o banco de dados em modo restrito

SQL> alter pluggable database GHMR_XTR open restricted;


c) Verificar o status do banco de dados PDB

SQL> select name, open_mode from v$pdbs;

NAME             OPEN_MODE
---------------- ----------
GHMR_XTR         READ WRITE

Este passo é apenas uma verificação de que o banco de dados PDB, aberto em modo restrito, está em modo READ WRITE


d) Fazer o rename do banco de dados PDB

Neste ponto temos que sair do banco de dados CDB e nos conectar no banco de dados PDB atual, o qual iremos mudar de nome.

SQL> alter session set container=GHMR_XTR;

Em seguida, fazer a troca do nome do banco de dados PDB

SQL> alter pluggable database GHMR_XTR rename global_name to XPTO;


Observação:  Se ao tentar mudar o nome do banco de dados PDB, estivermos conectados no CDB, iremos receber o erro abaixo:

 ORA-65046: operation not allowed from outside a pluggable



e) Conferir o novo nome do banco de dados PDB

SQL> select name, con_id from v$active_services order by 1;

NAME CON_ID
------ ----------
XPTO 3


f) Fechar o banco de dados PDB (novo)

SQL> alter pluggable database XPTO close immediate ;


g) Abrir o banco de dados PDB (novo)

SQL> alter pluggable database XPTO open ;


h) Voltar para o container database (CDB)

Para voltarmos ao container database (CDB), podemos:


- Nos conectar diretamente ao container database com o comando:

SQL> conn / as sysdba

- Ou, podemos sair do banco de dados e nos conectarmos novamente ao CDB:

SQL> exit

$> sqlplus / as sysdba


i) verificar os serviços ativos no CDB, ou seja os bancos PDBs existentes.

SQL> select name, con_id from v$active_services order by 1;


NAME CON_ID
--------------- ----------
SYS$BACKGROUND 1
SYS$USERS 1
db12c 1
db12cXDB 1
XPTO 3

ORA-00600: internal error code, arguments: [KGL-heap-size-exceeded]


No Oracle 12c, foi implementado um novo parâmetro de controle de memória, o  _kgl_large_heap_assert_threshold.

O ORA-600 [KGL-heap-size-exceeded] aparece quando um heap baseado no SGA cresce demais, ultrapassando o limite definido para o _kgl_large_heap_assert_threshold.

Esse parâmetro possui o valor padrão, definifo pela Oracle, de 500MB.

Se qualquer heap tentar alocar memória além desse tamanho, um erro interno (ORA-600 [KGL-heap-size-exceeded]) será reportado.


A solução para esse problema é alteração da configuração de dois parâmetros:

 _kgl_large_heap_warning_threshold

 _kgl_large_heap_assert_threshold


O parâmetro _kgl_large_heap_warning_threshold é a configuração de um alerta para quando o oracle ultrapassar o valor definido.
Como padrão, ele também tem o valor de 500Mb e sempre que um heap atingir esse valor (Padrão) ou o valor configurado, caso já tenha sido alterado alguma vez, ele emitirá um alerta no arquivo alert.log do banco de dados.


O parâmetro _kgl_large_heap_assert_threshold, como descrito anteriormente, é o valor de heap de memória permitido pelo Oracle.

O valor a ser configurado para esses dois parâmetros deverá ser maior do que o oracle está tentando alocar.


Para alterar o parâmetro devemos:

a) Conectar no banco de dados como sysdba

$ sqlplus / as sysdba


b) Alterar o parâmetro  _kgl_large_heap_warning_threshold

Em ambiente single:

SQL> alter system set "_kgl_large_heap_warning_threshold"=2147483647 scope=both;

Em ambiente RAC

SQL> alter system set "_kgl_large_heap_warning_threshold"=2147483647 scope=both sid='*';



c) Alterar o parâmetro  _kgl_large_heap_assert_threshold

Em ambiente single:

SQL> alter system set "_kgl_large_heap_assert_threshold"=2147483647 scope=both;

Em ambiente RAC

SQL> alter system set "_kgl_large_heap_assert_threshold"=2147483647 scope=both sid='*';


Observação:

- O valor do parâmetro _kgl_large_heap_assert_threshold deve ser configurado em bytes.
- O valor a ser definido não pode ser maior que 2147483647.
- No exemplo, utilizamos a alocação para o valor máximo permitido, mas qualquer valor poderá ser utilizado desde que seja menor ou igual a 2147483647.

- Também podemos definir os parâmetros como zero e deixar o Oracle decidir sobre a alocação dos valores de heap de memória.


Para verificarmos os valores atuais dos parâmetros, podemos utilizar o SQL abaixo:

Set lines 200
col name format a40
col DESCRIPTION format a70
col KSPPSTVL format a20

select nam.ksppinm NAME, nam.ksppdesc DESCRIPTION, val.KSPPSTVL
from x$ksppi nam,x$ksppsv val
where nam.indx = val.indx and nam.ksppinm like '%kgl_large_heap_%_threshold%';


NAME                                     DESCRIPTION                                                            KSPPSTVL
---------------------------------------- ---------------------------------------------------------------------- --------------------
_kgl_large_heap_warning_threshold        maximum heap size before KGL writes warnings to the alert log          2147483647
_kgl_large_heap_assert_threshold         maximum heap size before KGL raises an internal error                  2147483647



Referências:

Memory Notification: Library Cache Object loaded into SGA / ORA-600 [KGL-heap-size-exceeded] (Doc ID 330239.1)
Bug 22330282  "Heap size 0K exceeds notification threshold" alert messages when "_kgl_large_heap_warning_threshold" is set to 0
Bug 19708342 - Package compilation fails with ORA-600 [KGL-heap-size-exceeded] (Doc ID 19708342.8)

Alterar o nome da instância de um banco de dados Oracle


Para alterarmos o nome de uma instância no banco de dados Oracle, devemos:


1) Fazer um backup do banco de dados

É recomendado a execução de um backup FULL do banco de dados antes da atividade.


2) Criar um arquivo pfile 

Devemos, antes de fazer qualquer alteração, criar um arquivo pfile através do arquivo spfile existente no banco de dados.

SQL> create pfile='/home/oracle/pfileX.ora' from spfile;



3) Alterar o arquivo pfile

Antes de alterar o arquivo pfile que criamos no passo 2, devemos fazer uma cópia desse arquivo e deixar salvo em um diretório seguro, pois o mesmo pode ser necessário para subir o banco de dados em caso de erro durante o procedimento.

$> cp /home/oracle/pfileX.ora /home/oracle/pfileX-copia-seguranca.ora


Após termos uma cópia segura do pfile, editaremos o arquivo e alteraremos todos os parâmetros de configuração que contiverem o nome da instância antiga, trocando para o nome da instância nova.



4) Identificar a localização do SPFILE

É importante termos a localização do arquivo atual do SPFILE no banco de dados, pois posteriormente, teremos que recriar o arquivo SPFILE.

show parameter spfile

NAME        TYPE        VALUE
----------- ----------- --------------------------------------
spfile      string      +DG_001/<BANCO>/PARAMETERFILE/spfile.ora


NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
spfile                               string      +DG_001/<BANCO>/PARAMETERFILE/spfile.ora



5) Parar o banco de dados

Após a criação do arquivo pfile e identificarmos a localização do arquivo spfile, devemos parar o banco de dados.

SQL> shutdown immediate;



6) Alterar a variável de ambiente ORACLE_SID

Neste momento, já com o banco de dados parado e uma cópia do SPFILE, gerado no arquivo PFILE, devemos configurar a variável de ambiente ORACLE_SID para o valor com o novo nome da instância que desejamos criar.

$> export ORACLE_SID=NOVA_INST



7) Alterar o nome dos arquivos pfile e do spfile

Neste momento, devemos alterar o nome do arquivo pfile e do spfile para o novo nome de instância que desejamos, mas algumas ações devem ser tomadas, como:


- Fazer uma cópia do pfile e do spfile originais;

$ mv $ORACLE_HOME/dbs/pfileINST.ora $ORACLE_HOME/dbs/pfileINST_ORIGINAL.ora
$ mv $ORACLE_HOME/dbs/spfileINST.ora $ORACLE_HOME/dbs/spfileINST_ORIGINAL.ora

* Estamos entendendo que o arquivo spfile está armazenado no diretório $ORACLE_HOME/dbs/


Aqui, estamos alterando o nome do arquivo pfile que foi alterado no passo 3.

$ cp /home/oracle/pfileX.ora $ORACLE_HOME/dbs/pfileNOVA_INST.ora


Observação: Se for um ambiente RAC, este procedimento deverá ser feito em todas as instâncias do banco de dados.



8) Criar um novo arquivo de senhas

Agora, vamos criar um novo arquivo de senhas para ser utilizada com a nova instância que estamos criando.

$ orapwd file=$ORACLE_HOME/dbs/orapwNOVA_INST password=PASSWORD entries=5

Observação: Este passo é opcional.



9) Iniciar a instância do banco de dados

O banco de dados deverá ser iniciado utilizando o arquivo pfile onde foi feita a alteração do nome da instância, já copiado para $ORACLE_HOME/dbs/.

$ sqlplus / as sysdba

SQL> startup pfile='$ORACLE_HOME/dbs/pfileNOVA_INST.ora'

Observação: Se for um ambiente RAC, este procedimento deverá ser feito em todas as instâncias do banco de dados.



10) Verificar se o nome da instância foi alterada

SQL> show parameter instance_name;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
instance_name                        string      NOVA_INST


Observação: Se for um ambiente RAC, este procedimento deverá ser feito em todas as instâncias do banco de dados.



11) Forçar o checkpoint e o switch dos redo`s:

SQL> alter system checkpoint;
SQL> alter system switch logfile;


Observação: Se for um ambiente RAC, este procedimento deverá ser feito em todas as instâncias do banco de dados.



12) Criar o spfile a partir do pfile

Agora que já verificamos a alteração do nome da instância, devemos recriar o spfile utilizando o arquivo pfile.

As informações para criação do spfile foram obtidas nos passos 2,3,4 e 7.

SQL> create spfile='+DG_001/<BANCO>/PARAMETERFILE/spfile.ora' from pfile='$ORACLE_HOME/dbs/pfileNOVA_INST.ora';


Observação: Se for um ambiente RAC, este procedimento deverá ser feito em todas as instâncias do banco de dados.



13) Reiniciar o banco de dados.

Após a alteração do spfile, devemos parar o banco de dados e reiniciá-lo.

SQL> shutdown immediate

SQL> startup

Observação: Se for um ambiente RAC, este procedimento deverá ser feito em todas as instâncias do banco de dados.



Referência:

https://veduardodba.wordpress.com/2012/01/24/alterando-o-nome-da-instancia-e-do-banco-de-dados-oracle/

quarta-feira, 28 de dezembro de 2016

Como identificar o SQL_ID de um processamento

Para identificarmos o SQL_ID de um processamento no banco de dados, podemos entre algumas opções utilizar a view V$SQL;


Para isso, precisaremos:


1) Executar o SQL desejado:

Conectado no banco de dados, devemos executar o SQL que desejamos para que as informações sobre esse SQL fiquem registradas na view V$SQL.

SQL> SELECT NOME,CIDADE,UF FROM INFO WHERE CIDADE='CAJATI';



2) Obter o SQL_ID

Após a execução do SQL desejado, devemos fazer a consulta na V$SQL, onde informaremos parte do texto do SQL que desejamos obter o SQL_ID, conforme demostrado abaixo:


SELECT sql_id, hash_value, substr(sql_text,1,40) sql_text FROM V$SQL WHERE sql_text like 'SELECT NOME,CIDADE,UF%'

SQL_ID        HASH_VALUE SQL_TEXT
------------- ---------- -------------------------------------------
8g81zcprgb2t4 1861585700 SELECT NOME,CIDADE,UF FROM INFO WHERE CI



Obs.: Existem outras formas de obtenção do SQL_ID de um processamento, onde podemos utilizar as views gv$sql, v$session, gv$session, v$sqlarea, entre outras.

segunda-feira, 26 de dezembro de 2016

Sql Tunning


TUNNING com SQL_ID


Para executarmos um tunning em um SQL através de linha de comando, podemos seguir o passo a passo abaixo.


1) Criar a atividade para o tunning do SQL


Com SQL ID:

SET SERVEROUTPUT ON
declare
stmt_task VARCHAR2(50);
begin
stmt_task := DBMS_SQLTUNE.CREATE_TUNING_TASK(sql_id => '0p20wcvkp0pjw');
DBMS_OUTPUT.put_line('id: ' || stmt_task );
end;
/



Com SQL TEXT

Nesta opção, ao invés de utilizarmos o SQL ID , utilizaremos o texto do SQL que queremos fazer o tunning

EXEC :stmt_task := DBMS_SQLTUNE.CREATE_TUNING_TASK(sql_text => '<comando sql>');


Obs.: Se o comando SQL for muito grande, vale a pena obter o SQL ID para fazer o tunning



Nas duas formas de criação da atividade de tunning (TASK) informadas acima, será gerado um TASK_ID.
Devemos guardar esse TASK_ID, pois será necessário para a continuidade da análise.



2) Executar o tunning

Aqui, iremos executar o tunning no SQL desejado, conforme configurado para a atividade desejada

begin
DBMS_SQLTUNE.EXECUTE_TUNING_TASK(task_name => 'TASK_ID');
end;
/



3) Monitorar o processo de tunning

Podemos monitorar o processo de tunning na atividade desejada, com o comando abaixo:

SELECT TASK_NAME, STATUS FROM DBA_ADVISOR_LOG WHERE TASK_NAME = '<TASK_ID>';

Quando o TASK_NAME tiver o STATUS=COMPLETED significa que o processo de tunning na atividade configurada foi finalizado.



4) Verificar resultado

Com a confirmação de que o tunning para a atividade foi finalizado, podemos executar o comando abaixo para verificarmos as recomendações.

set lines 200
set long 9999999

SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_ID') AS recommendations FROM dual;


Obs.: O parâmetro SET LONG deve ser configurado antes de executar o SELECT, pois sem essa configuração o SELECT poderá não exibir o resultado e acharmos que o mesmo está vazio, quando na verdade ele precisa da configuração do SET LONG, pois o tamanho da saída do tunning é grande.


5) Examinar os resultados

Com as informações do relatório que foram exibidas no passo anterior (passo 4), podemos implementar ou não as recomendações.

Uma das recomendações pode ser a aplicação de um profile. Caso queira aplicar o profile, podemos utilizar o comando abaixo:


begin
DBMS_SQLTUNE.ACCEPT_SQL_PROFILE(task_name => '<TASK_ID>', task_owner => 'SYSTEM', replace => TRUE);
end;
/


onde:

TASK_ID é a identificação da atividade onde foi feito o tunning

task_owner é o usuário que fará a aplicação do profile e para isso precisa ser o usuário SYSTEM, ou um usuário que possua as permissões necessárias.

replace => TRUE informa que um sql profile existe será substituído por este que estamos aplicando no momento.


Obs.: No resultado do SQL TUNNING que é gerado no passo 4 desse procedimento, quando existe a possibilidade de aplicarmos um profile, o comando já vem exibido nas recomendações.



6) Verificar os sql profiles


Podemos verificar os profiles no banco de dados através do comando abaixo:

select * from dba_sql_profiles;


7) Desabilitar um sql profile

Se desejarmos desabilitar um sql profile, podemos utilizar o comando abaixo:

begin
DBMS_SQLTUNE.ALTER_SQL_PROFILE('SQL_PROFILE','STATUS','DISABLED');
end;
/




Referências:
https://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_sqltun.htm#CHDGBCDB
http://www.runningoracle.com/product_info.php?products_id=435

Alterar a porta de comunicação do SCAN - Oracle 11g


Para alterarmos a porta de comunicação do SCAN Listener, podemos seguir o procedimento abaixo.

Como usuário GRID, devemos executar:

1) Verificar a configuração atual da porta de comunicação do SCAN

$ srvctl config scan_listener

SCAN Listener LISTENER_SCAN1 exists. Port: TCP:1522
SCAN Listener LISTENER_SCAN2 exists. Port: TCP:1522
SCAN Listener LISTENER_SCAN3 exists. Port: TCP:1522

O resultado mostra que na configuração atual, a porta de comunicação definida é a 1522


2) Alterar a porta de comunicação do SCAN


$ srvctl modify scan_listener -p 1521


3) Verificar se a mudança foi realizada com sucesso

$ srvctl config scan_listener

SCAN Listener LISTENER_SCAN1 exists. Port: TCP:1521
SCAN Listener LISTENER_SCAN2 exists. Port: TCP:1521
SCAN Listener LISTENER_SCAN3 exists. Port: TCP:1521


O resultado mosta que a porta de comunicação foi alterada para 1521


4) Reiniciar o grid infraestrutura

Para que o ambiente possa carregar a nova configuração, precisamos parar todo o cluster e reiniciá-lo


$ crsctl stop crs -f

$ crsctl start crs


Esse procedimento deverá ser realizado em todos os nós do cluster.


5) Alterar o parâmetro remote_listener

Após a alteração da porta de comunicação do Grid, devemos agora configurar o banco de dados para que utilize a nova porta de comunicação.

Para isso, como usuário Oracle, devemos:

a) Conectar no banco de dados

$ sqlplus / as sysdba


b) Verificar a configuração atual do remote_listener


SQL> show parameter remote_listener

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
remote_listener                      string      banco-scan.world:1522




c) Alterar o remote_listener para o novo valor

SQL> alter system set remote_listener='banco-scan.world:1521' scope=both sid='*';



d) Verificar se a configuração do remote_listener foi alterada corretamente


SQL> show parameter remote_listener

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
remote_listener                      string      banco-scan.world:1521



Esse procedimento deverá ser realizado em todos os nós do cluster.


6) Alterar os arquivos de configuração do ambiente

Após a mudança da porta de comunicação do SCAN, os arquivos que se encontram em $ORACLE_HOME/network/admin, como listener.ora, tnsnames.ora deverão ser alterados, caso tenham em sua configuração a porta de comunicação antiga.




Referência:

https://oraclehandson.wordpress.com/2010/05/21/oracle-11gr2-how-to-change-scan-port/