Monitorando operações de uma tabela atraves da DBA_TAB_MODIFICATIONS

Alguns dias atrás estava precisando monitorar uma tabela da aplicação do cliente para registrar a quantidade de operações DML que ela estava sofrendo.

Após algumas buscas encontrei a tabela do Oracle DBA_TAB_MODIFICATIONS que conforme documentação registra as modificações sofridas nas tabelas do banco de dados após a ultima coleta de estatisticas, ou seja, a cada nova coleta de estatistica sobre a tabela seus registros na DBA_TAB_MODIFICATIONS são descartados(zerados!).

SQL> desc DBA_TAB_MODIFICATIONS
 Nome                                      Nulo?    Tipo
 ----------------------------------------- -------- ----------------------------
 TABLE_OWNER                                        VARCHAR2(30)
 TABLE_NAME                                         VARCHAR2(30)
 PARTITION_NAME                                     VARCHAR2(30)
 SUBPARTITION_NAME                                  VARCHAR2(30)
 INSERTS                                            NUMBER
 UPDATES                                            NUMBER
 DELETES                                            NUMBER
 TIMESTAMP                                          DATE
 TRUNCATED                                          VARCHAR2(3)
 DROP_SEGMENTS                                      NUMBER

De qualquer forma, minha necessidade era identificar as operações DML sofridas na tabela X no período de 1 hora.

Como o Oracle não atualiza estas informações constantemente, podemos utilizar a procedure FLUSH_DATABASE_MONITORING para baixar as informações de monitoramento da memória para as tabelas de dicionário (*_TAB_MODIFICATIONS, *_TAB_STATISTICS e *_IND_STATISTICS).

SQL> exec DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO;

Procedimento PL/SQL concluido com sucesso.

SQL> select to_char(TIMESTAMP,'dd/mm/yyyy hh24:mi') HORARIO, UPDATES from DBA_TAB_MODIFICATIONS where TABLE_OWNER='PRODUCAO' and TABLE_NAME='X';

HORARIO             UPDATES
---------------- ----------
24/09/2012 10:00     127014

Observem que realizei um flush para atualizar as informações e posteriormente obter a quantidade de UPDATES realizados até o momento.

Depois de 1 hora realizei o mesmo procedimento, logo,  318558 – 127014 = 191.544 UPDATES registrados!

SQL> exec DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO;

Procedimento PL/SQL concluido com sucesso.

HORARIO             UPDATES
---------------- ----------
24/09/2012 11:00     318558

Vamos fazer alguns testes para melhor evidenciar o monitoramento registrado pelo Oracle na DBA_TAB_MODIFICATIONS:

SQL> create table teste.teste (cod number);

Tabela criada.

SQL> select to_char(TIMESTAMP,'dd/mm/yyyy hh24:mi') HORARIO, INSERTS, UPDATES, DELETES from dba_tab_modifications where TABLE_OWNER='TESTE' and TABLE_NAME='TESTE';

n?o ha linhas selecionadas

Observem que ainda não temos nada coletado para a tabela TESTE! Vamos então adicionar um registro:

SQL> insert into teste.teste values (1);

1 linha criada.

SQL> commit;

Commit concluido.

SQL> select to_char(TIMESTAMP,'dd/mm/yyyy hh24:mi') HORARIO, INSERTS, UPDATES, DELETES from dba_tab_modifications where TABLE_OWNER='TESTE' and TABLE_NAME='TESTE';

n?o ha linhas selecionadas

Vamos baixar os registros de monitoramento da memória e realizar novamente a consulta:

SQL> exec DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO;

Procedimento PL/SQL concluido com sucesso.

SQL> select to_char(TIMESTAMP,'dd/mm/yyyy hh24:mi') HORARIO, INSERTS, UPDATES, DELETES from dba_tab_modifications where TABLE_OWNER='TESTE' and TABLE_NAME='TESTE';

HORARIO             INSERTS    UPDATES    DELETES
---------------- ---------- ---------- ----------
24/09/2012 12:02          1          0          0

Um teste com updates:

SQL> update teste.teste set cod=2 where cod=1;

1 linha atualizada.

SQL>  update teste.teste set cod=1 where cod=2;

1 linha atualizada.

SQL> commit;

Commit concluido.

SQL> exec DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO;

Procedimento PL/SQL concluido com sucesso.

SQL> select to_char(TIMESTAMP,'dd/mm/yyyy hh24:mi') HORARIO, INSERTS, UPDATES, DELETES from dba_tab_modifications where TABLE_OWNER='TESTE' and TABLE_NAME='TESTE';

HORARIO             INSERTS    UPDATES    DELETES
---------------- ---------- ---------- ----------
24/09/2012 12:03          1          2          0

Agora se executarmos uma coleta de estatisticas na tabela, como já mencionado, todos os registros são zerados!

SQL> execute DBMS_STATS.GATHER_TABLE_STATS (ownname => 'TESTE',TABNAME =>'TESTE',estimate_percent => 100,method_opt => 'FOR ALL COLUMNS SIZE AUTO',degree => null,granularity => 'ALL', cascade => TRUE);

Procedimento PL/SQL concluido com sucesso.

SQL> select to_char(TIMESTAMP,'dd/mm/yyyy hh24:mi') HORARIO, INSERTS, UPDATES, DELETES from dba_tab_modifications where TABLE_OWNER='TESTE' and TABLE_NAME='TESTE';

n?o ha linhas selecionadas

Então fica a dica de como podemos monitorar algumas operações sobre uma tabela. Foi muito útil para mim e talvez seja para vocês!

OBS: Para a execução do DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO é necessário o privilégio de ANALYZE ANY

Referências:

http://docs.oracle.com/cd/B19306_01/server.102/b14237/statviews_4149.htm http://docs.oracle.com/cd/E11882_01/appdev.112/e25788/d_stats.htm#i1036624

%name Monitorando operações de uma tabela atraves da DBA TAB MODIFICATIONS

Autor: Anderson Graf

Bacharel em Sistemas de Informação e MBA em Gestão de Banco de Dados Oracle. Entusiasta da tecnologia Oracle, ACE Associate ♠, autor em vários blogs e OTN. Consultor Oracle Senior na Exímio Soluções em TI

Envolvido em soluções de:
– Implementação, migração, gerenciamento e suporte a produtos Oracle, multiplataforma
– Monitoramento de ambientes 24×7
– Backup e Recovery
– Performance e Tuning
– Alta disponibilidade (HA) – RAC, Data Guard
– EM database/grid/cloud control
– Particionamento & Advanced Compression
– Oracle Engineered Systems – ODA, Exadata

Blog pessoal: http://www.andersondba.com.br
Articulista na Oracle Technology Network (OTN) – https://goo.gl/99R6yW
ACE Associate – https://goo.gl/MBB51b
Articulista GPO – http://profissionaloracle.com.br

Comentários

3 respostas a “Monitorando operações de uma tabela atraves da DBA_TAB_MODIFICATIONS”

  1. Avatar de rubinho.santos
    rubinho.santos

    Ótimo post amigo!

    Estava há algumas semanas de como buscar informações deste tipo no Oracle! Muito obrigado!

    Só duas perguntinhas:

    Tem como ter as informações de leitura também?
    Esta informações é somente para a sessão atual ou para todas as sessões do banco? Se for para todos, tem como configurar somente ser da sessão atual?

    Abs,
    Rubens Dos Santos Filho

    1. Avatar de Anderson Graf (Admin)

      Ola Rubens,

      Na DBA_* você verá as informações de todas as sessões, para visualizar apenas da sua sessão utilize a USER_*

      Para coletar os select você pode utilizar FGA (Fine Grained Auditing).

      Abs.

  2. Muito bom artigo!

    Abraço.

    Att,
    Ed Carlos Schneider

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Connect with Facebook