terça-feira, 24 de outubro de 2017

Roteiro de utilização - ASM Filter Driver (ASMFD)

Olá pessoal.

Vamos falar um pouco de ASM Filter Driver (ASMFD).

Não vamos entrar aqui em questão de definições do que é, para que serve porque se você chegou até aqui você já sabe (ou deveria saber) do que se trata o assunto.

A ideia aqui é um roteiro para inserir novos discos, deletar discos, criar diskgroup, adicionar discos, etc. 

Lembrando também que a minha virtual tem um Oracle Single 12.2.0.1.0 com GRID instalado.

Primeiro, sempre bom dar uma olhada no Help. Aqui abaixo está somente a parte que nos interessa que é do ASMFD.

[oracle@single122 ~]$ asmcmd help

        commands:
        --------
        afd_configure, afd_deconfigure, afd_di, afd_dsget, afd_dsset
        afd_filter, afd_label, afd_lsdsk, afd_lslbl, afd_refresh
        afd_scan, afd_state, afd_unlabel

Legal também dar uma olhada nos comandos para sabermos as possibilidades como abaixo.
[oracle@single122 ~]$ asmcmd help afd_state

Enfim, vamos ao que interessa. Para os nossos testes apresentei um disco (/dev/sdl) para podermos fazer o processo inteiro.

-- Vamos primeiro verificar o disco e seu tamanho.
[oracle@single122 ~]$ cd /dev/

[oracle@single122 dev]$ ls -lhrt sdl*
brw-rw---- 1 root disk 8, 176 Oct 24 08:51 sdl

[oracle@single122 dev]$ lsblk sdl
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdl    8:176  0  10G  0 disk 

-- Criando a partição no disco 

oracle@single122 dev]$ su -

[root@single122 ~]# fdisk -l /dev/sdl 

Disk /dev/sdl: 10.7 GB, 10737418240 bytes, 20971520 sectors

Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

[root@single122 ~]# fdisk /dev/sdl 
-- Responda as opções abaixo as perguntas apresentadas.
n
p
1
ENTER
ENTER
w

[root@single122 ~]# fdisk -l /dev/sdl 

Disk /dev/sdl: 10.7 GB, 10737418240 bytes, 20971520 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x00094735

Device Boot      Start         End      Blocks   Id  System
  /dev/sdl1       2048    20971519    10484736   83  Linux

-- Verificando a artição criada.
[oracle@single122 dev]$ ls -lhrt sdl*
brw-rw---- 1 root disk 8, 176 Oct 24 09:07 sdl
brw-rw---- 1 root disk 8, 177 Oct 24 09:07 sdl1

[oracle@single122 dev]$ lsblk sdl
NAME   MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdl      8:176  0  10G  0 disk 
+-sdl1   8:177  0  10G  0 part 

-- Nesse momento ainda não temos nada além da partição, nenhum disco candidate.

[oracle@single122 dev]$ asmcmd lsdsk -p --candidate



-- Vou listar os meus discos já existentes apresentados ao ASMFD.

[oracle@single122 dev]$ asmcmd afd_lsdsk
------------------------------------------------------------
Label                     Filtering   Path
============================================================
DATA01                      ENABLED   /dev/sdb1
DATA02                      ENABLED   /dev/sdc1
DATA03                      ENABLED   /dev/sdd1
DATA04                      ENABLED   /dev/sde1
DATA05                      ENABLED   /dev/sdf1
DATA06                      ENABLED   /dev/sdg1
DATA07                      ENABLED   /dev/sdh1
DATA08                      ENABLED   /dev/sdi1
DATA09                      ENABLED   /dev/sdj1
DATA10                      ENABLED   /dev/sdk1


-- Criar um label para o novo disco. Esse comando seria o equivalente (bem a grosso modo) ao CREATEDISK do ASLMLIB.


[oracle@single122 ~]$ su -

[root@single122 ~]# /oracle/12.2.0.1/grid/bin/asmcmd afd_label DATA11 /dev/sdl1


Importante: Se tentar criar um label para um disco que já está mapeado, levamos o erro abaixo:
[root@single122 dev]# /oracle/12.2.0.1/grid/bin/asmcmd afd_label DATA10 /dev/sdj1
disk /dev/sdj1 is already provisioned for ASM
ASMCMD-9513: ASM disk label set operation failed.

-- SCAN
[root@single122 dev]# /oracle/12.2.0.1/grid/bin/asmcmd afd_scan


-- Listando novamente os discos com o label criado.

[oracle@single122 dev]$ asmcmd afd_lsdsk
------------------------------------------------------------
Label                     Filtering   Path
============================================================
DATA01                      ENABLED   /dev/sdb1
DATA02                      ENABLED   /dev/sdc1
DATA03                      ENABLED   /dev/sdd1
DATA04                      ENABLED   /dev/sde1
DATA05                      ENABLED   /dev/sdf1
DATA06                      ENABLED   /dev/sdg1
DATA07                      ENABLED   /dev/sdh1
DATA08                      ENABLED   /dev/sdi1
DATA09                      ENABLED   /dev/sdj1
DATA10                      ENABLED   /dev/sdk1
DATA11                      ENABLED   /dev/sdl1

-- Ao criarmos o label, agora temos um disco candidate ao ASMFD.

[oracle@single122 dev]$ asmcmd lsdsk -p --candidate


-- Podemos verificar via SQL também.

COL GROUP_NUMBER  FORMAT 999;
COL MOUNT_STATUS  FORMAT A7;
COL HEADER_STATUS FORMAT A12;
COL MODE_STATUS   FORMAT A6;
COL PATH          FORMAT A11;
COL STATE         FORMAT A7;
COL TOTAL_MB      FORMAT 999,999,999.99;
COL FREE_MB       FORMAT 999,999,999.99;
COL NAME          FORMAT A15;
COL LABEL         FORMAT A15;
COL LIBRARY       FORMAT A10;
COL FAILGROUP     FORMAT A15;
COL VOTING_FILE   FORMAT A1;

SELECT 
           GROUP_NUMBER, 
           MOUNT_STATUS,HEADER_STATUS,MODE_STATUS,PATH, 
           STATE,TOTAL_MB,FREE_MB,NAME,LABEL,LIBRARY, 
           FAILGROUP, VOTING_FILE     
        FROM V$ASM_DISK 
        ORDER BY HEADER_STATUS, PATH;



Se o header status estiver PROVISIONED OU FORMER (fazia parte de outro DG e foi liberado), podemos adicionar. Caso tenha outro header, ai fazer o dd abaixo.
-- Vamos agora criar um novo diskgroup.

[oracle@single122 sql]$ sqlplus / as sysasm

SQL> CREATE DISKGROUP TESTE EXTERNAL REDUNDANCY DISK 'AFD:DATA11'
  ATTRIBUTE 
'SECTOR_SIZE'='512',
'LOGICAL_SECTOR_SIZE'='512',
'compatible.asm'='12.2.0.1',
'compatible.rdbms'='12.2.0.1',
'au_size'='1M';
Diskgroup created.


SQL>@showasm



-- Vamos agora dropar um disco de um dos diskgroups.

-- Remover o disco 09 do diskgroup REDO
SQL> alter diskgroup TESTE drop disk DATA09;
Diskgroup altered.


SQL> @showasm



-- Para fazer a remoção completa do disco devemos remover o label também.

[root@single122 ~]# su -

-- Listando os discos 
[root@single122 ~]# /oracle/12.2.0.1/grid/bin/asmcmd afd_lsdsk
------------------------------------------------------------
Label                     Filtering   Path
============================================================
DATA01                      ENABLED   /dev/sdb1
DATA02                      ENABLED   /dev/sdc1
DATA03                      ENABLED   /dev/sdd1
DATA04                      ENABLED   /dev/sde1
DATA05                      ENABLED   /dev/sdf1
DATA06                      ENABLED   /dev/sdg1
DATA07                      ENABLED   /dev/sdh1
DATA08                      ENABLED   /dev/sdi1
DATA09                      ENABLED   /dev/sdj1
DATA10                      ENABLED   /dev/sdk1
DATA11                      ENABLED   /dev/sdl1

-- Removendo o label
[root@single122 ~]# /oracle/12.2.0.1/grid/bin/asmcmd afd_unlabel DATA09

-- Listando novamente
[root@single122 ~]# /oracle/12.2.0.1/grid/bin/asmcmd afd_lsdsk
------------------------------------------------------------
Label                     Filtering   Path
============================================================
DATA01                      ENABLED   /dev/sdb1
DATA02                      ENABLED   /dev/sdc1
DATA03                      ENABLED   /dev/sdd1
DATA04                      ENABLED   /dev/sde1
DATA05                      ENABLED   /dev/sdf1
DATA06                      ENABLED   /dev/sdg1
DATA07                      ENABLED   /dev/sdh1
DATA08                      ENABLED   /dev/sdi1
DATA10                      ENABLED   /dev/sdk1
DATA11                      ENABLED   /dev/sdl1


--  Agora, vamos adicionar um disco a um DG existente

[oracle@single122 sql]$ sqlplus / as sysasm

-- Adicinando o disco 09
SQL> alter diskgroup TESTE add disk 'AFD:DATA09';
Diskgroup altered.


-- Dropar um diskgroup completo

SQL> drop diskgroup TESTE including contents;
Diskgroup dropped.



Importante 1: Depois disso, basta excluir os labels dos discos como descrito mais acima.
Importante2 : Caso esteja em um RAC, deixar apenas um dos nós montados

Exemplo: Temos um RAC com 2 nós, então no nó 2 executar como grid:
sqlplus / as sysasm
SQL> alter diskgroup TESTE dismount;
-- Se necessário, podemos fazer outros acertos via SQL

--  Alterando o compat ASM e DB

-- Antes da alteração
Group Name         Type       Compat.      DB Compat.      Total (GB)     Used (GB)     Free (GB) Used (PCT) Free (PCT) State
----- ------------ ---------- ------------ ------------ ------------- ------------- ------------- ---------- ---------- ----------
2 FRA          EXTERN     12.2.0.0.0   12.2.0.0.0           30.00           .06         29.94     .20 %    99.80%   MOUNTED
    

SQL> sqlplus / as sysasm
SQL> ALTER DISKGROUP FRA SET ATTRIBUTE 'compatible.asm'   = '12.2.0.1.0';
Diskgroup altered.

SQL> ALTER DISKGROUP FRA SET ATTRIBUTE 'compatible.rdbms' = '12.2.0.1.0';
Diskgroup altered.

Group Name         Type       Compat.      DB Compat.      Total (GB)     Used (GB)     Free (GB) Used (PCT) Free (PCT) State
----- ------------ ---------- ------------ ------------ ------------- ------------- ------------- ---------- ---------- ----------
2 FRA          EXTERN     12.2.0.1.0   12.2.0.1.0           30.00           .06         29.94     .20 %    99.80%   MOUNTED


-- Algumas verificações interessantes:

-- Quando adicionar ou dropar um disco do ASM, para verificar se ainda está fazendo REBALANCE
select 
o.INST_ID, 
g.name AS disk_grp, 
o.OPERATION, 
o.STATE, 
o.POWER, 
o.SOFAR, 
o.EST_WORK, 
o.EST_RATE, 
o.EST_MINUTES 
from 
GV$ASM_OPERATION o
join 
v$asm_diskgroup g ON g.group_number = o.group_number
where
o.GROUP_NUMBER=2
ORDER BY o.INST_ID, g.name;


-- Se necessário alterar o valor do rebalance online (isso pode gerar lentidão - quanto maior o power, mais impacto)

ALTER DISKGROUP DG_MVTREINA REBALANCE POWER 1;


-- Para verificar o compat,
COLUMN name FORMAT A10
COLUMN compatibility FORMAT A20
COLUMN database_compatibility FORMAT A20

SELECT 
        group_number, name, compatibility,  
        database_compatibility 
        FROM v$asm_diskgroup;


-- Para verificar os valores default na criação dos DG's
COLUMN name FORMAT A20
COLUMN value FORMAT A20

SELECT 
        group_number, name, value 
        FROM v$asm_attribute 
        WHERE 
        UPPER(NAME) NOT LIKE ('%TEMPLATE%') AND 
        GROUP_NUMBER = 1 
        ORDER BY group_number, name;

Então é isso. Espero que esse roteiro ajude.

Abraço
Mario

domingo, 8 de outubro de 2017

Erro ao criar controlfile no duplicate - perdi tudo?

Fala pessoal.

Uma dica rápida mas que pode ajudar no momento de necessidade.

Hoje estava fazendo um duplicate de uma base em RAC e por um descuido da minha parte o parâmetro "cluster_database" ficou setado com TRUE.

Como todos sabem durante o processo de duplicate deixamos esse parâmetro como FALSE.

Enfim, ao final do processo - era uma base de 5T então foi um processo bem demorado, eu tomei o erro abaixo no momento do CREATE CONTROLFILE:

released channel: aux1
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of Duplicate Db command at 10/08/2017 13:04:28
RMAN-05501: aborting duplication of target database
RMAN-06136: ORACLE error from auxiliary database: ORA-01503: CREATE CONTROLFILE failed
ORA-12720: operation requires database is in EXCLUSIVE mode

Obviamente não poderia perder todo o meu trabalho até porque tinha prazo para entrega da base. 

Verifiquei nos logs que o Restore e Recover estavam completos e que só faltava os direcionamentos do clone para o novo controlfile.

Na realidade, a sequência que faltava era a partir desse ponto abaixo:

contents of Memory Script:
{
   set newname for tempfile  1 to
'+ASMDATA01';
   set newname for tempfile  2 to
'+ASMDATA01';
   set newname for tempfile  3 to
'+ASMDATA01';
   set newname for tempfile  4 to
'+ASMDATA01';
   set newname for tempfile  5 to
'+ASMDATA01';
   set newname for tempfile  6 to
'+ASMDATA01';
   switch clone tempfile all;
   catalog clone datafilecopy  
...

   
Fiz umas pesquisas no MOS e a partir desse ponto verifiquei que seria apenas recriado o controlfile, catalogado os datafiles e feito o switch final.

Deu um pouco de trabalho no início, listei os datafiles nos DISKGROUP's e depois apenas recriei o controlfile e abri a base.

Nesse momento, como diz meu amigo Ricardo Portilho, não existe DBA Ateu ahahahahhahaha... 

Mas também lembrei dele quando demorou para o comando ser completado e como ele sempre diz "Se demorou deve estar certo...".

A criação foi normal com: CREATE CONTROLFILE SET DATABASE 'MV0610' RESETLOGS ARCHIVELOG...

Então fica a dica, caso tome um erro nesso ponto do duplicate, o trabalho não está perdido.

Abraço
Mario

quarta-feira, 12 de julho de 2017

Renomear e excluir arquivos no Linux com caracteres especiais no nome

Fala pessoal...

Hoje surgiu uma necessidade um pouco fora do normal aqui. Nada a ver com Oracle e sim com a exclusão de arquivos no linux.

Achei bacana compartilhar.

Não sei porque surgiu um arquivo com o nome "?0?@@?i@8?@" no meu servidor de testes.

[root@odin]# ls -lrht
-rw-r--r--   1 root   root        0 Jul 12 09:58 ?0?@@?i@8?@

Ok, vamos excluir esse arquivo:

rm -f ?0?@@?i@8?@
rm -f "?0?@@?i@8?@"

Nos dois casos recebi o erro que o nome do arquivo era inválido.

Então, dei uma pesquisada e achei o tal do "--". Ai ficou fácil, primeiro renomeei o arquivo problemático e depois exclui.

-- Renomear
[root@odin]# mv -- ?0?@@?i@8?@ tt

[root@odin]# ll
-rw-r--r--   1 root   root        0 Jul 12 09:58 tt

-- Excluir
[root@odin]# rm tt
rm: remove regular empty file `tt'? y


E tudo foi resolvido.

Então é isso. Só uma dica que pode ser útil um dia.

Abraço
Mario

segunda-feira, 10 de julho de 2017

IPS - Incident Package Service

Olá pessoal.

Hoje me deparei com um erro ORA-07445. Após algumas pesquisas no MOS e como não havia achado nada relacionada decidi abrir um SR.

Um dos arquivos solicitados para abertura era o zip gerado pelo IPS (Incident Package Service).

O IPS é uma extensão do "Automatic Diagnostic Repository (ADR)", ou seja, ele é gerado pela ferramenta ADRCI.

Bom, então vamos ao que interessa. São várias as formas de usar o IPS. Abaixo vou colocar duas ou três.


Vamos nos conectar ao ADRCI e exibir os nossos homes:
adrci>  show homes
ADR Homes:
diag/asm/+asm/+ASM1
diag/rdbms/mv/mv1

Vamos setar o nosso homepath:
adrci> set homepath diag/rdbms/mv/mv1

adrci> show homes
ADR Homes:
diag/rdbms/mv/mv1

Exibir os incidentes do ambiente:

adrci> show incidents


Vamos agora criar o pacote de arquivos pelo INCIDENT_ID.

adrci> ips pack incident 1233454 in /tmp
Generated package 6 in file /tmp/ORA7445pr_20170710095409_COM_1.zip, mode complete

$ ls -lrht /tmp/
-rw-r--r--  1 oracle       oinstall     2.1M Jul 10 09:54 ORA7445pr_20170710095409_COM_1.zip

É isso, podemos mandar esse arquivo para o MOS.

Temos várias outras formas de criação, como por exemplo, pelo PROBLEM_ID:

Primeiro vamos identificar o PROBLEM_ID:
adrci> show incident -mode brief -p "incident_id=1233454"



Agora, é só criar o pacote:
adrci> ips create package problem 5 correlate all
Created package 11 based on problem id 5, correlation level all

E gerar o zip:
adrci> ips generate package 11 in "/tmp"
Generated package 11 in file /tmp/ORA7445pr_20170710103222_COM_1.zip, mode complete

$ ls -lrht /tmp/ORA7445pr_20170710103222_COM_1.zip
-rw-r--r-- 1 oracle oinstall 12M Jul 10 10:33 /tmp/ORA7445pr_20170710103222_COM_1.zip

Para listar os incidentes1 que fazem parte do pacote, basta executar:
adrci> ips show incidents package 11



Ou ainda, listar os arquivos que fazem parte do pacote.   
adrci> IPS SHOW FILES PACKAGE 11





Podemos também gerar por um período de tempo, por exemplo:

adrci> IPS CREATE PACKAGE TIME '2017-07-10 06:19:41.614000 -03:00' to '2017-07-10 09:23:07.109000 -03:00'
Created package 9 based on time range 2017-07-10 06:19:41.614000 -03:00 to 2017-07-10 09:23:07.109000 -03:00, correlation level typical

adrci> ips generate package 9 in /tmp
Generated package 9 in file /tmp/ORA7445pr_20170710100817_COM_1.zip, mode complete

$ ls -lrht /tmp/ORA7445pr_20170710100817_COM_1.zip
-rw-r--r-- 1 oracle oinstall 11M Jul 10 10:08 /tmp/ORA7445pr_20170710100817_COM_1.zip


Para verificar todas as opções, basta acessar o help;

adrci> help ips

 HELP IPS [topic]
   Available Topics:
        ADD
        ADD FILE
        ADD NEW INCIDENTS
        CHECK REMOTE KEYS
        COPY IN FILE
        COPY OUT FILE
        CREATE PACKAGE
        DELETE PACKAGE
        FINALIZE PACKAGE
        GENERATE PACKAGE
        GET MANIFEST
        GET METADATA
        GET REMOTE KEYS
        PACK
        REMOVE
        REMOVE FILE
        SET CONFIGURATION
        SHOW CONFIGURATION
        SHOW FILES
        SHOW INCIDENTS
        SHOW PACKAGE
        UNPACK FILE
        UNPACK PACKAGE
        USE REMOTE KEYS

E para verificar as configurações atuais do IPS:

adrci> ips  SHOW CONFIGURATION





Então é isso pessoal. Uma dica rápida mas que ajuda bastante no momento da abertura do SR.

Mais informações: ADRCI

Abraço
Mario

sábado, 8 de julho de 2017

Trigger de logon para ativar trace

Olá pessoal.

Tive uma necessidade a um tempo atrás de ativar um trace em uma detereminada sessão que viesse de um programa específico.

Coisa simples, então vou deixar documentado aqui para quem precisar a trigger de logon que eu usei.

create or replace trigger sys.LOGON_TRACE
      after logon on database
DECLARE
      v_username VARCHAR2(70);
      v_program  VARCHAR2(70);
BEGIN
      SELECT LOWER(USERNAME),
                      LOWER(PROGRAM)
      INTO  v_username,
                 v_program
      FROM sys.v_$session
      WHERE
                   sid = SYS_CONTEXT('USERENV', 'SID');

  -- if ora_login_user = 'MARIO' then   -- Se quiser utilizar a trigger em determinados logins
  IF (v_program = 'q_sender.exe' OR v_program='sqlplusw.exe')
  THEN
        EXECUTE IMMEDIATE 'ALTER SESSION SET sql_trace=TRUE';
        EXECUTE IMMEDIATE 'alter session set timed_statistics=true';
        EXECUTE IMMEDIATE 'alter session set max_dump_file_size=unlimited';
EXECUTE IMMEDIATE 'alter session set events=''10046 trace name context forever, level 12''';
  END IF;
END LOGON_TRACE;
/

Então é isso pessoal, simples e objetivo. 

Abraço
Mario

terça-feira, 30 de maio de 2017

Artigo para o OTN - Criação e configuração de ambiente Oracle Cloud Service: Database Cloud Service – Parte 1

Olá pessoal...
Mais um artigo publicado no OTN. Dessa vez falando sobre o Cloud Oracle, mais especificamente sobre o Database Cloud Service.


Se você não leu os outros, abaixo estão os links para facilitar.
Voltando ao artigo atual, não é de hoje que vemos crescer a importância das operações em cloud como um todo. É claro que os bancos de dados não ficariam de fora dessa evolução.
É cada vez mais comum ouvirmos falar termos como PaaS (Platform as a Service), IaaS (Infrastructure as a Service), SaaS (Software as a Service), entre outras.
Neste artigo procuro passar o passo a passo para a criação de um ambiente em Database Cloud Service, um dos produtos oferecidos no PaaS.
Artigo com a revisão do grande Alex Zaballa.

Então é isso pessoal, espero que gostem.
Abraço
Mario

terça-feira, 6 de dezembro de 2016

Utilizando o SQL Tuning Advisor (DBMS_SQLTUNE)

Fala pessoal...

Hoje fazendo uns acertos aqui no meu ambiente, precisei utilizar o SQL Tuning Advisor.

Ele é bem simples, mas é sempre bom lembrar que precisamos ter o "Diagnostic+Tunig" devidamente licenciado e habilitado.

Sendo assim, abaixo segue um exemplo da utilização.


-- Executar o ADDM. 

@?/rdbms/admin/addmrpt.sql

Na verdade baseado no ADDM identifiquei as necessidades iniciais tendo em vista que é um ambiente que não administro a muito tempo. Sendo assim, não é obrigatório executar esse relatório.


-- Create task
DECLARE
  l_sql_tune_task_id  VARCHAR2(100);
BEGIN
  l_sql_tune_task_id := DBMS_SQLTUNE.create_tuning_task (
         begin_snap  => 34932,           -- Snap inicial
        end_snap    => 35220,           -- Snap final
        sql_id      => 'cyb0csh3g3vxa',   -- SQL Id
        scope       => DBMS_SQLTUNE.scope_comprehensive,
        time_limit  => 3600,            -- Execução em seg
        task_name   => 'cyb0csh3g3vxa_AWR2_tuning_task', 
        description => 'Task: cyb0csh3g3vxa');
   DBMS_OUTPUT.put_line('l_sql_tune_task_id: ' || l_sql_tune_task_id);
END;
/

No exemplo acima utilizei uma período do meu AWR para limitar a minha task. Se não quiser utilizar os snaps, basta excluir essas duas linhas.

-- Execute task
   EXEC DBMS_SQLTUNE.execute_tuning_task(
           task_name => 'cyb0csh3g3vxa_AWR2_tuning_task');


-- Verify status
   SELECT 
task_id, 
task_name, 
status
   FROM 
dba_advisor_log
   WHERE 
task_name like '%cyb0csh3g3vxa%'
   order by 
task_id;

  TASK_ID  TASK_NAME                      STATUS
---------- ------------------------------ -----------
    154921 cyb0csh3g3vxa_AWR2_tuning_task COMPLETED

-- Verify recomendations 
SET LONG 10000;
SET PAGESIZE 1000
SET LINESIZE 200
   SELECT 
      DBMS_SQLTUNE.report_tuning_task(
      'cyb0csh3g3vxa_AWR2_tuning_task'
      ) AS recommendations 
   FROM 
      dual;

Nesse momento será apresentado uma relatório com as recomendações de melhorias.

Example:

RECOMMENDATIONS
--------------------------------------------------------------------------------
GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name   : cyb0csh3g3vxa_AWR2_tuning_task
Tuning Task Owner  : SYS
Workload Type      : Single SQL Statement
Scope              : COMPREHENSIVE
Time Limit(seconds): 1200
Completion Status  : COMPLETED
Started at         : 12/06/2016 06:24:20
Completed at       : 12/06/2016 06:24:22

-------------------------------------------------------------------------------
Schema Name: PRD1_GC_APP
SQL ID     : cyb0csh3g3vxa
SQL Text   : select tbatchjobs0_.SUB_ID as SUB1_34_, tbatchjobs0_.RUN_ID as
             RUN2_34_, tbatchjobs0_.PROCESS_TYPE as PROCESS3_34_,
             tbatchjobs0_.PIECE_ID as PIECE4_34_, tbatchjobs0_.CREATE_TIME as
             CREATE5_34_, tbatchjobs0_.START_TIME as START6_34_,
             tbatchjobs0_.FINISH_TIME as FINISH7_34_, tbatchjobs0_.AGENT_ID
             as AGENT8_34_, tbatchjobs0_.THREAD_ID as THREAD9_34_,
             tbatchjobs0_.STATUS as STATUS34_, tbatchjobs0_.RESULT_INFO as
             RESULT11_34_ from T_BATCH_JOB_SUB tbatchjobs0_ where
             tbatchjobs0_.AGENT_ID=1 and tbatchjobs0_.STATUS<>107 and
             tbatchjobs0_.STATUS<>105 and tbatchjobs0_.STATUS<>223 and
             tbatchjobs0_.STATUS<>106 order by tbatchjobs0_.SUB_ID

-------------------------------------------------------------------------------
FINDINGS SECTION (3 findings)
-------------------------------------------------------------------------------

1- Restructure SQL finding (see plan 1 in explain plans section)
----------------------------------------------------------------
  Predicate "TBATCHJOBS0_"."STATUS"<>107 used at line ID 2 of the execution
  plan is an inequality condition on indexed column "STATUS". This inequality
  condition prevents the optimizer from selecting indices  on table
  "PRD1_GC"."T_BATCH_JOB_SUB".

  Recommendation
  --------------
  - Rewrite the predicate into an equivalent form to take advantage of
    indices.

2- Statistics Finding
---------------------
  Optimizer statistics for table "PRD1_GS"."T_CTS_BCP_GL_FEE" and its indices
  are stale.

  Recommendation
  --------------
  - Consider collecting optimizer statistics for this table.
    execute dbms_stats.gather_table_stats(
        ownname => 'PRD1_GS', 
        tabname => 'T_CTS_BCP_GL_FEE', 
        estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, 
        method_opt => 'FOR ALL COLUMNS SIZE AUTO');

  Rationale
  ---------
    The optimizer requires up-to-date statistics for the table in order to
    select a good execution plan.

3- SQL Profile Finding (see explain plans section below)
--------------------------------------------------------
  A potentially better execution plan was found for this statement.

  Recommendation (estimated benefit: 48.56%)
  ------------------------------------------
  - Consider accepting the recommended SQL profile.
    execute dbms_sqltune.accept_sql_profile(
task_name => 'cyb0csh3g3vxa_AWR2_tuning_task', 
task_owner => 'SYS', 
replace => TRUE);

-------------------------------------------------------------------------------
EXPLAIN PLANS SECTION
-------------------------------------------------------------------------------

1- Original
-----------
Plan hash value: 4019928224

--------------------------------------------------------------------------------------
| Id  | Operation          | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                 |  7983 |   350K|  2063   (3)| 00:00:21 |
|   1 |  SORT ORDER BY     |                 |  7983 |   350K|  2063   (3)| 00:00:21 |
|*  2 |   TABLE ACCESS FULL| T_BATCH_JOB_SUB |  7983 |   350K|  2061   (3)| 00:00:21 |
--------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("TBATCHJOBS0_"."STATUS"<>107 AND "TBATCHJOBS0_"."STATUS"<>105
              AND "TBATCHJOBS0_"."STATUS"<>106 AND "TBATCHJOBS0_"."AGENT_ID"=1 AND
              "TBATCHJOBS0_"."STATUS"<>223)
-------------------------------------------------------------------------------

É isso ai pessoal, bem simples e objetivo. 

Agora é só analisar essas sugestões e lembrar-se que o advisor fornece sugestões de melhorias e não uma receita de bolo pronta e infalível. 

Portanto, o seu resultado e sua utilização devem ser analisados e testados com muito cuidado.

Abraço
Mario

Postagem em destaque

[ORACLE] Useful scripts for the day-to-day life of a DBA (Part 3) - System metrics

Hello everyone.   Hope you're doing well! As I said here , I've created a repository on GITHUB to share some scripts that I like t...