Conteúdo voltado para banco de dados Oracle e SQL Server

Author Description

Leonardo Pedroso

Leonardo Pedroso, é administrador de banco de dados, possui amplo conhecimento em Oracle 11g e 12c, com atuação em empresas de telecomunicações, bancos, seguradoras e órgãos do governo brasileiro prestando serviços especializados em banco de dados. Atua ativamente em comunidades técnicas através de fóruns, eventos, blog e palestras.

As colunas que armazenam datas e horas no Oracle, pode default retornam apenas a DATA no formato DD/MM/YYYY, sendo que DD = Dia, MM = Mês e YYYY = Ano!

No exemplo abaixo temos um select que retorna a data do sistema:

SELECT TO_CHAR(SYSDATE) FROM DUAL;
14/10/18

Para extrair a data e hora desse campo, é preciso usar a função TO_CHAR passando o parâmetro de data e hora, conforme comando abaixo:

SELECT TO_CHAR(SYSDATE,'DD/MM/YYYY HH:MI:SS') FROM DUAL;
14/10/2018 11:19:32

E se preferir o formato de 24 horas, basta ajustar conforme abaixo:

SELECT TO_CHAR(SYSDATE,'DD/MM/YYYY HH24:MI:SS') FROM DUAL;
14/10/2018 23:19:49

Sabendo como funciona o TO_CHAR, você consegue aplicar esse comando em qualquer coluna de data nas suas tabelas, basta trocar o SYSDATE pelo nome da coluna na tabela e executar o comando.

Algumas operações de tecnologias podem ser paralelizadas utilizando mais CPUs para processar determinadas tarefas, e no banco de dados não é diferente. A opção PARALLEL X, onde X é a quantidade de cores a ser utilizada permite dividir a consulta em pequenos pedaços fazendo com que cada processador execute parte da query.

No exemplo abaixo estou paralelizando a consulta entre 20 cpus com o comando PARALLEL 20 e suspendi a geração de REDO LOG com o NOLLOGGING. Essa operação é lenta, pois está comprimindo uma tabela de 500GB e movendo para outra tablespace, a TD_MOVELOB:

ALTER TABLE GALOMG.TB_LOG COMPRESS FOR OLTP;
ALTER TABLE GALOMG.TB_LOG MOVE TABLESPACE TD_MOVELOB NOLOGGING PARALLEL 20;

Para checar se a consulta está paralelizada, basta executar o select abaixo na LONGOPS que trará uma linha para cada processo dividido:

SELECT inst_id,sid, serial#, opname, username,start_time,last_update_time,
round(time_remaining/60,2) "REMAIN MINS", round(elapsed_seconds/60,2) "ELAPSED MINS", round((time_remaining+elapsed_seconds)/60,2) "TOTAL MINS", 
ROUND(SOFAR/TOTALWORK*100,2) "%_COMPLETE", message
FROM gv$session_longops 
WHERE TOTALWORK != 0 AND sofar<>totalwork AND time_remaining > 0;

Abaixo o resultado da query, onde msotra que cada pedaço da query possui um SID diferente, mesmo que a tabela seja a mesma: GALOMG.TB_LOG !

Basta executar a query várias vezes para consultar o tempo que cada pedaço da query está sendo executado.

Olá pessoal,
hoje vou passar algumas dicas para desligar corretamente seu ambiente do Oracle RAC. Precisei fazer uma manutenção em apenas 1 dos nós e as vezes temos dúvidas de qual procedimento usar, qual é melhor, mais rápido, etc.

Há duas maneiras legais de para uma instância que são utilizando os comando SRVCTL (servercontrol) ou o CRSCTL (clustercontrol). A diferença básica de um para o outro é que o ClusterControl vai parar a instância do ASM automaticamente e deve ser executado como ROOT.

Maos á obra !

Utilizando o SRVCTL teremos as seguintes opções:

srvctl stop instance -d database -i instancia -o abort
srvctl start instance -d database -i instance
srvctl status database -d database

srvctl stop asm -node hostname -stopoption IMMEDIATE
srvctl start asm -node hostname
srvctl status asm

Utilizando o CRSCTL teremos as seguintes opções:

crsctl stop crs
crsctl start crs
crsctl stat res -t init
crsstat

Com esses comandos acima você consegue facilmente parar e subir os serviços do Oracle

Um recurso pouco utilizado, porém muito útil no Oracle Database é setar informações da aplicação nas views de sistema V$SESSION / GV$SESSION. É comum alguma consulta estar impactando o ambiente e as informações contidas nas views de sistema e as informações não serem tão precisas a ponto de ir direto no problema. É possível, por exemplo, colocar o nome da aplicação ou da etapa do processo em que está sendo executado, e com isso você saberia se o processo que está impactando é o início ou o fim do processo.

Mãos á obra ..

Abra uma query no Oracle e execute a query abaixo. Nesse caso, eu estou informando que minha aplicação é o controle de estoque e que o procedimento que está sendo executado é a baixa de produtos devolvidos:


exec dbms_application_info.set_module(module_name => 'Controle de Estoque',action_name => 'Baixa dos produtos devolvidos');

PL/SQL procedure successfully completed.

Após execução do pacote acima, a query na v$session será populada com os dados:


select osuser, module, action from v$session where action is not null

noraldino <strong>Controle de Estoque Baixa dos produtos devolvidos</strong>


As informações contidas no pacote podem ser customizadas de acordo com sua necessidade. É recomendado que esse procedimento seja repassado ao time de desenvolvimento para que seja incluído esse pacote antes das execuções de procedimentos, pois na hora do troubleshooting essas informações podem ser muito úteis e poupar muito tempo dos envolvidos.

Enjoy !

Esse erro comum ocorre quando você tenta executar uma operação em uma tabela que foi alterada e a transação ainda está pendente. No nosso caso, estávamos tentando truncar uma tabela de B.I. e o erro era retornado instantaneamente: ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired !

O select abaixo ajudou a identificar a causa raiz, ele lista quais sessões estão aguardando commit ou roolback. No meu caso foi uma transação aberta há mais de 30 dias e, alinhando com a área, matamos a sessão:

SELECT O.OBJECT_NAME, S.SID, S.SERIAL#, P.SPID, S.PROGRAM,S.USERNAME,
S.MACHINE,S.PORT , S.LOGON_TIME,SQ.SQL_FULLTEXT 
FROM V$LOCKED_OBJECT L, DBA_OBJECTS O, V$SESSION S, 
V$PROCESS P, V$SQL SQ 
WHERE L.OBJECT_ID = O.OBJECT_ID 
AND L.SESSION_ID = S.SID AND S.PADDR = P.ADDR 
AND S.SQL_ADDRESS = SQ.ADDRESS;

Dica: Em ambiente Oracle RAC troque o V$ por GV$ !

Faça bom uso do script.

Criei um banco do zero, movi os dados da instância anterior para o mesmo e fui conectar no RMAN/CATALOGO para ver se estava tudo ok. No exato momento recebi o segunte erro:

RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of crosscheck command at 07/18/2018 15:15:45
RMAN-12010: automatic channel allocation initialization failed
RMAN-06004: ORACLE error from recovery catalog database: RMAN-20001: target database not found in recovery catalog

Esse erro acontece porque o banco de dados criado não foi registrado no catálogo. Um comando extremamente simples resolve o problema, basta registrar o database no catálogo : )

Com o usuário Oracle e as variáveis do banco setadas, execute o seguinte comando para conectar no banco de dados:

rman target / catalog rman/mypassword@repositorio;

A seguinte mensagem de sucesso será apresentada na tela:

Recovery Manager: Release 12.1.0.1.0 - Production on Wed Jul 18 15:15:39 2018

Copyright (c) 1982, 2013, Oracle and/or its affiliates.  All rights reserved.

connected to target database: GALOMINEIRO (DBID=131313131313)
connected to recovery catalog database

Após conectar, basta digitar o comando register database para que o banco de dados seja registrado no catálogo:

RMAN> register database;

E acompanhe a execução do procedimento:

database registered in recovery catalog
starting full resync of recovery catalog
full resync complete

Pronto! A partir desse momento o banco de dados estará devidamente registrado no catálogo. Basta conectar no catálogo e rodar o select abaixo para garantir que o banco está de fato no catalogo:

select * from rc_database where name = 'VS24'
65432165	50023546	131313131313	GALOMINEIRO	654984613565	18/07/18

Há poucos dias atrás precisei instalar os agentes do Oracle Cloud Control 13c em 3 servidores de produção, porém ele dava o erro em que a porta xxx estava sendo usada. Verifiquei que já haviam outros agentes rodando nas máquinas e eram referentes á versões anteriores, para que os novos agentes fossem instalados, esse antigos deveriam ser removidos.

Mãos á obra:

Localize o agent_home da instalação anterior e exporta a variável AGENT_HOME. No meu caso ela estava em /u01/app/oracle/agent12c/core/12.1.0.4.0:


export AGENT_HOME=/u01/app/oracle/agent12c/core/12.1.0.4.0

Em seguida execute o comando abaixo para remoção do agente:


$perl $AGENT_HOME/sysman/install/AgentDeinstall.pl -agentHome $AGENT_HOME

Após executar o código acima, a mensagem abaixo informará na tela o progresso da desinstalação:

** Esse processo só retira o agente do servidor, para retirar do Oracle Cloud Control deverá ser feita uma operação á parte.
Agent Oracle Home: /u01/app/oracle/agent12c/core/12.1.0.4.0

agentHome = /u01/app/oracle/agent12c/core/12.1.0.4.0

NOTE: The agent base directory: /u01/app/oracle/agent12c will be removed after successful deinstallation of agent home.

DetachHome Command executed:/u01/app/oracle/agent12c/core/12.1.0.4.0/oui/bin/runInstaller -detachHome -force -depHomesOnly -silent ORACLE_HOME=/u01/app/oracle/agent12c/core/12.1.0.4.0 -waitForCompletion -invPtrLoc /u01/app/oracle/agent12c/core/12.1.0.4.0/oraInst.loc
Iniciando Oracle Universal Installer…

Verificando espaço de swap: deve ser superior a 500 MB. 99999 MB Reais Passado
The inventory pointer is located at /u01/app/oracle/agent12c/core/12.1.0.4.0/oraInst.loc
‘DetachHome’ bem-sucedido.
Iniciando Oracle Universal Installer…

Verificando espaço de swap: deve ser superior a 500 MB. 99999 MB Reais Passado
The inventory pointer is located at /u01/app/oracle/agent12c/core/12.1.0.4.0/oraInst.loc
Não foi possível atualizar o Oracle home ‘/u01/app/oracle/agent12c/sbin’ pois ele não existe.

Deinstall Command executed:/u01/app/oracle/agent12c/core/12.1.0.4.0/oui/bin/runInstaller -deinstall -silent “REMOVE_HOMES={/u01/app/oracle/agent12c/core/12.1.0.4.0}” -waitForCompletion -removeAllFiles -invPtrLoc /u01/app/oracle/agent12c/core/12.1.0.4.0/oraInst.loc
Iniciando Oracle Universal Installer…

Verificando espaço de swap: deve ser superior a 500 MB. 99999 MB Reais Passado
Preparando para iniciar o Oracle Universal Installer de /tmp/OraInstall2018-06-28_10-38-07AM. Aguarde …Oracle Universal Installer, Versão 11.1.0.12.0 Produção
Copyright (C) 1999, 2014, Oracle. Todos os direitos reservados.

Iniciando desinstalação

Desinstalação em andamento (Quinta-feira, 28 de Junho de 2018 10h38min12s BRT)
O assistente de configuração “Agent Deinstall Assistant” foi bem-sucedido
……………………………………………………… 100% Concluído.

Desinstalação bem-sucedida

Fim das fases de instalação.(Quinta-feira, 28 de Junho de 2018 10h38min20s BRT)
Fim das desinstalações
Verifique “/u01/app/oraInventory/logs/silentInstall2018-06-28_10-38-07AM.log” para obter mais detalhes.
cannot fetch initial working directory: Arquivo ou diretório não encontrado at /u01/app/oracle/agent12c/core/12.1.0.4.0/sysman/install/AgentDeinstall.pl line 303
cannot fetch initial working directory: Arquivo ou diretório não encontrado at /u01/app/oracle/agent12c/core/12.1.0.4.0/sysman/install/AgentDeinstall.pl line 303
cannot fetch initial working directory: Arquivo ou diretório não encontrado at /u01/app/oracle/agent12c/core/12.1.0.4.0/sysman/install/AgentDeinstall.pl line 303

NOTE: The targets monitored by this Management Agent will not be deleted in the Enterprise Manager Repository by this deinstall script. Make sure to delete the targets manually from the Cloud Control Console for a successful deinstallation.

Numa bela tarde de terça-feira (12/06/2018) me deparo com esse erro bacana ao tentar colocar uma PK de uma tabela online .. Os scripts que eu tentei executar sempre tomavam esse erro. A causa desse problema foi um rebuild de índice PK que parei no meio do processo com um alter system kill session e o mesmo ficou incompleto.

A solução estava num doc id do MOS 375856.1 nomeado de: Session Was Killed During The Rebuild Of Index ORA-08104 : )

Basicamente é rodar esse script na instância que está ocorrendo o erro e em seguida rodar o rebuild dos índices:

DECLARE
isClean BOOLEAN;
BEGIN
isClean := FALSE;
WHILE isClean=FALSE
LOOP
isClean := dbms_repair.online_index_clean(
dbms_repair.all_index_id, dbms_repair.lock_wait);
dbms_lock.sleep(10);
END LOOP;
END;


Até a próxima.