Buenas a todos.
Neste post vou ensinar como usar o LogMiner para a visualização do conteúdo de RedoLogs e ArchiveLogs.
Vamos primeiro nos ambientar.
Imagine que seu banco de dados está gerando muito archivelog e a partição disponível está enchendo constantemente, ou imagine que seu I/O subiu repentinamente em uma determinada parte do dia e você gostaria de saber o que houve.
Nestes casos, se voce não achou nada na boa e velha V$SQL, você poderá usar o LogMiner.
LogMiner é um pacote com um conjunto de procedures que analisam arquivos de redo e archivedlogs.
Depois de analisado os arquivos, uma tabela é criada com as informações das queries.
Chega de lero lero, vamos à ação.
( para que este tutorial fique mais completo, vou mostrar como pegar um archivedlog de uma base de dados e abrí-lo em outra base de dados. Afinal, você não vai ficar analisando archives em produção, né? )
Passo 1, gerar dicionario de dados no servidor produtivo
Apesar de estranho, precisaremos gerar o dicionário de dados do servidor produtivo para que os archives possam ser lidos no nosso servidor de teste.
Não se preocupe, a geração dos dicionários de dados não vai prejudicar a performance do servidor. ( não vai prejudicar perceptívelmente )
Se você não pegar os dicionários de dados do servidor produtivo e tentar ler os archives diretamente, provavelmente vai se deparar com erros como ORA-01295 ou ORA-01294.
No servidor produtivo execute:
SQL>EXECUTE DBMS_LOGMNR_D.BUILD(OPTIONS=> DBMS_LOGMNR_D.STORE_IN_REDO_LOGS); PL/SQL procedure successfully completed.
Após executar este comando o Oracle vai gerar um archivedlog com os dados do dicionário.
Para descobrir qual archive pegar, execute esta SQL:
SQL> SELECT NAME FROM V$ARCHIVED_LOG WHERE DICTIONARY_BEGIN='YES'; NAME ---------------------------------------------------------------------------------- /u01/app/oracle/admin/archs/3_6937_703020779.dbf
Passo 2, obter o archived log
Bem, neste passo eu copiei os archivedlogs de um servidor produtivo para minha maquina virtual.
Ahhh, por consequência eu copiei o archive com o dicionário de dados junto!
scp 10.0.0.23:/u01/app/oracle/admin/archs/*.dbf /oracle/MEUS_ARCHIVES
Passo 3, carregando arquivos para o LogMiner.
Agora que já temos o dicionário de dados, fica fácil usar o LogMiner!
Só carregarmos os ArchivedLogs usando a procedure ADD_LOGFILE e iniciarmos o LogMiner com START_LOGMNR…
EXECUTE DBMS_LOGMNR.ADD_LOGFILE( LOGFILENAME => '/oracle/MEUS_ARCHIVES/1_64530_703020779.dbf', OPTIONS => DBMS_LOGMNR.ADDFILE); EXECUTE DBMS_LOGMNR.ADD_LOGFILE( LOGFILENAME => '/oracle/MEUS_ARCHIVES/1_64531_703020779.dbf', OPTIONS => DBMS_LOGMNR.ADDFILE); EXECUTE DBMS_LOGMNR.ADD_LOGFILE( LOGFILENAME => '/oracle/MEUS_ARCHIVES/1_64532_703020779.dbf', OPTIONS => DBMS_LOGMNR.ADDFILE); EXECUTE DBMS_LOGMNR.ADD_LOGFILE( LOGFILENAME => '/oracle/MEUS_ARCHIVES/1_64533_703020779.dbf', OPTIONS => DBMS_LOGMNR.ADDFILE); EXECUTE DBMS_LOGMNR.ADD_LOGFILE( LOGFILENAME => '/oracle/MEUS_ARCHIVES/1_64534_703020779.dbf', OPTIONS => DBMS_LOGMNR.ADDFILE); EXECUTE DBMS_LOGMNR.ADD_LOGFILE( LOGFILENAME => '/oracle/MEUS_ARCHIVES/1_64535_703020779.dbf', OPTIONS => DBMS_LOGMNR.ADDFILE); EXECUTE DBMS_LOGMNR.ADD_LOGFILE( LOGFILENAME => '/oracle/MEUS_ARCHIVES/1_64536_703020779.dbf', OPTIONS => DBMS_LOGMNR.ADDFILE); EXECUTE DBMS_LOGMNR.ADD_LOGFILE( LOGFILENAME => '/oracle/MEUS_ARCHIVES/3_6937_703020779.dbf', OPTIONS => DBMS_LOGMNR.ADDFILE);
Depois de carregar os arquivos vamos iniciar a “Mineração” heehhehehe
EXECUTE DBMS_LOGMNR.START_LOGMNR(OPTIONS => DBMS_LOGMNR.DICT_FROM_REDO_LOGS);
Passo 4, analisando o resultado do LogMiner…
Depois de esperar uma eternidade para o LogMiner terminar a análise, chegou a hora da tão esperada pesquisa das queries!
SELECT * FROM V$LOGMNR_CONTENTS;
Caso queira, eu uso a seguinte query que abrevia muito o resultado 🙂
set linesize 200; set pagesize 400; col REDO format a30; col UNDO format a30; col TABLE_SPACE format a20; col USERNAME format a20; SELECT USERNAME, TABLE_SPACE, SUBSTR( SQL_REDO, 0, INSTR( SQL_REDO , '"', 1,4)) REDO, SUBSTR( SQL_UNDO, 0, INSTR( SQL_UNDO , '"', 1,4)) UNDO FROM V$LOGMNR_CONTENTS WHERE SQL_UNDO IS NOT NULL;
Aeee, agora você sabe o que está “Rolando” em seus archives!
Grande abraço!