<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Francois Fiorino | Oracle & MySQL Performance Specialist]]></title><description><![CDATA[DBA focado em performance, alta disponibilidade e segurança de bancos de dados Oracle e MySQL em ambientes corporativos críticos.]]></description><link>https://francoisfiorino.com.br</link><image><url>https://cdn.hashnode.com/uploads/logos/69835211e3aecdfd224c568a/45ead01e-899f-47e9-9c5f-74521b473b40.png</url><title>Francois Fiorino | Oracle &amp; MySQL Performance Specialist</title><link>https://francoisfiorino.com.br</link></image><generator>RSS for Node</generator><lastBuildDate>Mon, 20 Apr 2026 20:15:49 GMT</lastBuildDate><atom:link href="https://francoisfiorino.com.br/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Backup não é Data Pump: Como Estruturar uma Rotina RMAN de Verdade]]></title><description><![CDATA[Recentemente, precisei implementar uma rotina de backup em um ambiente onde o cliente utilizava apenas uma exportação via Data Pump, executada diariamente às 23h. Nem preciso dizer que essa abordagem ]]></description><link>https://francoisfiorino.com.br/backup-n-o-data-pump-como-estruturar-uma-rotina-rman-de-verdade</link><guid isPermaLink="true">https://francoisfiorino.com.br/backup-n-o-data-pump-como-estruturar-uma-rotina-rman-de-verdade</guid><dc:creator><![CDATA[Francois Fiorino]]></dc:creator><pubDate>Tue, 31 Mar 2026 13:28:05 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/75da4695-e944-47b4-a0ea-33f8ccf58687.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Recentemente, precisei implementar uma rotina de backup em um ambiente onde o cliente utilizava apenas uma exportação via Data Pump, executada diariamente às 23h. Nem preciso dizer que essa abordagem é totalmente inadequada como estratégia de backup.</p>
<p><strong>O mais impressionante é que, mesmo com a enorme quantidade de conteúdo técnico disponível hoje, ainda encontramos cenários com alto nível de desinformação e baixa maturidade em práticas essenciais dentro de ambientes corporativos.</strong></p>
<p>2 pontos que eu gostaria de salientar :</p>
<blockquote>
<p>1- Backup</p>
<p>2-Observabilidade</p>
</blockquote>
<p>Esses dois pontos precisam caminhar juntos: não adianta ter uma rotina de backup se você não sabe, de fato, se ela está funcionando corretamente. Faz sentido, não é?</p>
<p>Com isso em mente, agora podemos avançar para a parte prática.</p>
<h2>A Tal Rotina de data pump</h2>
<pre><code class="language-shell">#!/bin/bash

export ORACLE_PDB_SID=PDB_APP01 
export ORACLE_BASE=/u01/app/oracle 
export ORACLE_HOME=/u01/app/oracle/product/19.0.0.0/dbhome_1 export ORACLE_HOSTNAME=DBSERVER01 
export PATH=\(PATH:\)ORACLE_HOME/bin

#
cd /backup/datapump

/bin/mv /backup/datapump/*APP01*.gz /backup/datapump_old 2&gt;/dev/null

DATA=$(date +%Y-%m-%d)

expdp system/SenhaFicticia123@PDB_APP01 
schemas=APP,APP_AUDIT 
directory=DP_DIR_APP01 
flashback_time=systimestamp 
dumpfile=EXPDP_APP01_${DATA}.dmp 
logfile=EXPDP_APP01_${DATA}.log

/bin/gzip *APP01*
/bin/chmod 644 *.gz *.log
</code></pre>
<p>Até aqui, nada além do básico — uma rotina simples e funcional.</p>
<p>Optei por mantê-la como estava, pois, apesar de existirem diversas oportunidades de melhoria, ela cumpria seu papel. E, naquele momento, o foco da atividade não era evoluir essa rotina, mas atuar em pontos mais críticos do ambiente.</p>
<h2>Rotina Backup Contrab</h2>
<pre><code class="language-shell">#rotina arc - a cada 30m 
*/30 * * * * /backup/scripts_bkp/bkp_arc.sh &gt; /backup/scripts_bkp/log_err_arc 2&gt;&amp;1

#inc - segunda a sabado as 21:15h
15 21 * * 1-6 /backup/scripts_bkp/bkp_inc.sh &gt; /backup/scripts_bkp/log_err_inc 2&gt;&amp;1

#full - Domingo as 21h
0 21 * * 0 /backup/scripts_bkp/bkp_full.sh &gt; /backup/scripts_bkp/log_err_full 2&gt;&amp;1
</code></pre>
<p>Com essa estratégia, conseguimos cobrir a base de dados com backups ao longo de uma semana.</p>
<p>Os parâmetros adotados foram definidos com base nas limitações de espaço do ambiente. Considerando a rotina de backup de archivelogs a cada 30 minutos, temos um RPO aproximado de 30 minutos — desde que todos os backups estejam íntegros e disponíveis para recuperação.</p>
<p>Os scripts utilizados estão disponibilizados abaixo, devidamente documentados, incluindo regras de notificação por e-mail tanto para sucesso quanto para falhas. É uma abordagem simples, mas que atende bem ao objetivo proposto.</p>
<p>O ambiente em questão utilizava Oracle Standard Edition e apresentava diversas limitações. Ainda assim, isso não justifica a ausência de uma estratégia de backup confiável e funcional — pelo contrário, torna essa necessidade ainda mais crítica.</p>
<h3>Configurações Essenciais RMAN</h3>
<pre><code class="language-shell">CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 7 DAYS; CONFIGURE BACKUP OPTIMIZATION ON;
CONFIGURE ARCHIVELOG DELETION POLICY TO BACKED UP 1 TIMES TO DISK;
</code></pre>
<p>Todas as rotinas documentas e com envio de e-mail diretamente nos scripts para facilitar a Observability quando uma rotina falhar ou finalizar com sucesso.</p>
<h2>Script Backup Full</h2>
<p><a href="https://github.com/francois-fiorino/Advanced-Scripts/blob/344dc099fa1c545ca3af29c45aafe5cb7db6b3f6/oracle/bkp-full">https://github.com/francois-fiorino/Advanced-Scripts/blob/344dc099fa1c545ca3af29c45aafe5cb7db6b3f6/oracle/bkp-full</a></p>
<h2>Script Backup Archive</h2>
<p><a href="https://github.com/francois-fiorino/Advanced-Scripts/blob/344dc099fa1c545ca3af29c45aafe5cb7db6b3f6/oracle/bkp-archive">https://github.com/francois-fiorino/Advanced-</a><a href="https://github.com/francois-fiorino/Advanced-Scripts/blob/344dc099fa1c545ca3af29c45aafe5cb7db6b3f6/oracle/bkp-archive">Scripts/blob/344dc099fa1c545ca3af29c45aafe5cb7db6b3f6/oracle/bkp-archive</a></p>
<h2>Script Backup Incremental</h2>
<p><a href="https://github.com/francois-fiorino/Advanced-Scripts/blob/de12df01eb0d081218b175e30bde60552cd9ddb4/oracle/bkp-incr">https://github.com/francois-fiorino/Advanced-Scripts/blob/de12df01eb0d081218b175e30bde60552cd9ddb4/oracle/bkp-incr</a></p>
<h2>Conclusão</h2>
<p>É isso galera, nem sempre temos disponíveis as melhores condições no cliente, as melhores features ou recursos, mas o básico deve ser atendido, pelo menos é desta forma que eu penso.</p>
<p>Até a próxima ...</p>
]]></content:encoded></item><item><title><![CDATA[Performance Oracle não se decora - se entende (minha jornada do 27% até a aprovação)]]></title><description><![CDATA[Hoje este artigo não é técnico, bem longe disso. Ele é inspirador, de alguém que luta todos os dias por condições melhores e que jamais nega uma boa briga.
Agora vou contar para vocês o que ninguém co]]></description><link>https://francoisfiorino.com.br/performance-oracle-n-o-se-decora-se-entende-minha-jornada-do-27-at-a-aprova-o</link><guid isPermaLink="true">https://francoisfiorino.com.br/performance-oracle-n-o-se-decora-se-entende-minha-jornada-do-27-at-a-aprova-o</guid><dc:creator><![CDATA[Francois Fiorino]]></dc:creator><pubDate>Wed, 18 Mar 2026 22:55:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/be33d1a0-ec7f-4ae0-bb67-9149d43a3848.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hoje este artigo não é técnico, bem longe disso. Ele é inspirador, de alguém que luta todos os dias por condições melhores e que jamais nega uma boa briga.</p>
<p>Agora vou contar para vocês o que ninguém conta sobre o exame:</p>
<blockquote>
<h3><strong>Exam 1Z0-084: Oracle Database 19c: Performance Management and Tuning</strong></h3>
</blockquote>
<p><strong>Sem dúvida este é o exame mais difícil da Oracle !!!!</strong></p>
<h2>Inicio do Desafio</h2>
<p>Existem conquistas que você comemora.<br />E existem conquistas que <strong>te transformam</strong>.</p>
<p>Essa com toda certeza, está me transformou em um <strong>DBA Foda!!</strong></p>
<p>Aqui eu entendi uma coisa que muitos ignoram:</p>
<img src="https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/62ad5e05-7f63-47e6-bb4a-500eceb01791.png" alt="" />

<p>Saber Oracle não é o mesmo que saber <strong>Performance e Tuning de verdade</strong>.</p>
<p>Você pode conhecer RMAN, Data Guard, SQL, Exadata ...<br />Mas quando entra em temas:</p>
<ul>
<li><p>CBO e Otimizador</p>
</li>
<li><p>estatísticas</p>
</li>
<li><p>plano de execução</p>
</li>
<li><p>Advisors e Tenicas diversas</p>
</li>
</ul>
<p><strong>…ou você entende profundamente, ou você cai.</strong></p>
<p><strong>E eu caí, mas não desisti.</strong></p>
<h2>Virada de Chave</h2>
<p>Na segunda tentativa, já não era mais ignorância.</p>
<p><strong>📉 Segunda tentativa — 44%</strong></p>
<img src="https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/d5ab187d-a6ae-4431-8989-533267e2b1a8.png" alt="" style="display:block;margin:0 auto" />

<p>Era um confronto interno. Eu entregava alta performance nos ambientes reais, mas na hora da prova, não conseguia transpor esse conhecimento para o papel.</p>
<p>Melhorou? Sim.<br /><strong>Mas ainda não era suficiente.</strong></p>
<p><strong>Foi aqui que a chave virou:</strong></p>
<p>Eu parei de estudar para a prova e comecei a estudar como um especialista.</p>
<p>Comecei a:</p>
<ul>
<li><p>simular cenários reais</p>
</li>
<li><p>testar comportamento do otimizador</p>
</li>
<li><p>analisar planos de execução na prática</p>
</li>
<li><p>questionar o “porquê” de cada decisão tomada pelo oracle</p>
</li>
<li><p>falar com especialistas da área, procurar entender a mentalidade de alguém que lida somente com performance no dia-a-dia</p>
</li>
</ul>
<p>Não era mais sobre acertar questão.<br />Era sobre <strong>entender o mecanismo por trás</strong>, se não entender o <em><strong>porquê</strong></em>, você não aprende.</p>
<p><em><strong>Então me dediquei pelo menos mais de 180H de montagem de laboratório, até que eu entendesse o porquê, item a item.</strong></em></p>
<h2>Aprovação</h2>
<p><strong>🔥 Terceira tentativa — 60% (APROVADO)</strong></p>
<p>Não foi perfeito.<br />Foi <strong>no limite</strong>.</p>
<img src="https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/379be9c5-fdd2-4ef9-bb59-25850e608d9a.png" alt="" style="display:block;margin:0 auto" />

<p>Mas dessa vez foi diferente.</p>
<p>Cada questão não era mais “chute técnico”.<br />Era decisão baseada em:</p>
<ul>
<li><p>experiência prática</p>
</li>
<li><p>análise crítica</p>
</li>
<li><p>entendimento real</p>
</li>
</ul>
<p>E quando veio o “<strong>Passed</strong>”, eu sabia:</p>
<p><strong>Não foi sorte. Foi construção, foi determinação e muito estudo.</strong></p>
<p><strong>Eu não estudei para a prova, não decorei conceito, eu simplesmente entendi os PORQUÊS...</strong></p>
<h2>Temas Abordas no Exame</h2>
<img src="https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/7b3febda-9167-4a8e-a2ca-53142e2006a6.png" alt="" style="display:block;margin:0 auto" />

<p>Minhas dicas de estudos:</p>
<blockquote>
<p>🔧 <strong>1. Monte laboratório — e confronte teoria com prática o tempo todo</strong><br />Não leia apenas. Teste. Quebre. Simule cenários reais.<br />Performance tuning só se aprende <strong>vendo o comportamento do banco na prática.</strong></p>
<p>🤖 <strong>2. Use IA para acelerar seus cenários de teste</strong><br />Gerar massa de dados, simular problemas, criar queries complexas…<br />A IA pode te economizar <strong>horas de setup</strong> e te colocar direto no que importa: análise e diagnóstico.</p>
<p>📊 <strong>3. Domine os Advisors e ferramentas internas</strong><br />Estude profundamente:</p>
<ul>
<li><p>AWR</p>
</li>
<li><p>ADDM</p>
</li>
<li><p>ASH</p>
</li>
<li><p>Advisors (SQL Tuning, Segment, etc.)</p>
</li>
</ul>
<p>Isso é <strong>extremamente cobrado</strong> — e mais importante: é o que você usa no mundo real.</p>
<p>🧠 <strong>4. Entenda o CBO de verdade (não superficialmente)</strong></p>
<ul>
<li><p>Como o otimizador pensa</p>
</li>
<li><p>Como ele estima cardinalidade</p>
</li>
<li><p>Como escolhe planos</p>
</li>
</ul>
<p>Se você entende isso, você deixa de reagir… e passa a <strong>antecipar o comportamento do banco.</strong></p>
<p>📈 <strong>5. Aprenda a ler planos de execução como um especialista</strong><br />Não é só olhar o custo.<br />É interpretar:</p>
<ul>
<li><p>Join methods</p>
</li>
<li><p>Access paths</p>
</li>
<li><p>Cardinalidade estimada vs real</p>
</li>
<li><p>Gargalos escondidos</p>
</li>
</ul>
<p>E principalmente: <strong>o porquê daquele plano existir.</strong></p>
<p>🧪 <strong>6. Trabalhe com traces e diagnóstico profundo</strong><br />10046, SQL Trace, tkprof…<br />Aqui você sai do “achismo” e entra no <strong>diagnóstico baseado em evidência.</strong></p>
<p>⚙️ <strong>7. Desenvolva sua própria metodologia de tuning</strong><br />Pare de atuar no improviso.<br />Crie um processo:</p>
<ol>
<li><p>Identificar o problema</p>
</li>
<li><p>Coletar evidências</p>
</li>
<li><p>Analisar</p>
</li>
<li><p>Testar hipóteses</p>
</li>
<li><p>Validar resultado</p>
</li>
</ol>
<p>Isso muda completamente seu nível como DBA.</p>
<p>📚 <strong>8. Conheça profundamente as views V\( e GV\)</strong><br />Aqui está a verdade do banco.</p>
<ul>
<li><p>Sessões</p>
</li>
<li><p>Esperas</p>
</li>
<li><p>Consumo de recursos</p>
</li>
<li><p>Histórico</p>
</li>
</ul>
<p>Se você domina essas views, você <strong>enxerga o banco por dentro.</strong></p>
<p>⏱️ <strong>9. Entenda Wait Events (de verdade)</strong><br />Não decore — <strong>interprete</strong>.</p>
<ul>
<li><p>Por que está esperando?</p>
</li>
<li><p>Onde está o gargalo?</p>
</li>
<li><p>É CPU, IO, lock, rede?</p>
</li>
</ul>
<p>Saber correlacionar wait events com cenários reais é um divisor de águas.</p>
<p>🧩 <strong>10. Entenda problemas físicos de dados</strong></p>
<ul>
<li><p>Migrated rows</p>
</li>
<li><p>Chained rows</p>
</li>
</ul>
<p>E principalmente: <strong>o impacto disso na performance.</strong></p>
<p>📐 <strong>11. Cardinalidade e seletividade são o jogo</strong><br />Se você entende isso, você entende o CBO.</p>
<p>E se você entende o CBO…<br />você consegue <strong>influenciar o plano de execução de forma inteligente.</strong></p>
</blockquote>
<h2>Conclusão</h2>
<p><strong>💡 O que essa jornada realmente me ensinou</strong></p>
<p>Essa prova não mede só conhecimento.<br />Ela mede <strong>maturidade técnica</strong>.</p>
<p>Ela separa:</p>
<ul>
<li><p>quem executa comando de quem entende comportamento</p>
</li>
<li><p>quando utilizar cada método, dependendo da situação ou cenário.</p>
</li>
</ul>
<p>Tuning é um aprendizado contínuo: confronto constante de cenários e situações adversas que consolida conceitos, permite praticar e aperfeiçoar técnicas, transformando o DBA em referência.</p>
<p>Isto força você a sair do superficial e entrar no nível onde realmente importa, ser critico e fazer sempre a pergunta: 👉 <strong>por que o banco se comportou desta forma?</strong></p>
<p>Não tive mentor nem fiz curso algum, mas mergulhei em diversas fontes e materiais — com destaque para a documentação oficial da Oracle. Meu foco foi confrontar conceitos e "meias-verdades", validando tudo na prática para solidificar o aprendizado.</p>
<p><strong>🧠 A maior lição</strong></p>
<p><strong>Você não falha quando reprova.</strong></p>
<p><strong>Você falha quando: desiste ou contínua estudando do mesmo jeito</strong></p>
<p>Eu precisei de 3 tentativas.<br />E cada uma delas foi necessária, não para me ensinar teoria, mas para me formar, me dar a visão que um especialista precisa frente a situações adversas.</p>
]]></content:encoded></item><item><title><![CDATA[Você realmente sabe quando usar Image Copy no RMAN?]]></title><description><![CDATA[Fundamentos
Você realmente sabe a diferença entre Backupset e Image Copy no RMAN?
Mais do que isso: sabe quando usar cada estratégia e quais são as limitações práticas de cada uma em ambientes reais?
]]></description><link>https://francoisfiorino.com.br/voc-realmente-sabe-quando-usar-image-copy-no-rman</link><guid isPermaLink="true">https://francoisfiorino.com.br/voc-realmente-sabe-quando-usar-image-copy-no-rman</guid><dc:creator><![CDATA[Francois Fiorino]]></dc:creator><pubDate>Mon, 16 Mar 2026 22:16:05 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/d92e8d42-537a-4f62-8ed7-f3dbb13ff1e4.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Fundamentos</h2>
<p><strong>Você realmente sabe a diferença entre Backupset e Image Copy no RMAN?</strong></p>
<p>Mais do que isso: sabe <strong>quando usar cada estratégia</strong> e quais são as <strong>limitações práticas de cada uma</strong> em ambientes reais?</p>
<p>Muita gente conhece os comandos, mas nem sempre entende <strong>o impacto que a escolha do tipo de backup pode ter no tempo de recuperação do banco (RTO) e na estratégia de proteção de dados (RPO).</strong></p>
<p>Por isso resolvi montar um <strong>laboratório prático</strong>, inspirado em um projeto real que atendi recentemente:</p>
<p><strong>Neste projeto o requisito era diminuir o RTO de um banco de dados produtivo que tinha mais ou menos 10 TB. Nos testes realizados em um ambiente controlado de simulação de falhas, substituímos a estratégia tradicional baseada em backupset por uma abordagem utilizando Image Copy. Os resultados foram bastante expressivos: o tempo necessário para restaurar e recuperar o banco apresentou uma redução significativa, principalmente em cenários de perda de datafiles ou necessidade de recuperação completa.</strong></p>
<p><strong>A estratégia adotada foi: Image Copy + Incremental Merge</strong></p>
<p>Neste artigo vou compartilhar esse laboratório, mostrando <strong>na prática, sem enrolação,</strong> as diferenças entre <strong>Backupset e Image Copy</strong>, quando cada um faz mais sentido e como essa escolha pode impactar diretamente a sua estratégia de backup e recovery.</p>
<h2><strong>Backupset (BACKUP AS BACKUPSET)</strong></h2>
<p><strong>O que é</strong></p>
<p>Um <strong>backupset</strong> é um <strong>formato proprietário do RMAN</strong> que <strong>não é uma cópia direta do datafile</strong>.</p>
<p><strong>Ele contém:</strong></p>
<blockquote>
<p>. Apenas Blocos Utilizados</p>
<p>. Pode ter compressão</p>
<p>. Pode ter multiplexação</p>
<p>. Pode ser criptografado</p>
<p>. Pode ser gravado em fita (SBT)</p>
</blockquote>
<p> <strong>Características</strong></p>
<blockquote>
<p>. RMAN <strong>lê os datafiles</strong></p>
<p>. Extrai <strong>somente blocos necessários</strong></p>
<p>. Grava em arquivos .bkp ou .backupset </p>
</blockquote>
<p><strong>Exemplo:</strong></p>
<pre><code class="language-sql">BACKUP DATABASE;
ou
BACKUP AS BACKUPSET DATABASE;
</code></pre>
<p><strong>Vantagens</strong></p>
<blockquote>
<p>✔ Menor espaço<br />✔ Mais rápido para transferir<br />✔ Suporta compressão<br />✔ Ideal para backup em fita</p>
<p>✔ Permite compressão</p>
<p>✔ Permite multiplexação</p>
</blockquote>
<p><strong>Desvantagens</strong></p>
<blockquote>
<p>❌ Não é utilizável diretamente pelo Oracle<br />❌ Precisa ser restaurado antes de usar</p>
</blockquote>
<h3><strong>Image Copy (BACKUP AS COPY)</strong></h3>
<p><strong>O que é</strong></p>
<p>Uma <strong>Image Copy</strong> é <strong>uma cópia física idêntica do datafile um datafile original -&gt; copia byte a byte.</strong></p>
<p><strong>Exemplo:</strong></p>
<pre><code class="language-sql">BACKUP AS COPY DATABASE;
ou
BACKUP AS COPY DATAFILE 5;
</code></pre>
<p>Isso gera um arquivo <strong>igual ao datafile original.</strong></p>
<p><strong>Vantagens</strong></p>
<blockquote>
<p>✔ Pode ser usado imediatamente</p>
<p>✔ Permite SWITCH DATABASE TO COPY</p>
<p>✔ Excelente para estratégia de recuperação rápida</p>
</blockquote>
<p><strong>Desvantagens</strong></p>
<blockquote>
<p>❌ Maior uso de disco</p>
<p>❌ Não comprime</p>
<p>❌ Não multiplexa</p>
</blockquote>
<h2><strong>Quando escolher Backupset</strong></h2>
<p><strong>Use quando:</strong></p>
<blockquote>
<p>• O banco é grande e espaço de backup é limitado</p>
<p>• Você precisa de compressão</p>
<p>• Você faz backup para fita</p>
<p>• O tempo de restore não é extremamente crítico</p>
<p>• O ambiente tem janela de manutenção suficiente para restore completo.</p>
<p>• Quando o ambiente tem data guard e ele é utilizado como estratégia de contingência.</p>
</blockquote>
<p><strong>Exemplo de cenários</strong></p>
<blockquote>
<p>• Backups enviados para <strong>tape library</strong></p>
<p>• Backups replicados para <strong>cloud storage</strong></p>
<p>• Ambientes com <strong>RTO mais flexível</strong></p>
<p>• Bancos de dados muito grandes onde armazenar cópias completas seria caro</p>
</blockquote>
<h2><strong>Quando escolher Image Copy</strong></h2>
<p>Use quando:</p>
<blockquote>
<p>• O <strong>RTO precisa ser muito baixo</strong></p>
<p>• O banco é <strong>crítico</strong></p>
<p>• Downtime precisa ser <strong>mínimo</strong></p>
<p>• Você quer usar <strong>Incremental Merge</strong></p>
<p>• Há <strong>bastante espaço em disco</strong></p>
<p>• <strong>Quando você quer economizar tempo de restore.</strong></p>
</blockquote>
<p><strong>Exemplo de cenários</strong></p>
<blockquote>
<p>• Sistemas financeiros</p>
<p>• E-commerce</p>
<p>• Bancos críticos de produção</p>
<p>• Ambientes de <strong>alta disponibilidade</strong></p>
</blockquote>
<h2>Montagem de Laboratório</h2>
<pre><code class="language-sql">SQL&gt; CREATE TABLESPACE ts_lab
DATAFILE '+DATADISK'
SIZE 100M;

Tablespace created.
</code></pre>
<pre><code class="language-sql">SQL&gt; select file_name from dba_data_files;

FILE_NAME
----------------------------------------------------
+DATADISK/ORADB/DATAFILE/system.256.1044815187
+DATADISK/ORADB/DATAFILE/sysaux.257.1044815223
+DATADISK/ORADB/DATAFILE/undotbs1.258.1044815237
+DATADISK/ORADB/DATAFILE/users.259.1044815239
+DATADISK/ORADB/DATAFILE/ts_lab.327.1228064151
</code></pre>
<p>Vamos criar uma tabela simples para consultar o seus dados, após restore.</p>
<pre><code class="language-sql">CREATE TABLE objeto_simples (
id NUMBER(10) PRIMARY KEY,
nome VARCHAR2(100),
tipo VARCHAR2(20),
criado_em DATE
)
TABLESPACE TS_LAB;

--Insere dados de exemplo 
INSERT INTO objeto_simples VALUES (2, 'VIEW_EXEMPLO', 'VIEW', SYSDATE - 1);
INSERT INTO objeto_simples VALUES (1, 'TABELA_TESTE', 'TABLE', SYSDATE);
INSERT INTO objeto_simples VALUES (3, 'PROCEDIMENTO1', 'PROCEDURE', SYSDATE - 2);
INSERT INTO objeto_simples VALUES (4, 'INDICE_PRINC', 'INDEX', SYSDATE);

COMMIT;
</code></pre>
<pre><code class="language-sql">--Verifica objeto criado (opcional)

SQL&gt; SELECT count(*) FROM objeto_simples;

  COUNT(*)
----------
         4
</code></pre>
<h2>Backup Usando BACKUPSET</h2>
<pre><code class="language-sql">--No Oracle Recovery Manager: 
RMAN&gt; BACKUP TABLESPACE ts_lab; 

Starting backup at 16-MAR-2026 10:05:38 using target database control file instead of recovery catalog allocated channel: ORA_DISK_1 channel
ORA_DISK_1: SID=283 device type=DISK channel ORA_DISK_1: starting full
datafile backup set channel ORA_DISK_1: specifying datafile(s) in backup
set input datafile file number=00013
name=+DATADISK/ORADB/DATAFILE/ts_lab.327.1228064151 channel ORA_DISK_1:
starting piece 1 at 16-MAR-2026 10:05:41 channel ORA_DISK_1: finished piece
1 at 16-MAR-2026 10:05:42 piece
handle=+DATADISK/ORADB/BACKUPSET/2026_03_16/nnndf0_tag20260316t100541_0.329.1228064743 tag=TAG20260316T100541 comment=NONE channel ORA_DISK_1: backup
set complete, elapsed time: 00:00:01 Finished backup at 16-MAR-2026
10:05:43 Starting Control File and SPFILE Autobackup at 16-MAR-2026
10:05:43 piece
handle=+DATADISK/ORADB/AUTOBACKUP/2026_03_16/s_1228064741.330.1228064743
comment=NONE

Finished Control File and SPFILE Autobackup at 16-MAR-2026 10:05:44
</code></pre>
<pre><code class="language-sql">RMAN&gt; LIST BACKUP OF TABLESPACE ts_lab;

List of Backup Sets
===================
BS Key  Type LV Size       Device Type Elapsed Time Completion Time
------- ---- -- ---------- ----------- ------------ --------------------
11      Full    1.15M      DISK        00:00:02     16-MAR-2026 17:05:41
        BP Key: 11   Status: AVAILABLE  Compressed: NO  Tag: TAG20260316T100541
        Piece Name: +DATADISK/ORADB/BACKUPSET/2026_03_16/nnndf0_tag20260316t100541_0.329.1228064743
  List of Datafiles in backup set 11
  File LV Type Ckp SCN    Ckp Time             Abs Fuz SCN Sparse Name
  ---- -- ---- ---------- -------------------- ----------- ------ ----
  13      Full 13757442   16-MAR-2026 17:05:41              NO    +DATADISK/ORADB/DATAFILE/ts_lab.327.1228064151
</code></pre>
<hr />
<h2><strong>Simular problema</strong></h2>
<pre><code class="language-sql">--Validar status da Tablespaces:

select TABLESPACE_NAME, STATUS from dba_tablespaces 
where tablespace_name ='TS_LAB';

TABLESPACE_NAME                STATUS
------------------------------ ---------
TS_LAB                         ONLINE

--Vamos remover o datafile.
ALTER TABLESPACE ts_lab OFFLINE IMMEDIATE;

--No ASM:
ASMCMD&gt; rm -rf +DATADISK/oradb/datafile/TS_LAB.327.1228064151

--Vamos tentar colocar esta tbs online e vermos o erro:
SQL&gt; ALTER TABLESPACE ts_lab online;
ALTER TABLESPACE ts_lab online
*
ERROR at line 1:
ORA-01157: cannot identify/lock data file 13 - see DBWR trace file
ORA-01110: data file 13: '+DATADISK/ORADB/DATAFILE/ts_lab.327.1228064151'
</code></pre>
<h2><strong>Recovery usando BACKUPSET</strong></h2>
<p>Agora vem o fluxo clássico - No padrão backupset</p>
<pre><code class="language-sql">--RMAN pega o backupset e recria o datafile.

RMAN&gt; RESTORE TABLESPACE ts_lab;

Starting restore at 16-MAR-2026 10:12:02

using target database control file instead of recovery catalog

allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=66 device type=DISK
channel ORA_DISK_1: restored backup piece 1
channel ORA_DISK_1: starting datafile backup set restore
channel ORA_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_DISK_1: restoring datafile 00013 to +DATADISK/ORADB/DATAFILE/ts_lab.327.1228064151

channel ORA_DISK_1: reading from backup piece +DATADISK/ORADB/BACKUPSET/2026_03_16/nnndf0_tag20260316t100541_0.329.1228064743
channel ORA_DISK_1: piece handle=+DATADISK/ORADB/BACKUPSET/2026_03_16/nnndf0_tag20260316t100541_0.329.1228064743 tag=TAG20260316T100541
channel ORA_DISK_1: restore complete, elapsed time: 00:00:01

Finished restore at 16-MAR-2026 10:12:06
</code></pre>
<p>Agora vamos aplicar redo logs, caso exista para deixar a tbs consistente e conseguir colocar a tbs ONLINE.</p>
<pre><code class="language-sql">RMAN&gt; RECOVER TABLESPACE ts_lab;

Starting recover at 16-MAR-2026 10:12:45
using channel ORA_DISK_1
starting media recovery media recovery
complete, elapsed time: 00:00:00

Finished recover at 16-MAR-2026 10:12:46

--Metricas obtidas.
--fim do RESTORE: 10:12:06
--início do RECOVER: 10:12:45
</code></pre>
<p>Colocar a tbs online:</p>
<pre><code class="language-sql">RMAN&gt; ALTER TABLESPACE ts_lab ONLINE;

Statement processed
</code></pre>
<p>Validar status da tbs recuperada.</p>
<pre><code class="language-sql">SQL&gt; select TABLESPACE_NAME, STATUS from dba_tablespaces 
where tablespace_name ='TS_LAB';

TABLESPACE_NAME                STATUS
------------------------------ ---------
TS_LAB                         ONLINE

SQL&gt; SELECT count() FROM objeto_simples;

  COUNT(*)
----------
         4
</code></pre>
<p><strong>Repare que ao validarmos o file name do datafile, ele foi criado usando um novo nome, isso é característico do método via backupset.</strong></p>
<pre><code class="language-sql">SQL&gt; select file_name from dba_data_files; 

FILE_NAME
-----------------------------------------------
+DATADISK/ORADB/DATAFILE/system.256.1044815187
+DATADISK/ORADB/DATAFILE/sysaux.257.1044815223
+DATADISK/ORADB/DATAFILE/undotbs1.258.1044815237
+DATADISK/ORADB/DATAFILE/users.259.1044815239
+DATADISK/ORADB/DATAFILE/ts_lab.327.1228065125
</code></pre>
<h2><strong>Fluxo do Backupset</strong></h2>
<blockquote>
<p>backupset</p>
<p>↓</p>
<p>RESTORE</p>
<p>↓</p>
<p>datafile recriado</p>
<p>↓</p>
<p>RECOVER</p>
<p>↓</p>
<p>tablespace online</p>
</blockquote>
<h2><strong>Backup usando IMAGE COPY</strong></h2>
<p>Primeiro criar backup do tipo - <strong>image copy</strong>.</p>
<pre><code class="language-sql">RMAN&gt; BACKUP AS COPY TABLESPACE ts_lab;

Starting backup at 16-MAR-2026 10:17:44

using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=66 device type=DISK
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=66 device type=DISK
channel ORA_DISK_1: starting datafile copy
input datafile file number=00013 name=+DATADISK/ORADB/DATAFILE/ts_lab.327.1228065125
output file name=+DATADISK/ORADB/DATAFILE/ts_lab.331.1228065467 tag=TAG20260316T101746 RECID=4 STAMP=1228040266
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:01
Finished backup at 16-MAR-2026 10:17:47
Starting Control File and SPFILE Autobackup at 16-MAR-2026 10:17:47
piece handle=+DATADISK/ORADB/AUTOBACKUP/2026_03_16/s_1228040267.332.1228065467 comment=NONE

Finished Control File and SPFILE Autobackup at 16-MAR-2026 10:17:48
</code></pre>
<pre><code class="language-sql">--Verificar o backup gerado:
RMAN&gt; LIST COPY OF TABLESPACE ts_lab;

List of Datafile Copies
Key File S Completion Time Ckp SCN Ckp Time Sparse
4 13 A 16-MAR-2026 10:17:46 13761413 16-MAR-2026 10:17:46 NO
Name: +DATADISK/ORADB/DATAFILE/ts_lab.331.1228065467
Tag: TAG20260316T101746
</code></pre>
<p><strong>Detalhe importante:</strong></p>
<p>Agora no ASM temos 2 arquivos da mesma Tablespace, um copia do outro:</p>
<pre><code class="language-sql">ASMCMD&gt; cd datafile
ASMCMD&gt; ls -l
Type Redund Striped Time Sys Name

DATAFILE UNPROT COARSE MAR 16 17:00:00 Y TS_LAB.327.1228065125
DATAFILE UNPROT COARSE MAR 16 17:00:00 Y TS_LAB.331.1228065467
</code></pre>
<h2><strong>Simular problema</strong></h2>
<pre><code class="language-sql">--Vamos novamente remover o datafile simulando um erro.
SQL&gt; ALTER TABLESPACE ts_lab OFFLINE IMMEDIATE;

# ASMCMD&gt; rm -rf +DATADISK/oradb/datafile/TS_LAB.327.1228065125
</code></pre>
<h2><strong>Recovery usando IMAGE COPY</strong></h2>
<p>Vamos agora recuperar o datafile, repare que o processo será mais rápido, pois não precisa recriar o datafile, apenas fazer um <strong>switch copy</strong> e alterar a referencia no controlfile.</p>
<pre><code class="language-sql">RMAN&gt; SWITCH TABLESPACE ts_lab TO COPY;

using target database control file instead of 
recovery catalog
datafile 13 switched to datafile copy "+DATADISK/ORADB/DATAFILE/ts_lab.331.1228065467"
</code></pre>
<p>Aqui fica evidente que em um banco enorme, economizaríamos um tempo considerado de <strong>RESTORE</strong> que em uma estratégia de <strong>RTO</strong> é o fator que mais consome tempo para recuperar um banco por completo.</p>
<pre><code class="language-sql">RMAN&gt; RECOVER TABLESPACE ts_lab;
Starting recover at 16-MAR-2026 10:30:43
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=47 device type=DISK
starting media recovery
media recovery complete, elapsed time: 00:00:01
Finished recover at 16-MAR-2026 10:30:46

RMAN&gt; ALTER TABLESPACE ts_lab ONLINE;
Statement processed

--Valide a quantidade de registros na tabela, após restore.
SQL&gt; SELECT count(*) FROM objeto_simples;

  COUNT(*)
----------
         4
</code></pre>
<h2><strong>Fluxo do Image Copy</strong></h2>
<blockquote>
<p>image copy já existe</p>
<p>↓</p>
<p>SWITCH TO COPY</p>
<p>↓</p>
<p>RECOVER</p>
<p>↓</p>
<p>tablespace online</p>
</blockquote>
<h2><strong>Conclusão</strong></h2>
<p>Quando falamos de estratégias de backup e recuperação, não existe uma única abordagem que funcione para todos os cenários. Cada ambiente possui suas próprias características, limitações e requisitos de negócio.</p>
<p>Por isso, evite ficar preso a apenas um método ou padrão. Analise o ambiente, entenda os objetivos de <strong>RPO e RTO</strong>, avalie as limitações de infraestrutura e identifique quais estratégias realmente fazem sentido para aquele contexto.</p>
<p>Se necessário, <strong>teste diferentes abordagens em ambientes controlados</strong>. Muitas vezes é justamente nesses testes que surgem oportunidades de melhoria que passam despercebidas no dia a dia operacional.</p>
<p>No final das contas, nada está escrito em pedra. O papel de quem administra bancos de dados é justamente <strong>questionar, analisar criticamente e buscar constantemente formas mais eficientes de proteger e recuperar os dados</strong>.</p>
<p>Faça as perguntas certas, valide as hipóteses e esteja sempre disposto a evoluir suas estratégias.</p>
]]></content:encoded></item><item><title><![CDATA[Provisionamento de usuários e concessão automatizada de privilégios no Oracle Database]]></title><description><![CDATA[Introdução
Em ambientes corporativos é comum a necessidade de provisionar múltiplos usuários com as mesmas permissões dentro do banco de dados.
Realizar a concessão manual de privilégios em centenas o]]></description><link>https://francoisfiorino.com.br/provisionamento-de-usu-rios-e-concess-o-automatizada-de-privil-gios-no-oracle-database</link><guid isPermaLink="true">https://francoisfiorino.com.br/provisionamento-de-usu-rios-e-concess-o-automatizada-de-privil-gios-no-oracle-database</guid><dc:creator><![CDATA[Francois Fiorino]]></dc:creator><pubDate>Fri, 13 Mar 2026 11:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/f42f230e-96b3-4ac9-b9a3-56c8738dec01.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3>Introdução</h3>
<p>Em ambientes corporativos é comum a necessidade de provisionar múltiplos usuários com as mesmas permissões dentro do banco de dados.</p>
<p>Realizar a concessão manual de privilégios em centenas ou milhares de objetos pode ser um processo demorado, sujeito a erros e difícil de auditar.</p>
<p>Neste artigo apresento uma abordagem estruturada para:</p>
<p>• Criar usuários no Oracle Database</p>
<p>• Centralizar privilégios em uma ROLE</p>
<p>• Automatizar a concessão de privilégios em tabelas e objetos PL/SQL</p>
<p>• Executar um dry-run para validação antes de aplicar os GRANTs</p>
<p>• Registrar todas as operações em log</p>
<p>Essa abordagem é especialmente útil em ambientes com grande volume de objetos, onde a manutenção manual se torna inviável.</p>
<p><strong>1. Criando uma ROLE para centralizar os privilégios</strong></p>
<p>A primeira boa prática é evitar conceder privilégios diretamente aos usuários.</p>
<p>Em vez disso, criamos uma ROLE que centraliza os privilégios.</p>
<pre><code class="language-sql">CREATE ROLE app_dml_role;
</code></pre>
<p><strong>2. Criação dos usuários no banco de dados</strong></p>
<p>Agora criamos os usuários que terão acesso ao banco.</p>
<pre><code class="language-sql">CREATE USER user_1 IDENTIFIED BY "aDo04j28L"

DEFAULT TABLESPACE USERS

TEMPORARY TABLESPACE TEMP

QUOTA UNLIMITED ON USERS;



CREATE USER user_2 IDENTIFIED BY "8178R2uxW"

DEFAULT TABLESPACE USERS

TEMPORARY TABLESPACE TEMP

QUOTA UNLIMITED ON USERS;



CREATE USER user_3 IDENTIFIED BY "O7F7xI0Y5"

DEFAULT TABLESPACE USERS

TEMPORARY TABLESPACE TEMP

QUOTA UNLIMITED ON USERS;



CREATE USER user_4 IDENTIFIED BY "CRF1190Kh"

DEFAULT TABLESPACE USERS

TEMPORARY TABLESPACE TEMP

QUOTA UNLIMITED ON USERS;



CREATE USER user_5 IDENTIFIED BY "N8cHd9q1A"

DEFAULT TABLESPACE USERS

TEMPORARY TABLESPACE TEMP

QUOTA UNLIMITED ON USERS;
</code></pre>
<p><strong>3. Concedendo privilégio de conexão</strong></p>
<p>Todos os usuários precisam do privilégio básico de conexão.</p>
<pre><code class="language-sql">GRANT CREATE SESSION TO user_1;

GRANT CREATE SESSION TO user_2;

GRANT CREATE SESSION TO user_3;

GRANT CREATE SESSION TO user_4;

GRANT CREATE SESSION TO user_5;
</code></pre>
<p><strong>4. Associando a ROLE aos usuários</strong></p>
<p>Agora vinculamos os usuários à role criada anteriormente.</p>
<pre><code class="language-sql">GRANT app_dml_role TO user_1;

GRANT app_dml_role TO user_2;

GRANT app_dml_role TO user_3;

GRANT app_dml_role TO user_4;

GRANT app_dml_role TO user_5;
</code></pre>
<p><strong>5. Tabela de log das operações</strong></p>
<p>Antes de executar os GRANTs, criamos uma tabela para registrar todas as operações realizadas.</p>
<pre><code class="language-sql">CREATE TABLE sec_grant_log (

  log_id      NUMBER GENERATED ALWAYS AS IDENTITY,

  log_ts      TIMESTAMP DEFAULT SYSTIMESTAMP,

  role_name   VARCHAR2(128),

  owner_name  VARCHAR2(128),

  obj_type    VARCHAR2(30),

  obj_name    VARCHAR2(128),

  stmt        CLOB,

  status      VARCHAR2(10),

  err_msg     VARCHAR2(4000)

);
</code></pre>
<p><strong>6. Package para execução automatizada dos GRANTs</strong></p>
<p>Specification</p>
<pre><code class="language-sql">CREATE OR REPLACE PACKAGE sec_grant_mgr AS

  PROCEDURE grant_role_for_owners(

    p_role      IN VARCHAR2,

    p_owners    IN SYS.ODCIVARCHAR2LIST,

    p_dry_run   IN BOOLEAN DEFAULT FALSE

  );

END sec_grant_mgr;

/
</code></pre>
<p><strong>Package Body</strong></p>
<pre><code class="language-sql">CREATE OR REPLACE PACKAGE BODY sec_grant_mgr AS

  PROCEDURE log_stmt(
    p_role   VARCHAR2,
    p_owner  VARCHAR2,
    p_type   VARCHAR2,
    p_name   VARCHAR2,
    p_stmt   CLOB,
    p_status VARCHAR2,
    p_err    VARCHAR2
  ) IS
  BEGIN
    INSERT INTO sec_grant_log(role_name, owner_name, obj_type, obj_name, stmt, status, err_msg)
    VALUES (UPPER(p_role), UPPER(p_owner), p_type, p_name, p_stmt, p_status, p_err);
  END;

  PROCEDURE exec_sql(
    p_role    VARCHAR2,
    p_owner   VARCHAR2,
    p_type    VARCHAR2,
    p_name    VARCHAR2,
    p_sql     CLOB,
    p_dry_run BOOLEAN
  ) IS
  BEGIN
    IF NOT p_dry_run THEN
      EXECUTE IMMEDIATE p_sql;
    END IF;

    log_stmt(p_role, p_owner, p_type, p_name, p_sql, 'OK', NULL);

  EXCEPTION
    WHEN OTHERS THEN
      log_stmt(p_role, p_owner, p_type, p_name, p_sql, 'ERROR', SQLERRM);
  END;

  PROCEDURE grant_role_for_owners(
    p_role      IN VARCHAR2,
    p_owners    IN SYS.ODCIVARCHAR2LIST,
    p_dry_run   IN BOOLEAN DEFAULT FALSE
  ) IS
  BEGIN

    FOR t IN (
      SELECT owner, table_name
      FROM dba_tables
      WHERE owner IN (SELECT UPPER(column_value) FROM TABLE(p_owners))
    ) LOOP
      exec_sql(
        p_role, t.owner, 'TABLE', t.table_name,
        'GRANT SELECT, INSERT, UPDATE, DELETE ON ' || t.owner || '.' || t.table_name || ' TO ' || p_role,
        p_dry_run
      );
    END LOOP;

    FOR o IN (
      SELECT owner, object_name, object_type
      FROM dba_objects
      WHERE owner IN (SELECT UPPER(column_value) FROM TABLE(p_owners))
      AND object_type IN ('PROCEDURE','FUNCTION','PACKAGE')
    ) LOOP
      exec_sql(
        p_role, o.owner, o.object_type, o.object_name,
        'GRANT EXECUTE ON ' || o.owner || '.' || o.object_name || ' TO ' || p_role,
        p_dry_run
      );
    END LOOP;

    COMMIT;

  END;

END sec_grant_mgr;
/
</code></pre>
<p><strong>7. Executando um DRY-RUN</strong></p>
<p>Antes de aplicar os GRANTs efetivamente, podemos simular a execução.</p>
<p>SQL</p>
<pre><code class="language-sql">BEGIN

  sec_grant_mgr.grant_role_for_owners(

    p_role    =&gt; 'APP_DML_ROLE',

    p_owners  =&gt; SYS.ODCIVARCHAR2LIST('RM'),

    p_dry_run =&gt; TRUE

  );

END;

/
</code></pre>
<p><strong>8. Validando os resultados da simulação</strong></p>
<pre><code class="language-sql">SELECT status, obj_type, COUNT(*) qtd

FROM sec_grant_log

WHERE role_name = 'APP_DML_ROLE'

GROUP BY status, obj_type

ORDER BY status, obj_type;



STATUS     OBJ_TYPE                              QTD

---------- ------------------------------ ----------

OK         FUNCTION                               45

OK         PROCEDURE                              53

OK         TABLE                                8544



SELECT stmt

FROM sec_grant_log

WHERE role_name = 'APP_DML_ROLE'

AND status = 'OK'

ORDER BY log_id;
</code></pre>
<p><strong>9. Validando os grants gerados e armazenados na tabela, após simulação.</strong></p>
<pre><code class="language-sql">SELECT stmt

FROM sec_grant_log

WHERE role_name = 'APP_DML_ROLE'

AND status = 'OK'

ORDER BY log_id;



STMT                                                                           

--------------------------------------------------------------------------------

GRANT EXECUTE ON RM.VERIFICAGLOSAGG TO APP_DML_ROLE                            

GRANT EXECUTE ON RM.SP_AJUSTACLIENTEDUPLICADO TO APP_DML_ROLE                  

GRANT EXECUTE ON RM.P_AUDITLOG TO APP_DML_ROLE                                 

GRANT EXECUTE ON RM.P_AUDITGETDIF TO APP_DML_ROLE                              

GRANT EXECUTE ON RM.SAUGETGRUPOGASTOTISS TO APP_DML_ROLE    

 
</code></pre>
<p><strong>9. Limpando o log antes da execução real, para garantir que não haja duplicidade.</strong></p>
<pre><code class="language-sql">TRUNCATE TABLE sec_grant_log;
</code></pre>
<p><strong>10. Executando os GRANTs efetivamente</strong></p>
<pre><code class="language-sql">BEGIN

  sec_grant_mgr.grant_role_for_owners(

    p_role    =&gt; 'APP_DML_ROLE',

    p_owners  =&gt; SYS.ODCIVARCHAR2LIST('RM'),

    p_dry_run =&gt; FALSE

  );

END;

/
</code></pre>
<p><strong>11. Validando os privilégios que foram concedidos aos usuários efetivamente.</strong></p>
<pre><code class="language-sql">SELECT owner, table_name, privilege, grantee

FROM dba_tab_privs

WHERE grantee = 'APP_DML_ROLE'

AND owner = 'RM';

 

OWNER TABLE_NAME PRIVILEGE GRANTEE
---------- ---------------------------------------- --------------- ---------------
RM P_AUDITGETDIF EXECUTE APP_DML_ROLE
RM SAUGETGRUPOGASTOTISS EXECUTE APP_DML_ROLE
</code></pre>
<p><strong>Conclusão</strong></p>
<p>Essa abordagem traz várias vantagens para ambientes Oracle:</p>
<p>• Centralização de permissões via ROLE</p>
<p>• Provisionamento consistente de usuários</p>
<p>• Automação de GRANTs em milhares de objetos</p>
<p>• Execução segura via dry-run</p>
<p>• Auditoria completa das operações</p>
<p>Esse tipo de automação é extremamente útil em ambientes corporativos com grande volume de objetos e múltiplos usuários de aplicação.</p>
<p>Fique à vontade em alterar a procedure e incluir outros grants necessários como DDL ou DCL.</p>
]]></content:encoded></item><item><title><![CDATA[Remote PDB Cloning no Oracle 19c]]></title><description><![CDATA[Introdução
Em ambientes Oracle Multitenant, a necessidade de clonar um PDB entre CDBs distintos é comum para refresh de ambientes, provisionamento rápido, migração controlada e consolidação. Uma das f]]></description><link>https://francoisfiorino.com.br/remote-pdb-cloning-no-oracle-19c</link><guid isPermaLink="true">https://francoisfiorino.com.br/remote-pdb-cloning-no-oracle-19c</guid><dc:creator><![CDATA[Francois Fiorino]]></dc:creator><pubDate>Sat, 07 Mar 2026 00:16:42 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/ed2addcf-960c-47dc-8427-7dd6d2b09d0f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Introdução</h2>
<p>Em ambientes Oracle Multitenant, a necessidade de clonar um PDB entre CDBs distintos é comum para refresh de ambientes, provisionamento rápido, migração controlada e consolidação. Uma das formas mais elegantes no Oracle 19c é utilizar Remote Cloning via Database Link.</p>
<h2>Cenário do Laboratório</h2>
<p>Origem: CDB1 contendo PDB1_RMDB</p>
<p>Destino: CDB2 onde será criado PDB2_RMDB</p>
<p>Detalhe: Ambos precisam ter</p>
<h2>1.Pré-requisitos Técnicos</h2>
<p>Validar LOCAL UNDO, no banco de origem:</p>
<p>SELECT property_name, property_value<br />FROM database_properties<br />WHERE property_name = 'LOCAL_UNDO_ENABLED';</p>
<h2>2. Criar usuário comum para o clone remoto</h2>
<p>No CDB de origem:</p>
<p>CREATE USER c##remote_clone_user IDENTIFIED BY remote_clone_user CONTAINER=ALL;<br />GRANT CREATE SESSION, CREATE PLUGGABLE DATABASE TO c##remote_clone_user CONTAINER=ALL;</p>
<h2>3. Configurar TNS no destino</h2>
<p>Este será o dblink utilizado para capturar os dados a partir da origem e clonar o pdb no destino.</p>
<p>remote_cdb =<br />  (DESCRIPTION =<br />    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.18.10)(PORT = 1521))<br />    (CONNECT_DATA =<br />      (SERVER = DEDICATED)<br />      (SERVICE_NAME = pdb3)<br />    )<br />  )</p>
<h2>4. Criando o Database Link</h2>
<p>CREATE DATABASE LINK clone_link<br />  CONNECT TO c##remote_clone_user IDENTIFIED BY remote_clone_user<br />  USING 'remote_cdb';</p>
<p>Valide o dblink antes de iniciar a atividade:</p>
<p>SQL&gt; select sysdate from dual@clone_link;</p>
<p>SYSDATE</p>
<p>---------</p>
<p>23-FEB-26</p>
<h2>5. Executando o Remote Clone</h2>
<p>No servidor de destino, inicie o clone.</p>
<p>SQL&gt; CREATE PLUGGABLE DATABASE PDB2_RMDB<br />FROM PDB1_RMDB@clone_link;</p>
<h2>5.1. Evidências no alert.log</h2>
<p>Completed: CREATE PLUGGABLE DATABASE PDB2_RMDB FROM PDB1_RMDB@clone_link</p>
<p>2026-02-23T17:14:31.465239-03:00</p>
<p>PDB2_RMDB(4):Endian type of dictionary set to little</p>
<p>2026-02-23T17:14:33.344149-03:00</p>
<p>****************************************************************</p>
<p>Pluggable Database PDB2_RMDB with pdb id - 4 is created as UNUSABLE.</p>
<p>If any errors are encountered before the pdb is marked as NEW,</p>
<p>then the pdb must be dropped</p>
<p>local undo-1, localundoscn-0x000000000000012b</p>
<p>****************************************************************</p>
<p>2026-02-23T17:14:37.703009-03:00</p>
<p>Applying media recovery for pdb-4099 from SCN 592315319879 to SCN 592318035910</p>
<p>Remote log information: count-1</p>
<p>thr-1,seq-20746,logfile-+ARCH/RMDB/partial_archivelog/2026_02_23/thread_1_seq_20746.342.1225991677,los-592315312478,nxs-18446744073709551615,maxblks-17452</p>
<p>PDB2_RMDB(4):Media Recovery Start</p>
<p>2026-02-23T17:14:37.719435-03:00</p>
<p>PDB2_RMDB(4):Serial Media Recovery started</p>
<p>PDB2_RMDB(4):max_pdb is 5</p>
<p>2026-02-23T17:14:38.141677-03:00</p>
<p>PDB2_RMDB(4):Media Recovery Log +ARCH/RMDB/partial_archivelog/2026_02_23/thread_1_seq_20746.342.1225991677</p>
<p>2026-02-23T17:14:38.467834-03:00</p>
<p>PDB2_RMDB(4):Incomplete Recovery applied until change 592318035910 time 02/23/2026 17:14:35</p>
<p>2026-02-23T17:14:38.484103-03:00</p>
<p>PDB2_RMDB(4):Media Recovery Complete (RMDB)</p>
<p>PDB2_RMDB(4):Pluggable database PDB2_RMDB pseudo opening</p>
<p>2026-02-23T17:14:38.737473-03:00</p>
<p>PDB2_RMDB(4):SUPLOG: Initialize PDB SUPLOG SGA, old value 0x0, new value 0x18</p>
<p>PDB2_RMDB(4):Autotune of undo retention is turned on.</p>
<p>2026-02-23T17:14:39.505291-03:00</p>
<p>PDB2_RMDB(4):Undo initialization recovery: Parallel FPTR failed: start:1801041217 end:1801041235 diff:18 ms (0.0 seconds)</p>
<p>PDB2_RMDB(4):Undo initialization recovery: err:0 start: 1801041210 end: 1801041442 diff: 232 ms (0.2 seconds)</p>
<p>2026-02-23T17:14:39.783233-03:00</p>
<p>PDB2_RMDB(4):[4108367] Successfully onlined Undo Tablespace 2.</p>
<p>PDB2_RMDB(4):Undo initialization online undo segments: err:0 start: 1801041442 end: 1801041513 diff: 71 ms (0.1 seconds)</p>
<p>PDB2_RMDB(4):Undo initialization finished serial:0 start:1801041210 end:1801041561 diff:351 ms (0.4 seconds)</p>
<p>PDB2_RMDB(4):Database Characterset for PDB2_RMDB is WE8MSWIN1252</p>
<p>PDB2_RMDB(4):Pluggable database PDB2_RMDB pseudo closing</p>
<p>PDB2_RMDB(4):JIT: pid 4108367 requesting stop</p>
<p>PDB2_RMDB(4):Closing sequence subsystem (18980911116255).</p>
<p>PDB2_RMDB(4):Buffer Cache flush started: 4</p>
<p>PDB2_RMDB(4):Buffer Cache flush finished: 4</p>
<p>2026-02-23T17:14:41.231833-03:00</p>
<p>Completed: CREATE PLUGGABLE DATABASE PDB2_RMDB FROM PDB1_RMDB@clone_link</p>
<p>2026-02-23T17:39:39.513401-03:00</p>
<h2>6. Abrindo o PDB</h2>
<p>ALTER PLUGGABLE DATABASE PDB2_RMDB OPEN;</p>
<h2>6.1 Evidências do Alert.log</h2>
<p>ALTER PLUGGABLE DATABASE PDB2_RMDB OPEN</p>
<p>2026-02-23T17:39:39.525650-03:00</p>
<p>PDB2_RMDB(4):Pluggable database PDB2_RMDB opening in read write</p>
<p>PDB2_RMDB(4):SUPLOG: Initialize PDB SUPLOG SGA, old value 0x0, new value 0x18</p>
<p>PDB2_RMDB(4):Autotune of undo retention is turned on.</p>
<p>PDB2_RMDB(4):Endian type of dictionary set to little</p>
<p>2026-02-23T17:39:40.932091-03:00</p>
<p>PDB2_RMDB(4):Undo initialization recovery: Parallel FPTR complete: start:1802542564 end:1802542662 diff:98 ms (0.1 seconds)</p>
<p>PDB2_RMDB(4):Undo initialization recovery: err:0 start: 1802542559 end: 1802542662 diff: 103 ms (0.1 seconds)</p>
<p>2026-02-23T17:39:42.518603-03:00</p>
<p>PDB2_RMDB(4):[4108367] Successfully onlined Undo Tablespace 2.</p>
<p>PDB2_RMDB(4):Undo initialization online undo segments: err:0 start: 1802542662 end: 1802544248 diff: 1586 ms (1.6 seconds)</p>
<p>PDB2_RMDB(4):Undo initialization finished serial:0 start:1802542559 end:1802544297 diff:1738 ms (1.7 seconds)</p>
<p>PDB2_RMDB(4):Deleting old file#8 from file$</p>
<p>PDB2_RMDB(4):Deleting old file#9 from file$</p>
<p>PDB2_RMDB(4):Deleting old file#10 from file$</p>
<p>PDB2_RMDB(4):Deleting old file#11 from file$</p>
<p>PDB2_RMDB(4):Deleting old file#12 from file$</p>
<p>PDB2_RMDB(4):Deleting old file#13 from file$</p>
<p>PDB2_RMDB(4):Deleting old file#14 from file$</p>
<p>PDB2_RMDB(4):Deleting old file#15 from file$</p>
<p>PDB2_RMDB(4):Deleting old file#16 from file$</p>
<p>PDB2_RMDB(4):Deleting old file#17 from file$</p>
<p>PDB2_RMDB(4):Deleting old file#18 from file$</p>
<p>PDB2_RMDB(4):Deleting old file#19 from file$</p>
<p>PDB2_RMDB(4):Deleting old file#20 from file$</p>
<p>PDB2_RMDB(4):Deleting old file#21 from file$</p>
<p>PDB2_RMDB(4):Deleting old file#22 from file$</p>
<p>PDB2_RMDB(4):Adding new file#102 to file$(old file#8).             fopr-1, newblks-1728000, oldblks-26880</p>
<p>PDB2_RMDB(4):Adding new file#103 to file$(old file#9).             fopr-1, newblks-211840, oldblks-21120</p>
<p>PDB2_RMDB(4):Adding new file#104 to file$(old file#10).             fopr-1, newblks-819840, oldblks-7680</p>
<p>PDB2_RMDB(4):Adding new file#105 to file$(old file#11).             fopr-1, newblks-640, oldblks-640</p>
<p>PDB2_RMDB(4):Adding new file#106 to file$(old file#12).             fopr-1, newblks-4194302, oldblks-131072</p>
<p>PDB2_RMDB(4):Adding new file#107 to file$(old file#13).             fopr-1, newblks-4194302, oldblks-131072</p>
<p>PDB2_RMDB(4):Adding new file#110 to file$(old file#14).             fopr-1, newblks-131072, oldblks-131072</p>
<p>PDB2_RMDB(4):Adding new file#111 to file$(old file#15).             fopr-1, newblks-489472, oldblks-131072</p>
<p>PDB2_RMDB(4):Adding new file#112 to file$(old file#17).             fopr-1, newblks-131072, oldblks-131072</p>
<p>PDB2_RMDB(4):Adding new file#113 to file$(old file#18).             fopr-1, newblks-131072, oldblks-131072</p>
<p>PDB2_RMDB(4):Adding new file#108 to file$(old file#20).             fopr-1, newblks-3638272, oldblks-131072</p>
<p>PDB2_RMDB(4):Adding new file#109 to file$(old file#21).             fopr-1, newblks-3177472, oldblks-131072</p>
<p>PDB2_RMDB(4):Adding new file#114 to file$(old file#22).             fopr-1, newblks-2918400, oldblks-12800</p>
<p>PDB2_RMDB(4):Successfully created internal service PDB2_RMDB at open</p>
<p>2026-02-23T17:39:43.638607-03:00</p>
<p>****************************************************************</p>
<p>Post plug operations are now complete.</p>
<p>Pluggable database PDB2_RMDB with pdb id - 4 is now marked as NEW.</p>
<p>****************************************************************</p>
<p>PDB2_RMDB(4):Database Characterset for PDB2_RMDB is WE8MSWIN1252</p>
<p>2026-02-23T17:39:49.052903-03:00</p>
<p>PDB2_RMDB(4):JIT: pid 4108367 requesting full stop</p>
<p>2026-02-23T17:39:55.253777-03:00</p>
<p>Violations: Type: 2, Count: 3</p>
<p>PDB2_RMDB(4):***************************************************************</p>
<p>PDB2_RMDB(4):WARNING: Pluggable Database PDB2_RMDB with pdb id - 4 is</p>
<p>PDB2_RMDB(4):         altered with errors or warnings. Please look into</p>
<p>PDB2_RMDB(4):         PDB_PLUG_IN_VIOLATIONS view for more details.</p>
<p>PDB2_RMDB(4):***************************************************************</p>
<p>PDB2_RMDB(4):SUPLOG: Set PDB SUPLOG SGA at PDB OPEN, old 0x18, new 0x0 (no suplog)</p>
<p>2026-02-23T17:40:03.101257-03:00</p>
<p>PDB2_RMDB(4):Opening pdb with Resource Manager plan: DEFAULT_PLAN</p>
<p>PDB2_RMDB(4):joxcsys_required_dirobj_exists: directory object exists with required path /u01/app/oracle/product/19.0.0.0/dbhome_1/javavm/admin/, pid 4108367 cid 4</p>
<p>2026-02-23T17:40:04.120041-03:00</p>
<p>Pluggable database PDB2_RMDB opened read write</p>
<p>Completed: ALTER PLUGGABLE DATABASE PDB2_RMDB OPEN</p>
<h2>7. Verificando PDB_PLUG_IN_VIOLATIONS</h2>
<p>Valide se há violações ao abrir o <strong>PDB</strong>. No meu caso, não foram detectadas ocorrências e as atividades prosseguiram. Caso encontre alguma violação, realize as correções antes de continuar para evitar divergências nos dados.</p>
<p>SELECT name, cause, type, message, status<br />FROM pdb_plug_in_violations<br />WHERE name = 'PDB2_RMDB';</p>
<img src="https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/b23e89e3-c7dd-4ace-8906-d6a149dcc81b.png" alt="" style="display:block;margin:0 auto" />

<p>Esse warning é bem típico após <strong>plug/clone</strong> de PDB: ele está dizendo que <strong>no PDB clonado o componente/option “SDO” (Oracle Spatial / Locator)</strong> não está instalado (aparece como <strong>NULL</strong>), enquanto <strong>no CDB raiz</strong> ele está instalado/registrado como <strong>19.0.0.0.0</strong>. Por isso o <strong>PDB_PLUG_IN_VIOLATIONS</strong> registra <em>OPTION / WARNING / PENDING</em>.</p>
<p>Temos também warning de parâmetros:</p>
<p>Esses aqui:</p>
<ul>
<li><p>pga_aggregate_target mismatch: Previous 2032M Current 2G</p>
</li>
<li><p>session_cached_cursors mismatch: Previous 200 Current 50</p>
</li>
</ul>
<p>São <strong>warnings de parâmetro do CDB no momento do plug/clone</strong>.</p>
<p>Em geral:</p>
<ul>
<li><p><strong>não quebram</strong> o PDB</p>
</li>
<li><p>são só “diferença de configuração” registrada como <em>PENDING</em></p>
</li>
</ul>
<p><em>Mas vamos arrumar.</em></p>
<h2>8. Warnings de Parâmetros:</h2>
<p>No CDB (não no PDB), ajuste:</p>
<p>alter system set session_cached_cursors=200 scope=spfile;<br />alter system set pga_aggregate_target=2032M scope=both;</p>
<h2>8.1 Warnings de Option:</h2>
<p>Repita este processo para todos os PDBS que tiverem a VIOLATION registrada.</p>
<p>alter session set container = PDB1_RMDB;<br />@?/md/admin/catmd.sql<br />@?/rdbms/admin/utlrp.sql</p>
<p>alter session set container = PDB2_RMDB;<br />@?/md/admin/catmd.sql<br />@?/rdbms/admin/utlrp.sql</p>
<img src="https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/16b33c3b-f9d6-4785-a4f1-ec0356d88eb4.png" alt="" style="display:block;margin:0 auto" />

<p>Verifique se o status da <strong>OPTION</strong> consta como <strong>VALID</strong>.</p>
<p>Anteriormente inexistente, a opção foi instalada com sucesso.</p>
<p>Aproveite e compile tudo.</p>
<img src="https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/36c7ed2e-8be5-4277-b5dd-f5c7e2824fea.png" alt="" style="display:block;margin:0 auto" />

<p>select comp_id, version, status<br />from dba_registry<br />where comp_id='SDO';</p>
<img src="https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/18be3ebf-61be-4aae-b889-367abcd9c6e1.png" alt="" style="display:block;margin:0 auto" />

<p>Para aplicar as alterações de parâmetros e corrigir as violações, <strong>reinicie os PDBs</strong> e valide o status em seguida.</p>
<p>alter pluggable database PDB1_RMDB close immediate;<br />alter pluggable database PDB1_RMDB open;</p>
<p>alter pluggable database PDB2_RMDB close immediate;<br />alter pluggable database PDB2_RMDB open;</p>
<p>SQL&gt; show pdbs;</p>
<p>CON_ID CON_NAME                       OPEN MODE  RESTRICTED</p>
<p>---------- ------------------------------ ---------- ----------</p>
<p>2 PDB$SEED                       READ ONLY  NO</p>
<p>3 PDB1_RMDB                      READ WRITE NO</p>
<p>4 PDB2_RMDB                      READ WRITE NO</p>
<p>col cause for a25<br />col time for a25<br />col message for a80<br />select name, type, cause, status, time, message<br />from pdb_plug_in_violations<br />where name IN ('PDB1_RMDB', 'PDB2_RMDB')<br />and message like '%SDO%'<br />order by time desc;</p>
<img src="https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/7809b33b-6e8b-4bb3-8602-304eb1d52d6a.png" alt="" style="display:block;margin:0 auto" />

<img src="https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/8350d5ce-1cea-47e0-9c53-be2037cf3915.png" alt="" style="display:block;margin:0 auto" />

<h2>Conclusão</h2>
<p>Remote PDB Cloning no Oracle 19c permite clonagem consistente, auditável e rápida entre CDBs, eliminando processos manuais como unplug/plug via XML ou restore físico tradicional.</p>
]]></content:encoded></item><item><title><![CDATA[Como Listar Discos no Oracle Linux por Data de Criação]]></title><description><![CDATA[Introdução
Em ambientes corporativos com Oracle Linux, especialmente em cenários com RAC, ASM, SAN ou ambientes virtualizados, é comum surgir a seguinte dúvida: como descobrir quando um disco foi cria]]></description><link>https://francoisfiorino.com.br/artigos</link><guid isPermaLink="true">https://francoisfiorino.com.br/artigos</guid><category><![CDATA[Oracle Linux]]></category><dc:creator><![CDATA[Francois Fiorino]]></dc:creator><pubDate>Wed, 25 Feb 2026 22:41:41 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/5e16f565-bb8e-4ce0-80b7-c005706f9b85.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Introdução</h2>
<p>Em ambientes corporativos com Oracle Linux, especialmente em cenários com RAC, ASM, SAN ou ambientes virtualizados, é comum surgir a seguinte dúvida: como descobrir quando um disco foi criado ou quando foi apresentado ao sistema operacional?</p>
<p>Quem nunca? precisou expandir um Disk Group no ASM?</p>
<p>A primeira pergunta que vem a cabeça é a seguinte, dentre os 20 discos que tenho aqui, qual devo adicionar, sem sobrepor nenhum disco existe ou gerar algum problema?</p>
<p>Este artigo explica de forma técnica e estruturada as formas de você se certificar e ter segurança antes de conduzir esta atividade, que apesar de simples, se não tiver atenção pode gerar um problemão.</p>
<h2>1. O Linux não guarda a data real de criação do disco</h2>
<p>O Linux não armazena a data física de fabricação do disco nem a data de criação da LUN na storage. Ele registra apenas quando o kernel detectou o dispositivo, quando o device node foi criado e quando o file system foi criado.</p>
<h2>2. Ver quando o disco foi detectado pelo kernel</h2>
<p>Utilize journalctl para consultar logs do kernel, aqui será listado por data de evento:</p>
<p>journalctl -k | grep -i sd</p>
<img src="https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/78ba382a-e721-4d4e-b778-11009ac8a5f8.png" alt="" style="display:block;margin:0 auto" />

<p>journalctl -k --since "2026-02-20" | grep sd</p>
<p>Alternativamente, utilize dmesg:</p>
<p>dmesg | grep -i sd</p>
<img src="https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/667e8782-6b38-424a-a1d6-6639e49571d7.png" alt="" style="display:block;margin:0 auto" />

<p>No meu cenário o disco foi entregue logo pela manhã pela equipe de Linux, então por aqui já consigo localizar qual o disco que posso utilizar.</p>
<h2>3. Ver quando o device foi criado em /dev</h2>
<p>Comando para verificar ctime do device:</p>
<p>stat /dev/sdg</p>
<img src="https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/9db74a69-4dd6-4a21-a0bf-0de3aa04f2b1.png" alt="" style="display:block;margin:0 auto" />

<h2>4. Listar discos com informações técnicas completas</h2>
<p>lsblk -o NAME,SIZE,TYPE,MOUNTPOINT,MODEL,SERIAL</p>
<img src="https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/27596199-aaf8-4276-b0cf-44da55e7bb98.png" alt="" style="display:block;margin:0 auto" />

<p>Esta etapa é fundamental para identificar o <strong>tamanho, a unidade e o tipo de disco</strong>. Note que a sequência exibida corresponde exatamente à ordem em que os discos foram apresentados ao sistema</p>
<p><strong>Recomendação:</strong> Correlacione a data obtida nos passos anteriores ao tamanho exigido para assegurar a rastreabilidade das informações.</p>
<h2>5. Script para ordenar discos por data de criação do device</h2>
<p>Aqui este script absorve diversas informações e ordena do mais antigo para o mais novo, assim fica muito fácil saber qual o disco correto.</p>
<p>disks="\((lsblk -dn -o NAME,TYPE | awk '\)2=="disk"{print \(1}')"<br />journalctl -k -o short-iso --no-pager \<br />| awk -v disks="\)disks" '<br />BEGIN{<br />n=split(disks,a," ");<br />for(i=1;i&lt;=n;i++) want[a[i]]=1;<br />}<br /># exemplos que pegamos:<br /># "... kernel: sdb: ..."<br /># "... kernel: sd 2:0:0:0: [sdb] ..."<br />/ kernel: / {<br />for(d in want){<br />if (!seen[d] &amp;&amp; (\(0 ~ (""d"") || \)0 ~ (" kernel: " d ":")) ){<br />seen[d]=1;<br />first[d]=$1; # timestamp ISO<br />}<br />}<br />}<br />END{<br />for(d in want){<br />if (first[d]!="") print "/dev/" d, first[d];<br />else print "/dev/" d, "NOT_FOUND";<br />}<br />}' \<br />| sort -k2</p>
<img src="https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/3dcc50d6-9744-4ce4-a6d5-f2d7284da677.png" alt="" style="display:block;margin:0 auto" />

<h2>6. Script para ordenar discos conforme evento do kernel por data de criação do device</h2>
<p>journalctl -k -o short-iso --no-pager | egrep -i "Attached SCSI disk|sd[a−z]+| kernel: sd[a-z]+:"</p>
<img src="https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/58d25b99-2165-4e3f-8285-82b7e776a043.png" alt="" style="display:block;margin:0 auto" />

<h2>Conclusão Técnica</h2>
<p>A identificação do momento em que um disco é disponibilizado ao <strong>Oracle Linux</strong> pode ser realizada por meio de múltiplas fontes, como a correlação de logs do kernel (<strong>dmesg</strong>), metadados do <em>filesystem</em>, inventários de storage e históricos do hypervisor. Em ambientes críticos, como <strong>RAC</strong> e <strong>ASM</strong>, é indispensável documentar as alterações e validar a redundância via <strong>multipath</strong> antes da criação de <em>disk groups</em>." Oracle Docs - ASM Storage.</p>
]]></content:encoded></item></channel></rss>