<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Oracle - dbi Blog</title>
	<atom:link href="https://www.dbi-services.com/blog/category/oracle/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.dbi-services.com/blog/category/oracle/</link>
	<description></description>
	<lastBuildDate>Thu, 01 Oct 2026 09:15:41 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/05/cropped-favicon_512x512px-min-32x32.png</url>
	<title>Oracle - dbi Blog</title>
	<link>https://www.dbi-services.com/blog/category/oracle/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>AI meets OEM, let&#8217;s test Oracle AI Database Assistant</title>
		<link>https://www.dbi-services.com/blog/ai-meets-oem-lets-test-oracle-ai-database-assistant/</link>
					<comments>https://www.dbi-services.com/blog/ai-meets-oem-lets-test-oracle-ai-database-assistant/#respond</comments>
		
		<dc:creator><![CDATA[Marc Wagner]]></dc:creator>
		<pubDate>Thu, 01 Oct 2026 09:15:38 +0000</pubDate>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[ai]]></category>
		<category><![CDATA[Oracle Enterprise Manager]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=47287</guid>

					<description><![CDATA[<p>I have been recently blogging on how I have setup Oracle Enterprise Manager 24ai lab, installed an agent and finally configured Oracle AI Database Assistant. It&#8217;s time for me to test it now. Product evolution AI integration in Oracle Enterprise Manager 24ai was quite evolving rapidly. In a nutshell Oracle AI Database Assistant will help [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/ai-meets-oem-lets-test-oracle-ai-database-assistant/">AI meets OEM, let&#8217;s test Oracle AI Database Assistant</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">I have been recently blogging on how I have setup Oracle Enterprise Manager 24ai lab, installed an agent and finally configured Oracle AI Database Assistant. It&#8217;s time for me to test it now.</p>



<span id="more-47287"></span>



<h3>Product evolution</h3>



<p class="wp-block-paragraph">AI integration in Oracle Enterprise Manager 24ai was quite evolving rapidly.</p>



<ul class="wp-block-list">
<li>Ask EM<br>Was first introduced with Enterprise Manager 24ai Release 1 Update 4.<br>Dependent of OCI Ops Insight for the chatbot functionality and processing.</li>



<li>Oracle AI Database Assistant<br>Was introduced in Enterprise Manager 24ai Release 1 Update 10.<br>Replacing Ask EM<br>Use of LLM provider: OCI GenAI or BYO LLM</li>



<li>MCP server<br>Enterprise Manager 24ai Release 1 Update 12 is now integrating a MCP server which will bring a brand of new possibilities.<br>The MCP server is directly built in OEM.</li>



<li>Finally Enterprise Manager 24ai Release 1 Update 13 will bring a new good feature:<br>Autocompletion suggestions. We just write on the prompt &#8220;oracle databases&#8221; and many suggestions might come : &#8220;Show Oracle Databases by average active sessions&#8221; or &#8220;Show Oracle Databases by CPU time&#8221;</li>
</ul>



<h3>In a nutshell</h3>



<p class="wp-block-paragraph">Oracle AI Database Assistant will help me interacting with OEM with Natural-Language questions, like &#8220;What happened to prod?&#8221;. The assistant will then understand my question and retrieves data directly from OMR (Oracle Management Repository). OMR is storing all data for all my targets related to their health, issues and performance.</p>



<p class="wp-block-paragraph">Oracle AI Database Assistant no longer depends on OCI Ops Insight. OCI Ops Insights subscription is not needed any more.</p>



<p class="wp-block-paragraph">Oracle AI Database Assistant will use LLM (Large-Language Model). Multiple LLM are supported:</p>



<ul class="wp-block-list">
<li>You can use the one from Enterprise Manager, so OEM as provider. Oracle AI Database Assistant will access directly OCI Generative AI.</li>



<li>Or you can bring your own LLM Provider. Two Models are supported : OpenAI or Ollama. To use external LLM provider you will need some additional access between OMS server and OCI.</li>
</ul>



<h3>Prerequisites</h3>



<p class="wp-block-paragraph">There is a few prerequisites to configure and use Oracle AI Database Assistant. I will remind them here, but please refer to my other blogs explaining how to configure Oracle AI Database Assistant for guidance with screenshots.</p>



<ul class="wp-block-list">
<li>Log as SYSMAN for configuring Oracle AI Database Assistant</li>



<li>Choice in LLM provider</li>



<li>To use Enterprise Manager provider one account in a supported region is needed
<ul class="wp-block-list">
<li>Japan Central (Osaka): ap-osaka-1</li>



<li>Germany Central (Frankfurt): eu-frankfurt-1</li>



<li>Brazil East (Sao Paulo): sa-saopaulo-1</li>



<li>UK South (London): uk-london-1</li>



<li>US Midwest (Chicago): us-chicago-1</li>
</ul>
</li>



<li>Oracle AI Database Assistant to be enabled in Enterprise Manager
<ul class="wp-block-list">
<li>Activated per default</li>



<li>Command line<br><code>emctl set property -name enable_genai_assistant -value false|true</code></li>
</ul>
</li>



<li>OCI policies so that Enterprise Manager can access the OCI Generative AI service<br><code>allow group to manage opsi-genai-em-session in compartment<br>allow group to use generative-ai-family in compartment</code></li>



<li>An OCI Named Credential for communication with OCI LLM service
<ul class="wp-block-list">
<li>Use of Enterprise Manager LLM provider</li>



<li>OCI Authentication through API key</li>
</ul>
</li>
</ul>



<p class="wp-block-paragraph">With Oracle AI Database Assistant, you can bring your own LLM Provider:</p>



<ul class="wp-block-list">
<li>Bring-Your-Own LLM Providers</li>



<li>OpenAI or Ollama</li>



<li>API Key for LLM provider authentication</li>



<li>Name of the model to be used</li>



<li>Model endpoint URL
<ul class="wp-block-list">
<li>OMS property oracle.sysman.llm.provider.allowedProviderUrls</li>
</ul>
</li>



<li>Network connectivity between OMS and the provider endpoint</li>
</ul>



<p class="wp-block-paragraph">And what about the cost? Oracle AI Database Assistant includes a complimentary allocation of AI tokens for OCI Generative AI models. The cost can be visible through the OCI Ops Insights service.Once the allocated tokens are consumed, extended cost charged to the OCI account based on the AI model and the OCI region. See following oracle documentations:<br><a href="https://www.oracle.com/cloud/price-list/#pricing-ai">https://www.oracle.com/cloud/price-list/#pricing-ai</a><br><a href="https://docs.oracle.com/en-us/iaas/Content/generative-ai/home.htm">https://docs.oracle.com/en-us/iaas/Content/generative-ai/home.htm</a></p>



<h3>Let&#8217;s do some further tests!</h3>



<p class="wp-block-paragraph">Let&#8217;s have fun and test the Oracle AI Database Assistant, now I could configure it.</p>



<h4>Asking for targets&#8230;</h4>



<p class="wp-block-paragraph">I first asked about status summary for all my targets. Answer was coherent with the OEM summary dashboard.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b56599&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b56599" class="wp-block-image size-large wp-lightbox-container"><img fetchpriority="high" decoding="async" width="1024" height="560" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/target_status-1024x560.png" alt="" class="wp-image-47309" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/target_status-1024x560.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/target_status-300x164.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/target_status-768x420.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/target_status-1536x840.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/target_status.png 1603w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<p class="wp-block-paragraph">I then asked to list the target that are down, which of course is ok as the host was not up and running.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b56b73&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b56b73" class="wp-block-image size-full wp-lightbox-container"><img decoding="async" width="519" height="371" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/target_down.png" alt="" class="wp-image-47311" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/target_down.png 519w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/target_down-300x214.png 300w" sizes="(max-width: 519px) 100vw, 519px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<p class="wp-block-paragraph">I then started the lab node.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b570d7&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b570d7" class="wp-block-image size-large wp-lightbox-container"><img decoding="async" width="1024" height="119" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/Start-node-1024x119.png" alt="" class="wp-image-47312" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/Start-node-1024x119.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/Start-node-300x35.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/Start-node-768x90.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/Start-node.png 1278w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b575cc&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b575cc" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="98" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/node-started-1024x98.png" alt="" class="wp-image-47313" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/node-started-1024x98.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/node-started-300x29.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/node-started-768x74.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/node-started.png 1222w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<p class="wp-block-paragraph">I confirmed there is no more target down.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b57ad7&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b57ad7" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="534" height="616" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/target_status-2.png" alt="" class="wp-image-47315" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/target_status-2.png 534w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/target_status-2-260x300.png 260w" sizes="auto, (max-width: 534px) 100vw, 534px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<p class="wp-block-paragraph">I can see that no more targets are down. I took the opportunity to test the language wording, and as we can see, Oracle AI Database Assistant was not able to understand the situation, and my question &#8220;and now?&#8221; referring to make it (we would have been attracted to write him, but let&#8217;s use it <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> ) understand that I wanted the same previous questions was not understandable. We can only use specific OEM language.</p>



<p class="wp-block-paragraph">I could list the targets that are up. What is cool is that I do not need to make full sentences. &#8220;List target up&#8221; was enough for the assistant to understand the question.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b5805d&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b5805d" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="525" height="484" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/target_status-3.png" alt="" class="wp-image-47317" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/target_status-3.png 525w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/target_status-3-300x277.png 300w" sizes="auto, (max-width: 525px) 100vw, 525px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<p class="wp-block-paragraph">I could also ask to filter on host type, which was successfully.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b5858f&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b5858f" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="532" height="479" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/target_status-4.png" alt="" class="wp-image-47324" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/target_status-4.png 532w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/target_status-4-300x270.png 300w" sizes="auto, (max-width: 532px) 100vw, 532px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h4>Asking for documentation&#8230;</h4>



<p class="wp-block-paragraph">As we can see, the assistant will not provide me any OEM documentation, and the expected prompt stick on OEM data model language.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b58ad0&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b58ad0" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="537" height="364" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/docs-query.png" alt="" class="wp-image-47326" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/docs-query.png 537w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/docs-query-300x203.png 300w" sizes="auto, (max-width: 537px) 100vw, 537px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h4>Asking for incidents&#8230;</h4>



<p class="wp-block-paragraph">I could also successfully list open incidents.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b5901c&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b5901c" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="531" height="471" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/incident.png" alt="" class="wp-image-47329" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/incident.png 531w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/incident-300x266.png 300w" sizes="auto, (max-width: 531px) 100vw, 531px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h4>Asking for databases status&#8230;</h4>



<p class="wp-block-paragraph">I could list database target status, and also the assistant understand pdb, pluggable database.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b59591&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b59591" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="533" height="476" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/list-database-1.png" alt="" class="wp-image-47332" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/list-database-1.png 533w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/list-database-1-300x268.png 300w" sizes="auto, (max-width: 533px) 100vw, 533px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b59a25&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b59a25" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="633" height="710" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/list-database-2.png" alt="" class="wp-image-47333" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/list-database-2.png 633w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/list-database-2-267x300.png 267w" sizes="auto, (max-width: 633px) 100vw, 633px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<p class="wp-block-paragraph">Asking the assistant to list databases that have currently problems, I could get as answer&#8230; All databases. We can easily understand that the assistant take word that it understands and that it can put in correlation with any data from the OMR without making a full analyse of the full question.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b59f53&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b59f53" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="299" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/database-problem-1024x299.png" alt="" class="wp-image-47334" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/database-problem-1024x299.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/database-problem-300x88.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/database-problem-768x224.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/database-problem-1536x448.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/database-problem.png 1601w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h4>Asking for critical alerts&#8230;</h4>



<p class="wp-block-paragraph">I could also ask the assistant to list the critical alerts. This was working as expected. I was only a quite of surprised that asking the same for the last 24 hours, I got no data displayed. Which is incoherent knowing I have one running&#8230; We can see that the &#8220;last 24 hours&#8221; has been understood, as the filter &#8220;Last 24 hours&#8221; appeared.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b5a4b8&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b5a4b8" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="519" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-2-1024x519.png" alt="" class="wp-image-47337" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-2-1024x519.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-2-300x152.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-2-768x389.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-2-1536x778.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-2.png 1605w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<p class="wp-block-paragraph">I stopped BITS999P_PDB1 Pluggable Database to see if it will been displayed in the critical alerts.</p>



<p class="wp-block-paragraph">Stopping PDB:</p>



<pre class="brush: sql; gutter: true; first-line: 1; highlight: [1,13,20,24,28]">
[oracle@svl-orap-chz0-cl1n1 ~]$ sqlplus / as sysdba

SQL*Plus: Release 19.0.0.0.0 - Production on Tue Sep 22 13:18:36 2026
Version 19.31.0.0.0

Copyright (c) 1982, 2026, Oracle.  All rights reserved.


Connected to:
Oracle Database 19c EE Extreme Perf Release 19.0.0.0.0 - Production
Version 19.31.0.0.0

SQL&gt; show pdbs

    CON_ID CON_NAME           OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
     2 PDB$SEED               READ ONLY  NO
     3 BITS999P_PDB1          READ WRITE NO

SQL&gt; alter session set container=BITS999P_PDB1;

Session altered.

SQL&gt; alter pluggable database close abort;

Pluggable database altered.

SQL&gt; show pdbs

    CON_ID CON_NAME           OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
     3 BITS999P_PDB1          MOUNTED

</pre>
<br>



<p class="wp-block-paragraph">Let&#8217;s check the critical alerts again.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="300" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-pdb-stopped-1-1024x300.png" alt="" class="wp-image-47340" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-pdb-stopped-1-1024x300.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-pdb-stopped-1-300x88.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-pdb-stopped-1-768x225.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-pdb-stopped-1-1536x451.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-pdb-stopped-1.png 1602w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Working as expected. I could even be more precise filtering on pluggable database only.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b5b6e2&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b5b6e2" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="305" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-pdb-stopped-2-1024x305.png" alt="" class="wp-image-47341" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-pdb-stopped-2-1024x305.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-pdb-stopped-2-300x89.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-pdb-stopped-2-768x229.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-pdb-stopped-2-1536x458.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-pdb-stopped-2.png 1603w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<p class="wp-block-paragraph">I restarted the PDB:</p>



<pre class="brush: sql; gutter: true; first-line: 1; highlight: [1,5]">
SQL&gt; alter pluggable database open;

Pluggable database altered.

SQL&gt; show pdbs

    CON_ID CON_NAME           OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
     3 BITS999P_PDB1          READ WRITE NO
SQL&gt;
</pre>
<br>



<p class="wp-block-paragraph">And I could confirm the alerts disappeared.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b5bc9e&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b5bc9e" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="301" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-pdb-start_again-1-1024x301.png" alt="" class="wp-image-47343" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-pdb-start_again-1-1024x301.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-pdb-start_again-1-300x88.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-pdb-start_again-1-768x226.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-pdb-start_again-1-1536x452.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-pdb-start_again-1.png 1598w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<p class="wp-block-paragraph">Oh by the way, now my Data Guard alerts for last 24 hours filter is working. No idea why.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b5c1fc&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b5c1fc" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="301" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-1-1-1024x301.png" alt="" class="wp-image-47344" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-1-1-1024x301.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-1-1-300x88.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-1-1-768x225.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-1-1-1536x451.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/critical-alerts-1-1.png 1605w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h4>Asking what happened to my database&#8230;</h4>



<p class="wp-block-paragraph">I can ask what happened to a specific database in the last night, and the answer is totally coherent. We can see how the filters are appearing according to the content of my prompt: &#8220;Pluggable Database&#8221;, &#8220;BITS999P_PDB1&#8221;, &#8220;Last 1 day&#8221;.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="239" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/what-happened-database-1-1024x239.png" alt="" class="wp-image-47345" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/what-happened-database-1-1024x239.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/what-happened-database-1-300x70.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/what-happened-database-1-768x179.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/what-happened-database-1-1536x359.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/what-happened-database-1.png 1593w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Asking what happened to the PDB in the last 2 years, the filter automatically applied is &#8220;Last 60 minutes&#8221;. This might be related to a purge parameter, I guess&#8230; I have no explanation so far.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b5c856&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b5c856" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="252" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/what-happened-database-2-1024x252.png" alt="" class="wp-image-47346" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/what-happened-database-2-1024x252.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/what-happened-database-2-300x74.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/what-happened-database-2-768x189.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/what-happened-database-2-1536x377.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/what-happened-database-2.png 1579w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<p class="wp-block-paragraph">Asking what is the status of BITS999P_PDB1, we can see that the assistant did not understand the question, but added some drop-down list, where I can choose data.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b5cd74&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b5cd74" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="305" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/status-of-database-BITS999P_PDB1-1-1024x305.png" alt="" class="wp-image-47347" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/status-of-database-BITS999P_PDB1-1-1024x305.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/status-of-database-BITS999P_PDB1-1-300x89.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/status-of-database-BITS999P_PDB1-1-768x229.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/status-of-database-BITS999P_PDB1-1-1536x458.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/status-of-database-BITS999P_PDB1-1.png 1593w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b5d283&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b5d283" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="306" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/status-of-database-BITS999P_PDB1-2-1024x306.png" alt="" class="wp-image-47348" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/status-of-database-BITS999P_PDB1-2-1024x306.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/status-of-database-BITS999P_PDB1-2-300x90.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/status-of-database-BITS999P_PDB1-2-768x229.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/status-of-database-BITS999P_PDB1-2-1536x459.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/status-of-database-BITS999P_PDB1-2.png 1597w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<p class="wp-block-paragraph">Which will give me the possibility to get some valid information.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b5d79f&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b5d79f" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="303" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/status-of-database-BITS999P_PDB1-3-1024x303.png" alt="" class="wp-image-47349" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/status-of-database-BITS999P_PDB1-3-1024x303.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/status-of-database-BITS999P_PDB1-3-300x89.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/status-of-database-BITS999P_PDB1-3-768x227.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/status-of-database-BITS999P_PDB1-3-1536x454.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/status-of-database-BITS999P_PDB1-3.png 1582w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<p class="wp-block-paragraph">I could also successfully query what happened to the PDB in a time frame. Which is a very good added value.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b5dcbc&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b5dcbc" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="305" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/why-database-down-1024x305.png" alt="" class="wp-image-47350" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/why-database-down-1024x305.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/why-database-down-300x89.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/why-database-down-768x229.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/why-database-down-1536x457.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/why-database-down.png 1606w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h4>Asking for tablespace usage&#8230;</h4>



<p class="wp-block-paragraph">I also asked for pluggable database tablespace usage, for the same PDB. I could get an answer, which really is not that readable.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b5e23e&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b5e23e" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="300" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/tablespace-usage-1024x300.png" alt="" class="wp-image-47352" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/tablespace-usage-1024x300.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/tablespace-usage-300x88.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/tablespace-usage-768x225.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/tablespace-usage-1536x449.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/tablespace-usage.png 1600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<p class="wp-block-paragraph">But the more surprising is the assistant might not be so trustable. Let me explain why. Later on, I could see get coherent results for target status, incidents, but I could not get any information any more for the tablespace usage.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b5e760&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b5e760" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="872" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/prob_tablespace_BITS999P_PDB1_2-1024x872.png" alt="" class="wp-image-47354" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/prob_tablespace_BITS999P_PDB1_2-1024x872.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/prob_tablespace_BITS999P_PDB1_2-300x256.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/prob_tablespace_BITS999P_PDB1_2-768x654.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/prob_tablespace_BITS999P_PDB1_2.png 1128w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<p class="wp-block-paragraph">Even if the metrics are available in OEM, see next pictures.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b5ec73&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b5ec73" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="618" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/prob_tablespace_BITS999P_PDB1_4-1024x618.png" alt="" class="wp-image-47356" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/prob_tablespace_BITS999P_PDB1_4-1024x618.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/prob_tablespace_BITS999P_PDB1_4-300x181.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/prob_tablespace_BITS999P_PDB1_4-768x464.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/prob_tablespace_BITS999P_PDB1_4.png 1169w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b5f173&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b5f173" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" decoding="async" width="1024" height="690" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/prob_tablespace_BITS999P_PDB1_5-1024x690.png" alt="" class="wp-image-47357" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/prob_tablespace_BITS999P_PDB1_5-1024x690.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/prob_tablespace_BITS999P_PDB1_5-300x202.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/prob_tablespace_BITS999P_PDB1_5-768x518.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/prob_tablespace_BITS999P_PDB1_5.png 1304w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h3>To wrap up&#8230;</h3>



<p class="wp-block-paragraph">Following is the pros and cons I see in this new Oracle AI assistant.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6abfb74b5f6b8&quot;}" data-wp-interactive="core/image" data-wp-key="6abfb74b5f6b8" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="1025" height="517" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/image-4.png" alt="" class="wp-image-47359" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/image-4.png 1025w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/image-4-300x151.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/10/image-4-768x387.png 768w" sizes="auto, (max-width: 1025px) 100vw, 1025px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<p class="wp-block-paragraph">When I think it is a good startup, with an assistant that will help to get more quickly the health, issue and performance on any target monitored by OEM, the tool still need to improve the stability and the trust we can put on him.</p>
<p>L’article <a href="https://www.dbi-services.com/blog/ai-meets-oem-lets-test-oracle-ai-database-assistant/">AI meets OEM, let&#8217;s test Oracle AI Database Assistant</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/ai-meets-oem-lets-test-oracle-ai-database-assistant/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Deleting GoldenGate Trail Files via the REST API (OGG-30375)</title>
		<link>https://www.dbi-services.com/blog/deleting-goldengate-trail-files-via-the-rest-api-ogg-30375/</link>
					<comments>https://www.dbi-services.com/blog/deleting-goldengate-trail-files-via-the-rest-api-ogg-30375/#respond</comments>
		
		<dc:creator><![CDATA[Julien Delattre]]></dc:creator>
		<pubDate>Thu, 01 Oct 2026 06:23:00 +0000</pubDate>
				<category><![CDATA[GoldenGate]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[26]]></category>
		<category><![CDATA[26ai]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[ogg]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[REST-API]]></category>
		<category><![CDATA[trail]]></category>
		<category><![CDATA[Troubleshooting]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=47085</guid>

					<description><![CDATA[<p>When automating your GoldenGate deployments, or tearing down a test environment, handling trail files is important. In fact, deleting an extract or a replicat does not delete the trail files it was writing to or reading from. It leaves the trail resource itself behind too, causing confusion (or worse) later. Indeed, a fresh extract writing [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/deleting-goldengate-trail-files-via-the-rest-api-ogg-30375/">Deleting GoldenGate Trail Files via the REST API (OGG-30375)</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">When automating your GoldenGate deployments, or tearing down a test environment, handling trail files is important. In fact, deleting an extract or a replicat does not delete the trail files it was writing to or reading from. It leaves the trail resource itself behind too, causing confusion (or worse) later.</p>



<p class="wp-block-paragraph">Indeed, a fresh extract writing to the same trail name/path keeps appending after the old sequence numbers instead of restarting at <code>000000000</code>. A fresh replicat starts reading from <code>000000000</code> by default. If you don’t remove the trail files when re-creating an extract and replicat pair, the extract will do its job. However, the new replicat has no way to tell leftover files apart from new ones. It will read whatever is still sitting in <code>000000000</code> and onward as if it were live data.</p>



<p class="wp-block-paragraph">The <code>adminclient</code> does have a command for this, <code>PURGE EXTTRAIL</code>, but it only works once nothing is using the trail anymore:</p>



<pre class="wp-block-code"><code>OGG (http://vmogg:7810 ogg_test_01) 3&gt; purge exttrail PDB1/aa

Error: Cannot purge trail 'PDB1/aa', the trail is in use by EXTRACT 'EOGG375'</code></pre>



<p class="wp-block-paragraph">From the <code>adminclient</code>, you need to delete the extract first. Then, <code>PURGE EXTTRAIL</code> removes every sequence file and the trail resource:</p>



<pre class="wp-block-code"><code>OGG (http://vmogg:7810 ogg_test_01) 2&gt; purge exttrail PDB1/aa
2026-09-20T13:52:35Z  INFO    OGG-00957  Purged old extract file 'PDB1/aa000000000'. Purge rule: Purging all files for trail 'PDB1/aa'.
2026-09-20T13:52:35Z  INFO    OGG-00957  Purged old extract file 'PDB1/aa000000001'. Purge rule: Purging all files for trail 'PDB1/aa'.
&#091;...]
2026-09-20T13:52:35Z  INFO    OGG-00957  Purged old extract file 'PDB1/aa000000035'. Purge rule: Purging all files for trail 'PDB1/aa'.</code></pre>



<p class="wp-block-paragraph">So from an interactive session, <code>PURGE EXTTRAIL</code> is the easy way. But when automating, the REST API is often easier to handle, so let’s see how it should be done with it.</p>



<h2 id="deleting-a-trail" class="wp-block-heading">Deleting a trail</h2>



<p class="wp-block-paragraph">Calling the <a href="https://docs.oracle.com/en/database/goldengate/core/26/oggra/rest-endpoints.html" target="_blank" rel="noopener noreferrer"><code>DELETE /services/{version}/trails/{trail}</code></a> endpoint seems like a good call. Let’s try this first, on a trail still attached to a stopped (but not deleted) extract, using the <code>delete_trail</code> method of the <a href="https://juliendelattre.com/tools/ogg-python-client/" target="_blank" rel="noopener noreferrer"><code>oggrestapi</code></a> Python package:</p>



<pre class="wp-block-code"><code>from oggrestapi import OGGRestAPI

client = OGGRestAPI(
    url="http://vmogg:7810",
    username="ogg",
    password="ogg"
)

client.delete_trail(trail="aa", path_query="PDB1")</code></pre>



<pre class="wp-block-code"><code>RuntimeError: ERROR (code 400) - http://vmogg:7810/services/v2/trails/aa: Unable to delete trail resource 'PDB1/aa' because there are processes using it.</code></pre>



<p class="wp-block-paragraph">This is expected: a trail still referenced by a process cannot be deleted. Delete the extract, then retry:</p>



<pre class="wp-block-code"><code>RuntimeError: ERROR (code 500) - http://vmogg:7810/services/v2/trails/aa: There was a problem updating the Administration Service resources.</code></pre>



<p class="wp-block-paragraph">On a <strong>non-empty</strong> trail, once the process that was using it is gone, this call still fails with an <code>OGG-30375</code> error (code <code>500</code>) and a generic <code>There was a problem updating the Administration Service resources</code>.</p>



<p class="wp-block-paragraph">To delete a trail with the GoldenGate REST API, you must first empty the trail sequence. Once the trail sequence is empty, the trail resource is automatically deleted. The method <code>delete_trail_sequence_collection()</code>, mapping <a href="https://docs.oracle.com/en/database/goldengate/core/26/oggra/rest-endpoints.html" target="_blank" rel="noopener noreferrer"><code>DELETE /services/{version}/trails/{trail}/sequences</code></a>, does this in one call: it takes a sequence range, <code>first</code> and <code>last</code>, as named keyword arguments:</p>



<pre class="wp-block-code"><code>result = client.delete_trail_sequence_collection(
    trail="aa",
    path="PDB1",
    first=0,
    last=999999999
)
&#091;(m&#091;"code"], m&#091;"title"]) for m in result&#091;"messages"]]</code></pre>



<pre class="wp-block-code"><code>&#091;('OGG-30282', "Using actual highest sequence number '000000001' instead of last sequence number '999999999' specified in the request for trail 'PDB1/aa'."), ('OGG-30277', "Successfully deleted '2' of '2' trail sequences for trail 'PDB1/aa'."), ('OGG-30282', "Using actual highest sequence number '000000001' instead of last sequence number '999999999' specified in the request for trail 'PDB1/aa'."), ('OGG-30277', "Successfully deleted '2' of '2' trail sequences for trail 'PDB1/aa'.")]</code></pre>



<p class="wp-block-paragraph">An oversized value for <code>last</code> is a safe way to delete “everything”. Both <code>first</code> and <code>last</code> are required: omitting either one fails with an <code>OGG-12104</code> error (no “from <code>first</code> to the end” shortcut).</p>



<h2 id="background-operations-of-purge-exttrail" class="wp-block-heading">Background operations of <code>PURGE EXTTRAIL</code></h2>



<p class="wp-block-paragraph"><code>PURGE EXTTRAIL</code> from the <code>adminclient</code> does not call this endpoint. Tracing its requests through <code>restapi.log</code> shows it calling the generic command endpoint instead, <code>POST /services/{version}/commands/execute</code>, equivalent of the <code>execute_command</code> method, with a <code>purge</code> command:</p>



<pre class="wp-block-code"><code>data = {
    "name": "purge",
    "purgeType": "trails",
    "trails": &#091;{"name": "aa", "path": "PDB1"}],
    "useCheckpoints": False,
    "keep": &#091;{"type": "min", "units": "files", "value": 0}],
}

result = client.execute_command(data=data)
&#091;(m&#091;"code"], m&#091;"title"]) for m in result&#091;"messages"]]</code></pre>



<pre class="wp-block-code"><code>&#091;('OGG-00957', "Purged old extract file 'PDB1/aa000000000'. Purge rule: Purging all files for trail 'PDB1/aa'."), ('OGG-00957', "Purged old extract file 'PDB1/aa000000001'. Purge rule: Purging all files for trail 'PDB1/aa'.")]</code></pre>



<p class="wp-block-paragraph"><code>keep</code> with <code>value: 0</code> means “keep zero files”, or <em>purge everything</em>. It has the same end result as <code>delete_trail_sequence_collection()</code>, but with one <code>OGG-00957</code> message per file instead of the range-clamp/success pair.</p>



<p class="wp-block-paragraph">Whether it’s from the <code>adminclient</code> or with the REST API, the procedure to delete trail files is the same: make sure processes are deleted before deleting their trail files, and delete them one by one or with a purge command.</p>
<p>L’article <a href="https://www.dbi-services.com/blog/deleting-goldengate-trail-files-via-the-rest-api-ogg-30375/">Deleting GoldenGate Trail Files via the REST API (OGG-30375)</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/deleting-goldengate-trail-files-via-the-rest-api-ogg-30375/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Archiving 5 TB from Oracle into SQL Server: a migration logbook (part 1)</title>
		<link>https://www.dbi-services.com/blog/archiving-5-tb-from-oracle-into-sql-server-a-migration-logbook-part-1/</link>
					<comments>https://www.dbi-services.com/blog/archiving-5-tb-from-oracle-into-sql-server-a-migration-logbook-part-1/#respond</comments>
		
		<dc:creator><![CDATA[Louis Tochon]]></dc:creator>
		<pubDate>Tue, 29 Sep 2026 19:37:18 +0000</pubDate>
				<category><![CDATA[Database management]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=47204</guid>

					<description><![CDATA[<p>Loading 5 TB from Oracle into SQL Server with SSMA: type overflows, heaps, and the settings that took 788 rows/s to 42,170.</p>
<p>L’article <a href="https://www.dbi-services.com/blog/archiving-5-tb-from-oracle-into-sql-server-a-migration-logbook-part-1/">Archiving 5 TB from Oracle into SQL Server: a migration logbook (part 1)</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">680,000 rows in 863 seconds. That is 788 rows per second, and the table I was loading holds 229,881,717 of them.</p>



<p class="wp-block-paragraph">Eighty-one hours. For one table. There were five more behind it.</p>



<p class="wp-block-paragraph">SSMA is well documented but migrations at this scale are not done often enough to have plenty of materials. Most of what you find is either a step-by-step guide against a sample database, or a vendor case study with no numbers in it. This post has the numbers, in the order I actually got them, including the ones I got wrong first.</p>



<p class="wp-block-paragraph">To keep my sanity through a long and intricate migration, I kept a logbook. This first part is about getting the data across: the brief, the type negotiation, and the settings that took the load from 788 rows per second to 42,170. Part 2 picks up exactly where this one stops, with 3.2 TB sitting in heaps and not a single index on it.</p>



<h2 id="h-day-1-the-brief-and-the-one-sentence-that-mattered" class="wp-block-heading">Day 1. The brief, and the one sentence that mattered</h2>



<p class="wp-block-paragraph">An Oracle 19c production database running an asset management package, to be archived into SQL Server 2025 Standard Edition. Roughly 5,600 tables, 4,800 views, a little under 5 TB depending on how you count (more on that later).</p>



<p class="wp-block-paragraph">Three facts shaped everything that followed.</p>



<p class="wp-block-paragraph">The target is<strong><span style="text-decoration: underline"> read-only</span></strong>. Nothing will ever write to it once the load is finished, because the whole point of the exercise is to keep fifteen years of records available to people who need to look something up rather than to keep an application running. Auditors come by, rarely and unpredictably, to find one specific row.</p>



<p class="wp-block-paragraph">That is the entire performance requirement, and it decided more of this project than any measurement did. It is why the indexes are broad rather than targeted at known queries, why PAGE compression costs nothing here, why 25,000 triggers went straight in the bin, and why two views that take thirty seconds are perfectly acceptable. Every one of those decisions comes back later in this series.</p>



<p class="wp-block-paragraph">The freeze has no deadline. This is unusual enough to state plainly. Most migrations are built around a cutover window measured in hours, and every technical decision bends to it. Here the source was frozen since the beginning and simply stayed frozen.</p>



<p class="wp-block-paragraph">The data travels in two hops, which becomes the story of the whole load:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1024" height="171" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-43.png" alt="" class="wp-image-47208" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-43.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-43-300x50.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-43-767x128.png 767w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h3 id="h-getting-in-without-asking-for-the-keys" class="wp-block-heading">Getting in without asking for the keys</h3>



<p class="wp-block-paragraph">The source is critical production, so the migration account got the minimum that actually works: <code>CREATE SESSION</code>, dictionary read, and <code>SELECT </code>on the tables in scope.</p>



<p class="wp-block-paragraph">SSMA also asks for <code>CREATE ANY PROCEDURE</code>, <code>CREATE ANY TYPE</code> and <code>CREATE ANY TRIGGER</code>. Those three serve server-side extraction and SSMA’s own testing feature and at the end of the project a single <code>DROP USER &lt;user_name&gt; CASCADE</code> removes the whole thing.</p>



<p class="wp-block-paragraph">There is a decision hiding here that is worth making deliberately.<code> SELECT ANY TABLE</code> is convenient and gives your account read access to the entire database, including schemas you are not migrating. Granting <code>SELECT </code>table by table on the schemas in scope is more work and produces an auditable perimeter.</p>



<h2 id="h-day-2-negotiating-with-numbers" class="wp-block-heading">Day 2. Negotiating with numbers</h2>



<p class="wp-block-paragraph">We agreed the type mapping with the client before converting anything, which I recommend for the political reasons as much as the technical ones:</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Oracle</th><th>SQL Server</th></tr></thead><tbody><tr><td>NUMBER(38) to NUMBER(*)</td><td>FLOAT</td></tr><tr><td>NUMBER(19) to NUMBER(38)</td><td>DECIMAL[19-38]</td></tr><tr><td>NUMBER(11) to NUMBER(18)</td><td>BIGINT</td></tr><tr><td>NUMBER(5) to NUMBER(10)</td><td>INT</td></tr><tr><td>NUMBER(1) to NUMBER(4)</td><td>SMALLINT</td></tr><tr><td>DATE</td><td>DATETIME2(0)</td></tr><tr><td>XMLTYPE</td><td>XML</td></tr><tr><td>VARCHAR2(n CHAR)</td><td>NVARCHAR(n)</td></tr><tr><td>CHAR(n CHAR)</td><td>NCHAR(n)</td></tr></tbody></table></figure>



<h3 id="h-38-digits-against-51" class="wp-block-heading">38 digits against 51</h3>



<p class="wp-block-paragraph">Then the conversions started failing on decimal overflow, and the reason is more interesting than &#8220;<em>the numbers were too big</em>&#8220;.</p>



<p class="wp-block-paragraph">Oracle <code>NUMBER </code>without precision is a <strong>floating decimal:</strong> 38 significant digits, with an exponent range running from 1e-130 to just under 1e126. SQL Server <code>DECIMAL </code>is <strong>fixed point</strong>: the precision bounds the magnitude. <code>DECIMAL(38,0)</code> stops at 1e38 and there is no exponent to escape with.</p>



<p class="wp-block-paragraph">So the values that broke were not unusually precise, they were unusually <em>large</em>. A value carrying 51 digits and two significant figures is perfectly ordinary in Oracle, sails through every constraint it meets on the way out, and then has no <code>DECIMAL </code>representation waiting for it at the other end.</p>



<p class="wp-block-paragraph">The answer is <code>FLOAT</code>, which is also a floating type and reaches ±1.79e308. Eleven tables were reloaded after switching the mapping.</p>



<p class="wp-block-paragraph"><strong><span style="text-decoration: underline">Be careful</span></strong> what you promise the client here, because <code>FLOAT </code>keeps <span style="text-decoration: underline">15 significant digits, not 38</span>. For the values that actually overflowed, large magnitude and few significant figures, the loss is zero. For a value in those columns carrying more than 15 significant digits, the loss is real. That is countable rather than arguable, so count it before you write the reassuring email.</p>



<h3 id="h-25-000-triggers-none-converted" class="wp-block-heading">25,000 triggers, none converted</h3>



<p class="wp-block-paragraph">The source carried roughly 25,000 triggers, almost all in one schema. I converted none of them and unticked them all before <em>Convert Schema</em>.</p>



<p class="wp-block-paragraph">The reasoning fits in one line: on a read-only database, a trigger never fires. Converting and testing 25,000 objects that will never execute would have consumed weeks and produced nothing.</p>



<p class="wp-block-paragraph">Tables went first, with their types and sequences, to unblock the data migration. Packages, views and procedures came later. Indexes are not a separate step: SSMA converts them alongside their table, turning bitmap indexes into nonclustered ones, handling function-based indexes case by case, and skipping <code>XMLTYPE </code>indexes entirely.</p>



<p class="wp-block-paragraph">Then 103 tables failed extraction with <code>ORA-00904</code>, all because of hidden <code>SYS_C…$</code> columns left behind by function-based indexes. I had already set &#8220;<em>Ignore hidden system columns</em>&#8221; to <code>Yes</code>, which is why this took longer than it should have: in our project that option governed schema conversion and did not stop the extraction from asking for the column. The fix is a custom select that aliases <code>NULL </code>into the missing name (see my <a href="https://www.dbi-services.com/blog/fixing-ora-00904-on-oracle-hidden-columns-during-ssma-data-migration/">previous blog about this problem</a>).</p>



<h2 id="h-day-3-turning-everything-off" class="wp-block-heading">Day 3. Turning everything off</h2>



<p class="wp-block-paragraph">The loading method is three switches and a recovery model.</p>



<p class="wp-block-paragraph">Disable the nonclustered indexes. A disabled index stores nothing and is not maintained row by row during the load.</p>



<p class="wp-block-paragraph">Disable the foreign keys with <code>NOCHECK CONSTRAINT</code>.</p>



<p class="wp-block-paragraph">Drop the clustered primary keys on the largest tables and load into heaps.</p>



<p class="wp-block-paragraph">Then set the recovery model to <code>SIMPLE</code>. With heaps and bulk insert, logging is already minimal.</p>



<p class="wp-block-paragraph">The script that does this across every schema needs to be restartable and needs to log what it did. A load that runs for days will be interrupted, and you want to know exactly which of 22&#8217;000 indexes were disabled when it was.</p>



<p class="wp-block-paragraph">Script to disable all nonclustered indexes:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
USE &lt;DB_NAME&gt;;  
GO
  
  
IF OBJECT_ID(N&#039;tempdb..#Schemas&#039;) IS NOT NULL DROP TABLE #Schemas;
CREATE TABLE #Schemas (schema_name sysname PRIMARY KEY);
  
INSERT INTO #Schemas (schema_name) VALUES (N&#039;&lt;SCHEMA_NAME&gt;&#039;); --Insert your schema name here
    ;
  
SELECT schema_name AS schemas_a_traiter FROM #Schemas;
GO
  
  
-- Disable all NC Indexes
 
SET NOCOUNT ON;
DECLARE @Execute bit = 0;   -- 0 = preview ; 1 = execute
  
DECLARE @cmd nvarchar(max);
DECLARE @n   int = 0;
  
DECLARE idx_cur CURSOR LOCAL FAST_FORWARD FOR
    SELECT N&#039;ALTER INDEX &#039; + QUOTENAME(i.name)
         + N&#039; ON &#039; + QUOTENAME(s.name) + N&#039;.&#039; + QUOTENAME(t.name)
         + N&#039; DISABLE;&#039;
    FROM   sys.indexes  i
    JOIN   sys.tables   t ON i.object_id = t.object_id
    JOIN   sys.schemas  s ON t.schema_id = s.schema_id
    WHERE  s.name IN (SELECT schema_name FROM #Schemas)
      AND  i.type_desc            in (N&#039;NONCLUSTERED&#039;) 
      AND  i.is_disabled          = 0                
    ORDER BY s.name, t.name, i.name;
  
OPEN idx_cur;
FETCH NEXT FROM idx_cur INTO @cmd;
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @n += 1;
    PRINT @cmd;
    IF @Execute = 1
    BEGIN
        BEGIN TRY
            EXEC sys.sp_executesql @cmd;
        END TRY
        BEGIN CATCH
            PRINT N&#039;   -- ECHEC : &#039; + ERROR_MESSAGE();
        END CATCH
    END
    FETCH NEXT FROM idx_cur INTO @cmd;
END
CLOSE idx_cur;
DEALLOCATE idx_cur;
  
PRINT N&#039;---&#039;;
PRINT CONVERT(nvarchar(10), @n) + N&#039; index nonclustered &#039;
    + CASE WHEN @Execute = 1 THEN N&#039;disabled.&#039; ELSE N&#039;te be disabled (preview).&#039; END;
GO
  
  
----------------------------------------------
 
 
SET NOCOUNT ON;
DECLARE @Execute bit = 0;   -- 0 = preview ; 1 = executer
  
DECLARE @cmd nvarchar(max);
DECLARE @n   int = 0;
  
DECLARE fk_cur CURSOR LOCAL FAST_FORWARD FOR
    SELECT N&#039;ALTER TABLE &#039; + QUOTENAME(s.name) + N&#039;.&#039; + QUOTENAME(t.name)
         + N&#039; NOCHECK CONSTRAINT &#039; + QUOTENAME(fk.name) + N&#039;;&#039;
    FROM   sys.foreign_keys fk
    JOIN   sys.tables  t ON fk.parent_object_id = t.object_id
    JOIN   sys.schemas s ON t.schema_id = s.schema_id
    WHERE  s.name IN (SELECT schema_name FROM #Schemas)
      AND  fk.is_disabled = 0;
  
OPEN fk_cur;
FETCH NEXT FROM fk_cur INTO @cmd;
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @n += 1;
    PRINT @cmd;
    IF @Execute = 1
    BEGIN
        BEGIN TRY EXEC sys.sp_executesql @cmd; END TRY
        BEGIN CATCH PRINT N&#039;   -- FAILED: &#039; + ERROR_MESSAGE(); END CATCH
    END
    FETCH NEXT FROM fk_cur INTO @cmd;
END
CLOSE fk_cur;
DEALLOCATE fk_cur;
  
PRINT N&#039;---&#039;;
PRINT CONVERT(nvarchar(10), @n) + N&#039; FK &#039;
    + CASE WHEN @Execute = 1 THEN N&#039;disabled.&#039; ELSE N&#039;to be disabled (preview).&#039; END;
GO 
</pre></div>


<p class="wp-block-paragraph">There is a second script that puts all of this back, with PAGE compression, once the data is in. It belongs with the rebuild rather than with the load, so it is in part 2.</p>



<h2 class="wp-block-heading">Day 4. ×53, on the same architecture</h2>



<p class="wp-block-paragraph">The first load ran <strong>client-side</strong>: the hop server reads from Oracle and writes to SQL Server.</p>



<p class="wp-block-paragraph">On the SQL Server side the dominant wait was <code>ASYNC_NETWORK_IO</code>, which is the engine telling you it has finished its work and is sitting there waiting for the next batch to arrive. Meanwhile CPU and memory on the hop VM stayed low throughout. Nothing anywhere in the chain was short of power; the pipeline was simply underfed.</p>



<p class="wp-block-paragraph">The answer for this was not a different architecture (with for example a linked server directly from Oracle to SQL Server), it was three settings on the one I already had.</p>



<p class="wp-block-paragraph">Load into heaps with the nonclustered indexes disabled. Parallelise <strong>across tables</strong>, not within one, which is the part most people have backwards about SSMA: Thread Count 14 with <code>Table lock = No</code>, because <code>TABLOCK </code>plus multithreading deadlocks. Batch size at 200&#8217;000.</p>



<p class="wp-block-paragraph">Measured with the two-timestamp method: <strong>7,000,000</strong> <strong>rows in 166 seconds, about 42,170 rows per second</strong>. Against 788, that is ×53.</p>



<p class="wp-block-paragraph">It is worth being explicit about why write-side changes fixed a network wait, because the two do not obviously connect. Of the three levers only one touches writing. Parallelising across tables fills a pipe that was carrying a single stream and fast writes remove the back-pressure that was leaving the sender idle.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="598" height="348" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-44.png" alt="" class="wp-image-47228" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-44.png 598w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-44-300x175.png 300w" sizes="auto, (max-width: 598px) 100vw, 598px" /></figure>



<h3 class="wp-block-heading">Two volumetry traps</h3>



<p class="wp-block-paragraph">Ranking tables by <code>dba_segments </code>with <code>segment_type = 'TABLE' </code><strong>ignores LOBs</strong>, which live in their own segment. One table that looked unremarkable carried 123 GB of LOB. Redo the ranking with LOB segments included before you plan anything. And row count does not rank the same way as volume. One table held 2.8 billion rows in 67 GB. Another held a tenth of that in fourteen times the space.</p>



<h2 class="wp-block-heading">What I would tell the next person, about the load</h2>



<p class="wp-block-paragraph">The bottleneck was the feed rate rather than the hardware. 788 rows per second, with <code>ASYNC_NETWORK_IO </code>at the top of the wait list, on a chain where nothing was short of CPU or memory. Three settings took it to 42,170: heaps, disabled indexes and parallelism across tables. Reach for the settings before you reach for a new architecture, because the new architecture takes a week to build and may not be the thing that was slow.</p>



<p class="wp-block-paragraph">On types, the failure was one of magnitude and not of precision, which is worth knowing before you try to diagnose it. Oracle <code>NUMBER </code>is a floating decimal whose exponent runs far past anything <code>DECIMAL </code>can address, so a value with 51 digits and two significant figures breaks a conversion that a value with 38 significant digits survives without trouble. And when you move those columns to <code>FLOAT</code>, count what you are actually giving up before you write the email saying nothing was lost.</p>



<p class="wp-block-paragraph">At this point the data is across and the database is useless. Every nonclustered index is disabled, the largest tables have no primary key, the foreign keys are off, and none of the four thousand views compile. <strong>Part 2</strong> is about putting all of that back.</p>
<p>L’article <a href="https://www.dbi-services.com/blog/archiving-5-tb-from-oracle-into-sql-server-a-migration-logbook-part-1/">Archiving 5 TB from Oracle into SQL Server: a migration logbook (part 1)</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/archiving-5-tb-from-oracle-into-sql-server-a-migration-logbook-part-1/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Archiving Oracle databases with SIARD Suite</title>
		<link>https://www.dbi-services.com/blog/archiving-oracle-databases-with-siard-suite/</link>
					<comments>https://www.dbi-services.com/blog/archiving-oracle-databases-with-siard-suite/#respond</comments>
		
		<dc:creator><![CDATA[Alain Klein]]></dc:creator>
		<pubDate>Tue, 29 Sep 2026 15:46:10 +0000</pubDate>
				<category><![CDATA[Oracle]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=46428</guid>

					<description><![CDATA[<p>One of our customers needed to archive a 4T Oracle database. Several options have been chosen, one of them being archiving the data to SIARD format using SIARD Suite from Swiss Federal Archives. This blog posts explains the basics: what SIARD Suite is, how it works, and examples in command line mode. Meeting SIARD Suite [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/archiving-oracle-databases-with-siard-suite/">Archiving Oracle databases with SIARD Suite</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph" id="h-"></p>



<h2 id="h-one-of-our-customers-needed-to-archive-a-4t-oracle-database-several-options-have-been-chosen-one-of-them-being-archiving-the-data-to-siard-format-using-siard-suite-from-swiss-federal-archives-this-blog-posts-explains-the-basics-what-siard-suite-is-how-it-works-and-examples-in-command-line-mode" class="wp-block-heading">One of our customers needed to archive a 4T Oracle database. Several options have been chosen, one of them being archiving the data to SIARD format using SIARD Suite from Swiss Federal Archives. This blog posts explains the basics: what SIARD Suite is, how it works, and examples in command line mode.</h2>



<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 id="h-meeting-siard-suite" class="wp-block-heading">Meeting SIARD Suite</h3>



<p class="wp-block-paragraph"><a href="https://www.bar.admin.ch/en/siard-suite-en" data-type="link" data-id="https://www.bar.admin.ch/en/siard-suite-en">SIARD Suite</a> is software developed and made freely available by Swiss Federal Archives for long-term archiving of data stored in the following relational database management systems:</p>



<ul class="wp-block-list">
<li>MS Access 2007 or newer</li>



<li>DB/2 or newer</li>



<li>MySQL (or MariaDB) 5.5 or newer</li>



<li>Oracle 10 or newer</li>



<li>PostgreSQL 11 or newer</li>



<li>SQL Server 2012 or newer</li>
</ul>



<p class="wp-block-paragraph">Data is extracted and stored in a custom <a href="https://www.bar.admin.ch/dam/en/sd-web/e13OBixbrV01/en_siard_formatbeschreibung.pdf">SIARD</a> format based on XML, SQL:2008, UNICODE and ZIP64 standards, thus enabling long-term storage of data archives (often required by audit projects, governance and legal frameworks).</p>



<p class="wp-block-paragraph">Archive data files can later on be used to load the data in a new database if required.</p>



<p class="wp-block-paragraph">The software can be downloaded from GitHub through this <a href="https://github.com/sfa-siard/siard-suite/releases">link</a>.</p>



<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 id="h-concepts" class="wp-block-heading">Concepts</h3>



<p class="wp-block-paragraph">Archived data is stored in an XML files collection conforming to SQL:2008 standard.</p>



<p class="wp-block-paragraph">Code and custom application objects are not extracted. However, table and columns definition are exported as XML metadata. BLOBs and CLOBs are stored as binary files outside of the XML files.</p>



<p class="wp-block-paragraph">To unload more metadata, database features can be used such as Data Pump or DBMS_METADATA package procedures/functions when dealing with an Oracle database as the source database.</p>



<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 id="h-basic-principles-of-database-archiving-with-siard-suite" class="wp-block-heading">Basic principles of database archiving with SIARD Suite</h3>



<p class="wp-block-paragraph">The following list summarizes what to take into account and anticipate before starting a new archiving project:</p>



<ul class="wp-block-list">
<li>clearly define the data archiving scope: which tables, views or schemas, which records, and so on</li>



<li>create a dedicated user with the least privileges (typically read-only) on the objects belonging to the archiving scope</li>



<li>create views in case you need to filter data (columns and/or rows) to be archived</li>



<li>the source database must be frozen during archiving jobs (use whatever features the source database provides to bring the database in such a state)</li>



<li>to check thoroughly the end result of the archiving jobs, load the archive data into another database</li>



<li>define additional metadata to archive based on your specific business needs ; this will later (think of several years in the future) lead to a better understanding of data archives : PL/SQL code, application documentation, data model entity-relation diagrams, and so on.</li>
</ul>



<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 id="h-how-siard-suite-works" class="wp-block-heading">How SIARD Suite works</h3>



<p class="wp-block-paragraph">SIARD Suite is a JavaFX application, requiring JRE17 with JavaFX support in its latest release (v2.2.167) and can be used on Windows, Linux and MacOS.</p>



<p class="wp-block-paragraph">Based on our experience, it is recommended to download the binary file with the right Java version embedded (always better not having to manage a separate stack).</p>



<p class="wp-block-paragraph">There are two interfaces available:</p>



<ul class="wp-block-list">
<li>Graphical User Interface (GUI)</li>



<li>Command Line Interface (CLI)</li>
</ul>



<p class="wp-block-paragraph">Take care, if you are planning to use the CLI, to not use &#8220;native&#8221; binaries because they don&#8217;t include the CLI.</p>



<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 id="h-application-installation" class="wp-block-heading">Application installation</h4>



<p class="wp-block-paragraph">Binary files are downloaded as ZIP files and can be installed anywhere on your system. For our customer project, we decided to create a separate Virtual Machine with adequate storage space thanks to the high performance link between the two VMs.</p>



<p class="wp-block-paragraph">Once SIARD Suite has been unzipped, the directory looks like:</p>



<pre class="wp-block-code"><code>SIARD-Suite.2.2.161-linux
├── bin
├── conf
├── legal
├── lib
└── release</code></pre>



<p class="wp-block-paragraph">As expected, the bin directory contains all relevant utilities to perform the archiving or loading jobs:</p>



<pre class="wp-block-code"><code>SIARD-Suite.2.2.161-linux/bin
├── java
├── jfr
├── jrunscript
├── keytool
├── siard-from-db
├── siard-from-db.bat
├── SIARD-Suite
├── SIARD-Suite.bat
├── siard-to-db
└── siard-to-db.bat
</code></pre>



<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><td><strong>Utility name</strong></td><td><strong>Description</strong></td></tr><tr><td>SIARD-Suite</td><td>To launch the GUI</td></tr><tr><td>siard-from-db</td><td>To launch archiving jobs in CLI; several parameters can be provided to customize some aspects of the jobs</td></tr><tr><td>siard-to-db</td><td>To launch a loading job in CLI</td></tr></tbody></table></figure>



<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 id="h-command-line-interface" class="wp-block-heading">Command line interface</h3>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 id="h-siard-from-db-utility" class="wp-block-heading">&#8216;siard-from-db&#8217; utility</h4>



<p class="wp-block-paragraph">Using the &#8216;siard-from-db&#8217; utility is quite straightforward since there is no fine grained configurations/options/parameters to choose from:</p>



<pre class="wp-block-code"><code>siard-from-db &#091;-h] | &#091;-o] &#091;-v] &#091;-l=&lt;login timeout&gt;] &#091;-q=&lt;query timeout&gt;] &#091;-i=&lt;import
meta data&gt;] &#091;-x=&lt;external lob folder&gt;] &#091;-m=&lt;mime type&gt;] -j=&lt;JDBC URL&gt; -u=&lt;database
user&gt; -p=&lt;database password&gt; -s=&lt;siard file&gt; -e=&lt;export meta data&gt;"</code></pre>



<p class="wp-block-paragraph">The following table, pulled from the SIARD Suite documentation, details each parameter&#8217;s goal and usage pattern:</p>



<div class="wp-block-media-text is-stacked-on-mobile"><figure class="wp-block-media-text__media"><img loading="lazy" decoding="async" width="813" height="1024" src="http://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/08/siard-from-db-parameters-813x1024.png" alt="" class="wp-image-46444 size-full" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/08/siard-from-db-parameters-813x1024.png 813w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/08/siard-from-db-parameters-238x300.png 238w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/08/siard-from-db-parameters-768x967.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/08/siard-from-db-parameters-1220x1536.png 1220w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/08/siard-from-db-parameters-1627x2048.png 1627w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/08/siard-from-db-parameters.png 1878w" sizes="auto, (max-width: 813px) 100vw, 813px" /></figure><div class="wp-block-media-text__content">
<p class="wp-block-paragraph"></p>
</div></div>



<p class="wp-block-paragraph">For instance, to extract the Oracle HR sample schema, we could use the following command:</p>



<pre class="wp-block-code"><code>./siard-from-db -l=10 -q=120 \
-j=jdbc:oracle:thin:@&#091;hostname|ip]:listening_port/pdb_name \
-u=hr -p=hr_password -s=hr.siard -e=hr_metadata.xml</code></pre>



<p class="wp-block-paragraph">The archive job produces the following two files:</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><td>File name</td><td>Content</td></tr><tr><td>hr.siard</td><td>Archive file in ZIP format ; content can be listed with &#8216;unzip -l hr.siard&#8217; and extracted with &#8216;unzip hr.siard&#8217;</td></tr><tr><td>hr_metadata.xml</td><td>Contains the HR schema metadata exported</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Running the Linux &#8216;file&#8217; command on the &#8216;hr.siard&#8217; file confirms it is a Zip archive file:</p>



<pre class="wp-block-code"><code>file hr.siard
hr.siard: Zip archive data, at least v2.0 to extract</code></pre>



<p class="wp-block-paragraph">Listing the content of the archive file returns:</p>



<pre class="wp-block-code"><code>unzip -l hr.siard
Archive:  hr.siard
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  07-27-2026 08:15   content/
        0  07-27-2026 08:16   content/schema0/
        0  07-27-2026 08:16   content/schema0/table0/
        0  07-27-2026 08:16   content/schema0/table1/
        0  07-27-2026 08:16   content/schema0/table2/
        0  07-27-2026 08:16   content/schema0/table3/
        0  07-27-2026 08:16   content/schema0/table4/
        0  07-27-2026 08:16   content/schema0/table5/
        0  07-27-2026 08:16   content/schema0/table6/
     1595  07-27-2026 08:16   content/schema0/table0/table0.xml
     4857  07-27-2026 08:16   content/schema0/table0/table0.xsd
     1884  07-27-2026 08:16   content/schema0/table1/table1.xml
     4910  07-27-2026 08:16   content/schema0/table1/table1.xsd
    19577  07-27-2026 08:16   content/schema0/table2/table2.xml
     5323  07-27-2026 08:16   content/schema0/table2/table2.xsd
     1786  07-27-2026 08:16   content/schema0/table3/table3.xml
     4909  07-27-2026 08:16   content/schema0/table3/table3.xsd
     1345  07-27-2026 08:16   content/schema0/table4/table4.xml
     4951  07-27-2026 08:16   content/schema0/table4/table4.xsd
     2740  07-27-2026 08:16   content/schema0/table5/table5.xml
     5036  07-27-2026 08:16   content/schema0/table5/table5.xsd
      455  07-27-2026 08:16   content/schema0/table6/table6.xml
     4793  07-27-2026 08:16   content/schema0/table6/table6.xsd
        0  07-27-2026 08:16   header/
        0  07-27-2026 08:16   header/siardversion/
        0  07-27-2026 08:16   header/siardversion/2.2/
    38441  07-27-2026 08:16   header/metadata.xsd
     4825  07-27-2026 08:16   header/table.xsd
    32980  07-27-2026 08:16   header/metadata.xml
---------                     -------
   140407                     29 files</code></pre>



<p class="wp-block-paragraph">For each table, SIARD Suite generates an XML file containing the data unloaded from the database and an XSD file with the XML schema definition used.</p>



<p class="wp-block-paragraph">The header/metadata.xml file contains the list of schemas, list of tables, list of table columns, and so on.</p>



<p class="wp-block-paragraph">Here is an extract from header/metadata.xml file produced by the HR archiving job:</p>



<pre class="wp-block-code"><code>&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;
&lt;siardArchive xmlns="http://www.bar.admin.ch/xmlns/siard/2/metadata.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.2" xsi:schemaLocation="http://www.bar.admin.ch/xmlns/siard/2/metadata.xsd metadata.xsd"&gt;
    &lt;dbname&gt;(...)&lt;/dbname&gt;
    &lt;dataOwner&gt;(...)&lt;/dataOwner&gt;
    &lt;dataOriginTimespan&gt;(...)&lt;/dataOriginTimespan&gt;
    &lt;producerApplication&gt;SiardFromDb 2.2.26 Swiss Federal Archives, Berne, Switzerland, 2008-2016&lt;/producerApplication&gt;
    &lt;archivalDate&gt;2026-07-27Z&lt;/archivalDate&gt;
    &lt;messageDigest&gt;
        &lt;digestType&gt;MD5&lt;/digestType&gt;
        &lt;digest&gt;8DC757A5338AA000234CC6199FEFE0AA&lt;/digest&gt;
    &lt;/messageDigest&gt;
    &lt;clientMachine&gt;srvsiard&lt;/clientMachine&gt;
    &lt;databaseProduct&gt;Oracle Oracle AI Database 26ai Enterprise Edition Release 23.26.2.0.0 - Production&lt;/databaseProduct&gt;
    &lt;connection&gt;jdbc:oracle:thin:@xxx.xxx.xxx.xxx:yyyy/pdb_name&lt;/connection&gt;
    &lt;databaseUser&gt;HR&lt;/databaseUser&gt;
    &lt;schemas&gt;
        &lt;schema&gt;
            &lt;name&gt;HR&lt;/name&gt;
            &lt;folder&gt;schema0&lt;/folder&gt;
            &lt;tables&gt;
                &lt;table&gt;
                    &lt;name&gt;COUNTRIES&lt;/name&gt;
                    &lt;folder&gt;table0&lt;/folder&gt;
                    &lt;description&gt;country table. References with locations table.&lt;/description&gt;
                    &lt;columns&gt;
                        &lt;column&gt;
                            &lt;name&gt;COUNTRY_ID&lt;/name&gt;
                            &lt;type&gt;CHAR(2)&lt;/type&gt;
                            &lt;typeOriginal&gt;CHAR(2)&lt;/typeOriginal&gt;
                            &lt;nullable&gt;false&lt;/nullable&gt;
                            &lt;description&gt;Primary key of countries table.&lt;/description&gt;
                        &lt;/column&gt;
                        &lt;column&gt;
                            &lt;name&gt;COUNTRY_NAME&lt;/name&gt;
                            &lt;type&gt;VARCHAR(60)&lt;/type&gt;
                            &lt;typeOriginal&gt;VARCHAR2(60)&lt;/typeOriginal&gt;
                            &lt;description&gt;Country name&lt;/description&gt;
                        &lt;/column&gt;
                        &lt;column&gt;
                            &lt;name&gt;REGION_ID&lt;/name&gt;
                            &lt;type&gt;FLOAT(38)&lt;/type&gt;
                            &lt;typeOriginal&gt;NUMBER&lt;/typeOriginal&gt;
                            &lt;description&gt;Region ID for the country. Foreign key to region_id column in the departments table.&lt;/description&gt;
                        &lt;/column&gt;
                    &lt;/columns&gt;
                    &lt;primaryKey&gt;
                        &lt;name&gt;COUNTRY_C_ID_PK&lt;/name&gt;
                        &lt;column&gt;COUNTRY_ID&lt;/column&gt;
                    &lt;/primaryKey&gt;
                    &lt;foreignKeys&gt;
                        &lt;foreignKey&gt;
                            &lt;name&gt;COUNTR_REG_FK&lt;/name&gt;
                            &lt;referencedSchema&gt;HR&lt;/referencedSchema&gt;
                            &lt;referencedTable&gt;REGIONS&lt;/referencedTable&gt;
                            &lt;reference&gt;
&lt;column&gt;REGION_ID&lt;/column&gt;
&lt;referenced&gt;REGION_ID&lt;/referenced&gt;
                            &lt;/reference&gt;
                            &lt;deleteAction&gt;RESTRICT&lt;/deleteAction&gt;
                            &lt;updateAction&gt;CASCADE&lt;/updateAction&gt;
                        &lt;/foreignKey&gt;
                    &lt;/foreignKeys&gt;
                    &lt;rows&gt;25&lt;/rows&gt;
                &lt;/table&gt;
                &lt;table&gt;
                    &lt;name&gt;DEPARTMENTS&lt;/name&gt;
                    &lt;folder&gt;table1&lt;/folder&gt;
                    &lt;description&gt;Departments table that shows details of departments where employees\u000Awork. references with locations, employees, and job_history tables.&lt;/description&gt;
                    &lt;columns&gt;
                        &lt;column&gt;
                            &lt;name&gt;DEPARTMENT_ID&lt;/name&gt;
                            &lt;type&gt;SMALLINT&lt;/type&gt;
                            &lt;typeOriginal&gt;NUMBER(4,0)&lt;/typeOriginal&gt;
                            &lt;nullable&gt;false&lt;/nullable&gt;
                            &lt;description&gt;Primary key column of departments table.&lt;/description&gt;
                        &lt;/column&gt;
                        &lt;column&gt;
                            &lt;name&gt;DEPARTMENT_NAME&lt;/name&gt;
                            &lt;type&gt;VARCHAR(30)&lt;/type&gt;
                            &lt;typeOriginal&gt;VARCHAR2(30)&lt;/typeOriginal&gt;
                            &lt;nullable&gt;false&lt;/nullable&gt;
                            &lt;description&gt;A not null column that shows name of a department. Administration,\u000AMarketing, Purchasing, Human Resources, Shipping, IT, Executive, Public\u000ARelations, Sales, Finance, and Accounting.\u0020&lt;/description&gt;
                        &lt;/column&gt;
                        &lt;column&gt;
                            &lt;name&gt;MANAGER_ID&lt;/name&gt;
                            &lt;type&gt;INT&lt;/type&gt;
                            &lt;typeOriginal&gt;NUMBER(6,0)&lt;/typeOriginal&gt;
                            &lt;description&gt;Manager_id of a department. Foreign key to employee_id column of employees table. The manager_id column of the employee table references this column.&lt;/description&gt;
                        &lt;/column&gt;
                        &lt;column&gt;
                            &lt;name&gt;LOCATION_ID&lt;/name&gt;
                            &lt;type&gt;SMALLINT&lt;/type&gt;
                            &lt;typeOriginal&gt;NUMBER(4,0)&lt;/typeOriginal&gt;
                            &lt;description&gt;Location id where a department is located. Foreign key to location_id column of locations table.&lt;/description&gt;
                        &lt;/column&gt;
                    &lt;/columns&gt;
                    &lt;primaryKey&gt;
                        &lt;name&gt;DEPT_ID_PK&lt;/name&gt;
                        &lt;column&gt;DEPARTMENT_ID&lt;/column&gt;
                    &lt;/primaryKey&gt;
                    &lt;foreignKeys&gt;
                        &lt;foreignKey&gt;
                            &lt;name&gt;DEPT_MGR_FK&lt;/name&gt;
                            &lt;referencedSchema&gt;HR&lt;/referencedSchema&gt;
                            &lt;referencedTable&gt;EMPLOYEES&lt;/referencedTable&gt;
                            &lt;reference&gt;
&lt;column&gt;MANAGER_ID&lt;/column&gt;
&lt;referenced&gt;EMPLOYEE_ID&lt;/referenced&gt;
                            &lt;/reference&gt;
                            &lt;deleteAction&gt;RESTRICT&lt;/deleteAction&gt;
                            &lt;updateAction&gt;CASCADE&lt;/updateAction&gt;
                        &lt;/foreignKey&gt;
                        &lt;foreignKey&gt;
                            &lt;name&gt;DEPT_LOC_FK&lt;/name&gt;
                            &lt;referencedSchema&gt;HR&lt;/referencedSchema&gt;
                            &lt;referencedTable&gt;LOCATIONS&lt;/referencedTable&gt;
                            &lt;reference&gt;
&lt;column&gt;LOCATION_ID&lt;/column&gt;
&lt;referenced&gt;LOCATION_ID&lt;/referenced&gt;
                            &lt;/reference&gt;
                            &lt;deleteAction&gt;RESTRICT&lt;/deleteAction&gt;
                            &lt;updateAction&gt;CASCADE&lt;/updateAction&gt;
                        &lt;/foreignKey&gt;
                    &lt;/foreignKeys&gt;
                    &lt;rows&gt;27&lt;/rows&gt;
                &lt;/table&gt;</code></pre>



<p class="wp-block-paragraph">Complete metadata include definitions for:</p>



<ul class="wp-block-list">
<li>tables</li>



<li>columns</li>



<li>descriptions</li>



<li>primary keys</li>



<li>foreign keys</li>



<li>check constraints</li>



<li>triggers</li>



<li>views</li>



<li>procedures/functions (name and parameters but not the code)</li>
</ul>



<p class="wp-block-paragraph"><u>Important&nbsp;note:</u> as already mentioned, the tool doesn&#8217;t provide fine grained tuning of archiving jobs: extraction scope is based on the security perimeter of the user performing the job, which metadata is unloaded is fixed by the tool and data is fully extracted (no way to filter with utility parameters).</p>



<p class="wp-block-paragraph">That said, you can use the source database features to configure more fine grained behaviour, for instance by:</p>



<ul class="wp-block-list">
<li>creating a dedicated user</li>



<li>defining user permissions tailored to the archiving scope defined</li>



<li>creating views for column or row filtering purposes</li>
</ul>



<p class="wp-block-paragraph">To get an idea of how big an archive file can be when exporting a big table, we made a first test with a three columns table containing 26,300,300 rows and whose segment size is 50G: the archive file size is 27G. During the tests, other intermediary sizes were used for the table and each time, the archive file was a little more than 50% of the segment size.</p>



<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 id="h-what-s-next" class="wp-block-heading">What&#8217;s next</h3>



<p class="wp-block-paragraph">In upcoming blog posts, we will dive in the GUI interface and the various challenges encountered on real schemas.</p>
<p>L’article <a href="https://www.dbi-services.com/blog/archiving-oracle-databases-with-siard-suite/">Archiving Oracle databases with SIARD Suite</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/archiving-oracle-databases-with-siard-suite/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Deleting an Oracle 12c DB Home on a Recent ODA</title>
		<link>https://www.dbi-services.com/blog/deleting-an-oracle-12c-db-home-on-a-recent-oda/</link>
					<comments>https://www.dbi-services.com/blog/deleting-an-oracle-12c-db-home-on-a-recent-oda/#respond</comments>
		
		<dc:creator><![CDATA[Abdessamed El Ahmar]]></dc:creator>
		<pubDate>Tue, 29 Sep 2026 15:12:03 +0000</pubDate>
				<category><![CDATA[Oracle]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=47192</guid>

					<description><![CDATA[<p>The Context In the context of Oracle Database Aplliances, you might need to remove an old Oracle Database Home (For instance 12c), while the ODA is already on a recent patch level. For instance in my case : In an ODA patching operation, the appliance was already running 19.26 patchlevel On Oracle Linux 8.10, while [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/deleting-an-oracle-12c-db-home-on-a-recent-oda/">Deleting an Oracle 12c DB Home on a Recent ODA</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h3>The Context</h3>
<p>In the context of Oracle Database Aplliances, you might need to remove an old Oracle Database Home (For instance 12c), while the ODA is already on a recent patch level.</p>
<p>For instance in my case : In an ODA patching operation, the appliance was already running 19.26 patchlevel On Oracle Linux 8.10, while an unused Oracle Database 12.2 home was still registered:</p>
<pre class="brush: sql; gutter: true; first-line: 1 ">
[root@server-oda1 ~]# odacli list-dbhomes

ID                                    Name               DB Version          DB Edition Home Location                                               Status
------------------------------------- ------------------ ------------------- ---------- ----------------------------------------------------------- ----------
de8c09c9-beaf-4a0d-937b-02cace2e0121 OraDB12201_home1   12.2.0.1.220118     EE         /u01/app/odaorahome/oracle/product/12.2.0.1/dbhome_1        CONFIGURED
a0d28b10-07a4-4c43-8504-751245ddd2c3 OraDB19000_home5   19.26.0.0.250121    EE         /u01/app/odaorahome/oracle/product/19.0.0.0/dbhome_5        CONFIGURED
</pre>
<p>No database was using the 12c home anymore, so it could safely be removed before continuing with the patching.</p>
<p>Let&#8217;s use the normal procedure : </p>
<pre class="brush: sql; gutter: true; first-line: 1 ">
[root@server-oda1 ~]# odacli delete-dbhome -i de8c09c9-beaf-4a0d-937b-02cace2e0121
</pre>
<p>The job fails almost immediately:</p>
<pre class="brush: sql; gutter: true; first-line: 1 ">
[root@server-oda1 ~]# odacli describe-job -i 8e725314-aaea-4f6a-bc7b-e820bb3ffbce

Job details
----------------------------------------------------------------
                     ID:  8e725314-aaea-4f6a-bc7b-e820bb3ffbce
            Description:  Database Home OraDB12201_home1 Deletion with ID de8c09c9-beaf-4a0d-937b-02cace2e0121
                 Status:  Running
                Created:  April 29, 2026 09:54:15 CEST
                Message:

Task Name                                Start Time                               End Time                                 Status
---------------------------------------- ---------------------------------------- ---------------------------------------- ----------------
Validate DB Home                         April 29, 2026 09:54:15 CEST             April 29, 2026 09:54:15 CEST             Success
de8c09c9-beaf-4a0d-937b-02cace2e0121
for deletion

[root@server-oda1 diag]# odacli describe-job -i 8e725314-aaea-4f6a-bc7b-e820bb3ffbce

Job details
----------------------------------------------------------------
                     ID:  8e725314-aaea-4f6a-bc7b-e820bb3ffbce
            Description:  Database Home OraDB12201_home1 Deletion with ID de8c09c9-beaf-4a0d-937b-02cace2e0121
                 Status:  Failure (To view Error Correlation report, run "odacli describe-job -i 8e725314-aaea-4f6a-bc7b-e820bb3ffbce --ecr" command)
                Created:  April 29, 2026 09:54:15 CEST
                Message:  DCS-10001:Internal error encountered: PRGH-1010 : Removal of Oracle home /u01/app/odaorahome/oracle/product/12.2.0.1/dbhome_1 failed
PRCZ-4001 : failed to execute command "/u01/app/odaorahome/oracle/product/12.2.0.1/dbhome_1/deinstall/deinstall" using the privileged execution plugin "odaexec" on nodes "server-oda1" within 4,000 seconds
PRCZ-2103 : Failed to execute command "/u01/app/odaorahome/oracle/product/12.2.0.1/dbhome_1/deinstall/deinstall" on node "server-oda1" as user "oracle". Detailed error:
Checking for required files and bootstrapping ...
Please wait ...
Location of logs /u01/app/oraInventory/logs/

############ ORACLE DECONFIG TOOL START ############


######################### DECONFIG CHECK OPERATION START #########################
## [START] Install check configuration ##


Checking for existence of the Oracle home location /u01/app/odaorahome/oracle/product/12.2.0.1/dbhome_1
Oracle Home type selected for deinstall is: Oracle Real Application Cluster Database
Oracle Base selected for deinstall is: /u01/app/odaorabase/oracle
Checking for existence of central inventory location /u01/app/oraInventory
Checking for existence of the Oracle Grid Infrastructure home /u01/app/19.26.0.0/grid
The following nodes are part of this cluster: server-oda1
ERROR: null.

Task Name                                Start Time                               End Time                                 Status
---------------------------------------- ---------------------------------------- ---------------------------------------- ----------------
DbHome service deletion for              April 29, 2026 09:54:15 CEST             April 29, 2026 09:54:30 CEST             Failure
de8c09c9-beaf-4a0d-937b-02cace2e0121
DbHome service deletion for              April 29, 2026 09:54:15 CEST             April 29, 2026 09:54:30 CEST             Failure
de8c09c9-beaf-4a0d-937b-02cace2e0121
Validate DB Home                         April 29, 2026 09:54:15 CEST             April 29, 2026 09:54:15 CEST             Success
de8c09c9-beaf-4a0d-937b-02cace2e0121
for deletion
Setting up SSH equivalence               April 29, 2026 09:54:15 CEST             April 29, 2026 09:54:15 CEST             Success
Setting up SSH equivalence               April 29, 2026 09:54:15 CEST             April 29, 2026 09:54:15 CEST             Success
Deleting DB Home by RHP                  April 29, 2026 09:54:16 CEST             April 29, 2026 09:54:30 CEST             Failure

</pre>
<p>There are &#8220;harsh&#8221; solutions provided online, I would not talk about here, because I don&#8217;t want to spread risky stuff.</p>
<p>However, understanding the issue provides us with a &#8220;clean&#8221; workaround : </p>
<p>The important point here is that <code>odacli delete-dbhome</code> eventually calls the standard Oracle 12.2 <code>deinstall</code> utility.</p>
<p>And as you most probably already know, the 12c deinstallation stack prerequisite checks expects by default the Oracle Linux 7 version. and the well known CV_ASSUME_DISTID environment variable is usually used to fix that.</p>
<h3>The Workaround</h3>
<p>The workaround is exactly positionning the CV_ASSUME_DISTID to OL7 (Oracle Linux 7)</p>
<pre class="brush: sql; gutter: true; first-line: 1 ">
CV_ASSUME_DISTID=OL7
</pre>
<p>Because the deinstallation process is launched internally by <code>odacli</code>, simply exporting the variable in my current shell would not guarantee that it would be inherited by the process started by ODA.</p>
<p>I therefore added it directly to the 12c deinstall script:</p>
<pre class="brush: sql; gutter: true; first-line: 1 ">
[oracle@server-oda1 ~]# sed -i '1a export CV_ASSUME_DISTID=OL7' /u01/app/odaorahome/oracle/product/12.2.0.1/dbhome_1/deinstall/deinstall
</pre>
<p>This is obviously a workaround rather than a change that should be applied blindly to every environment. Before using it, make sure that the DB Home is no longer used by any database and that the failure is actually related to the legacy prerequisite checks.</p>
<h3>Deleting the DB Home Again</h3>
<p>After adding the environment variable, I simply restarted the ODA deletion:</p>
<pre class="brush: sql; gutter: true; first-line: 1 ">
[root@server-oda1 ~]# odacli delete-dbhome -i de8c09c9-beaf-4a0d-937b-02cace2e0121
Job details
----------------------------------------------------------------
                     ID:  21c05801-e3fb-4cdb-bf40-36e6dc1e0157
            Description:  Database Home OraDB12201_home1 Deletion with ID de8c09c9-beaf-4a0d-937b-02cace2e0121
                 Status:  Running
                Created:  April 29, 2026 09:57:01 CEST
                Message:

Task Name                                Start Time                               End Time                                 Status
---------------------------------------- ---------------------------------------- ---------------------------------------- ----------------
Validate DB Home                         April 29, 2026 09:57:01 CEST             April 29, 2026 09:57:01 CEST             Success
de8c09c9-beaf-4a0d-937b-02cace2e0121
for deletion
Setting up SSH equivalence               April 29, 2026 09:57:01 CEST                                                      Running

[root@server-oda1 diag]# odacli describe-job -i 21c05801-e3fb-4cdb-bf40-36e6dc1e0157

Job details
----------------------------------------------------------------
                     ID:  21c05801-e3fb-4cdb-bf40-36e6dc1e0157
            Description:  Database Home OraDB12201_home1 Deletion with ID de8c09c9-beaf-4a0d-937b-02cace2e0121
                 Status:  Success
                Created:  April 29, 2026 09:57:01 CEST
                Message:

Task Name                                Start Time                               End Time                                 Status
---------------------------------------- ---------------------------------------- ---------------------------------------- ----------------
Validate DB Home                         April 29, 2026 09:57:01 CEST             April 29, 2026 09:57:01 CEST             Success
de8c09c9-beaf-4a0d-937b-02cace2e0121
for deletion
Setting up SSH equivalence               April 29, 2026 09:57:01 CEST             April 29, 2026 09:57:01 CEST             Success
Setting up SSH equivalence               April 29, 2026 09:57:01 CEST             April 29, 2026 09:57:01 CEST             Success
Deleting DB Home by RHP                  April 29, 2026 09:57:02 CEST             April 29, 2026 09:57:49 CEST             Success

</pre>
<p>Finally, verify that the old Oracle Home is no longer registered in ODA:</p>
<pre class="brush: sql; gutter: true; first-line: 1 ">
[root@server-oda1 ~]# odacli list-dbhomes

ID                                    Name               DB Version          DB Edition Home Location
------------------------------------- ------------------ ------------------- ---------- ---------------------------------------------------
a0d28b10-07a4-4c43-8504-751245ddd2c3 OraDB19000_home5   19.26.0.0.250121    EE         /u01/app/odaorahome/oracle/product/19.0.0.0/dbhome_5
</pre>
<h3>Conclusion</h3>
<p>This issue is a good reminder of the importance of keeping Oracle Database Appliance environments up to date and within Oracle’s supported compatibility matrix.</p>
<p>When legacy Database Homes remain on an ODA that has already moved to a newer operating system and appliance software stack, compatibility gaps can appear and eventully cause issues.</p>
<p>L’article <a href="https://www.dbi-services.com/blog/deleting-an-oracle-12c-db-home-on-a-recent-oda/">Deleting an Oracle 12c DB Home on a Recent ODA</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/deleting-an-oracle-12c-db-home-on-a-recent-oda/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Snapshots with VirtualBox and btrfs</title>
		<link>https://www.dbi-services.com/blog/snapshots-with-virtualbox-and-btrfs/</link>
					<comments>https://www.dbi-services.com/blog/snapshots-with-virtualbox-and-btrfs/#respond</comments>
		
		<dc:creator><![CDATA[Martin Bracher]]></dc:creator>
		<pubDate>Mon, 28 Sep 2026 21:56:21 +0000</pubDate>
				<category><![CDATA[Development & Performance]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[SUSE]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=47071</guid>

					<description><![CDATA[<p>Snapshot mechanism of VirtualBox With VirtualBox you can take snapshots of the current state (without snapshot functionality of a filesystem like btrfs) This kind of snapshot will create a kind of differential file and the original file will be untouched. Every changed block is written to this difference file in the Snapshot/ directory. If you [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/snapshots-with-virtualbox-and-btrfs/">Snapshots with VirtualBox and btrfs</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 id="h-snapshot-mechanism-of-virtualbox" class="wp-block-heading">Snapshot mechanism of VirtualBox</h2>



<p class="wp-block-paragraph">With VirtualBox you can take snapshots of the current state (without snapshot functionality of a filesystem like btrfs)</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="816" height="189" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-30.png" alt="" class="wp-image-47105" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-30.png 816w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-30-300x69.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-30-768x178.png 768w" sizes="auto, (max-width: 816px) 100vw, 816px" /></figure>



<p class="wp-block-paragraph">This kind of snapshot will create a kind of differential file and the original file will be untouched.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; gutter: false; title: ; notranslate">
$  ls -lh ol9.vdi Snapshots/\{dfef3efe-1a67-466d-b968-835d7c2c915b\}.vdi
-rw------- 1 mnb mnb 463M Sep 25 17:55 &#039;/Snapshots/{dfef3efe-1a67-466d-b968-835d7c2c915b}.vdi&#039;
-rw------- 1 mnb mnb 9.5G Sep 25 17:52  ol9.vdi
</pre></div>


<p class="wp-block-paragraph">Every changed block is written to this difference file in the Snapshot/ directory.</p>



<p class="wp-block-paragraph">If you will do tests with always the same starting point, and after the test you will go back to the snapshot (restore). For this scenario it is a good solution. Virtualbox only needs to delete the differential file.</p>



<p class="wp-block-paragraph">But if you take a snapshot before an upgrade, and if it is successful, you will keep this state and delete the snapshot state. For this scenario, VirtualBox has to copy all the blocks from the differential file back to the original file (ol9.vdi), which can be very time-consuming after patching big software (e.g. the OS or Oracle database). </p>



<p class="wp-block-paragraph">You can also clone a VM with VirtualBox. You have the choice of a full- and a linked-clone. The full clone will create an independent copy of the disk files. The linked clone is only a snapshot of the disks of the source VM. So, the original disk will no longer be changed, but the original and the cloned VM will have an individual differential file in Snapshots/</p>



<pre class="wp-block-code"><code>ol9/ol9.iso  # will no longer be changed
ol9/Snapshots/{xxxxxxxxxxx}.vdi
ol9clone/Snapshots/{xxxxxxxxxxx}.vdi</code></pre>



<p class="wp-block-paragraph">This type of clone we should only  use for short-term usage. Create a snapshot of the production, do some tests, and afterwards, immediately delete it! But after deleting the clone, you have to do a cleanup with the original VM. On the original VM, the snapshot is not deleted! (if you forget to delete it, you will need more and more diskspace&#8230;)</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="504" height="59" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-31.png" alt="" class="wp-image-47106" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-31.png 504w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-31-300x35.png 300w" sizes="auto, (max-width: 504px) 100vw, 504px" /></figure>



<p class="wp-block-paragraph">But is there a better solution? Yes, if you are using Linux. Use filesystem based file-snapshots.</p>



<h2 id="h-snapshots-with-btrfs" class="wp-block-heading">Snapshots with btrfs</h2>



<p class="wp-block-paragraph">Some Linux filesystems with snapshots</p>



<ul class="wp-block-list">
<li><strong>OCFS2</strong>: I used it often in the past, it works very well, but is not widely used. It is a cluster filesystem, but it can also be used for single-hosts.</li>



<li><strong>OpenZFS</strong>: I never used it.</li>



<li><strong>btrfs</strong>: Available in most Linux distributions (*) with subvolume snapshots. In this blog post I will show the examples with btrfs. </li>
</ul>



<p class="wp-block-paragraph">(*) Btrfs is no longer included in RedHat Enterprise linux and 1:1 forks like Rocky Linux. With these distributions, you can use the kernel from <a href="https://elrepo.org/wiki/doku.php?id=start">https://elrepo.org/</a>. I used the &#8220;ml&#8221; Kernel and it worked well.<br>In Fedora (the development release of RedHat) btrfs is included. That means, there are political, not technical reasons that RedHat no longer delivers the modules for btrfs&#8230;<br>In Oracle Linux OL (also a RedHat fork) it is available with the UEK-kernel (a more modern Kernel than the RedHat Kernel). OL is freely available at <a href="https://yum.oracle.com">https://yum.oracle.com</a>. <br>SuSE uses btrfs as the default root filesystem.</p>



<p class="wp-block-paragraph">A good overview of btrfs you will get with this <a href="https://documentation.suse.com/sles/15-SP6/html/SLES-all/cha-filesystems.html">SuSE article</a>.</p>



<p class="wp-block-paragraph">Your VMs are located in a directory. If you create a VM, you will specify the name and a directory (VM Folder)</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="580" height="88" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-33.png" alt="" class="wp-image-47121" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-33.png 580w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-33-300x46.png 300w" sizes="auto, (max-width: 580px) 100vw, 580px" /></figure>



<p class="wp-block-paragraph">Then, it creates the VM (virtual disks and configuration file) in the subdirectory <code>/u00/virtualbox/vm1/</code></p>



<p class="wp-block-paragraph">Snapshots with btrfs works with subvolumes. For us, for the application, a subvolume is visible as a directory. We can mount such a subvolume separately. And important for our use-case: we can create a snapshot of a subvolume.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
&#x5B;root@ltp14 virtualbox]  btrfs subvolume list .
ID 264 gen 1015763 top level 5 path virtualbox/olvmm01
ID 289 gen 1015763 top level 5 path virtualbox/winxp_2023-06-26
ID 290 gen 1015763 top level 5 path virtualbox/winxp
ID 292 gen 1015783 top level 5 path virtualbox/ol9
ID 307 gen 1015763 top level 5 path virtualbox/ubuntu2204
ID 354 gen 1015763 top level 5 path virtualbox/ol9a
ID 362 gen 1015763 top level 5 path virtualbox/ol9b
</pre></div>


<p class="wp-block-paragraph">As you can see, most of my VMs are installed in subvolumes. I created a master image ol9, and ol9a and ol9b are snapshots of ol9 used for the &#8220;clone&#8221; functionality. And from my good old winxp installation i created a snapshot winxp_2023-06-26 which can be used similar to the &#8220;Snapshot&#8221; of virtualbox.</p>



<h3 id="h-difference-of-virtualbox-and-btrfs" class="wp-block-heading">Difference of VirtualBox and btrfs</h3>



<p class="wp-block-paragraph">But what is the difference? As we have seen before, VirtualBox stores changed blocks in a separate file. If we access a virtual disk, we have to access 2 files. First check, if the block is in the snapshot file, and if not, take the unchanged block from the (no longer changed) original. </p>



<p class="wp-block-paragraph">Btrfs is a copy-on-write filesystem. If we change a block, it will not change the current block on disk, instead, it allocates a new block and releases the old one. In case a snapshot exists, it will not release the old block as long as it is assigned in another snapshot.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; gutter: false; title: ; notranslate">
&#x5B;root@ltp14 virtualbox]  btrfs subvolume snapshot vm1 vm2
</pre></div>


<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="488" height="190" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-35.png" alt="" class="wp-image-47126" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-35.png 488w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-35-300x117.png 300w" sizes="auto, (max-width: 488px) 100vw, 488px" /></figure>



<p class="wp-block-paragraph">After we created the subvolume vm2 as a snapshot of subvolume vm1, fileA in both subvolumes share the same disk blocks, which is recorded in the inodes (mapping table between file and disk blocks). Of course, we can rename one of &#8220;FileA&#8221;, its inode assignment remains unchanged. If you update block 3 and 4 of fileA in vm1, then 2 new blocks are allocated (green, orange). If you update block 4 in vm2, then also a new block (light blue) is allocated and the old block (with white &#8220;x&#8221;) is deallocated (unused) because it is no longer allocated in any other snapshot.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="489" height="189" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-42.png" alt="" class="wp-image-47158" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-42.png 489w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-42-300x116.png 300w" sizes="auto, (max-width: 489px) 100vw, 489px" /></figure>



<p class="wp-block-paragraph">For us, for the application, there are 2 independent files. There is no &#8220;original&#8221; and a snapshot file. </p>



<h2 id="h-snapshots" class="wp-block-heading">Snapshots</h2>



<h4 id="h-subvolumes" class="wp-block-heading">Subvolumes</h4>



<p class="wp-block-paragraph">Now, let&#8217;s see how to replace VirtualBox snapshot functionality by btrfs snapshots. Fist of all, we need a subvolume of our VM. Unfortunately, we can not convert an existing directory directly to a subvolume. We have to move the files in a subvolume.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; gutter: false; title: ; notranslate">
&#x5B;root@ltp14 virtualbox]  btrfs subvolume create vm1sub
Create subvolume &#039;./vm1sub&#039;
&#x5B;root@ltp14 virtualbox]  chown mnb:mnb vm1sub/  #subvols are created as root
&#x5B;root@ltp14 virtualbox]  mv -v vm1/* vm1sub/
copied &#039;vm1/vm1.nvram&#039; -&gt; &#039;vm1sub/vm1.nvram&#039;
removed &#039;vm1/vm1.nvram&#039;
copied &#039;vm1/vm1.vbox&#039; -&gt; &#039;vm1sub/vm1.vbox&#039;
removed &#039;vm1/vm1.vbox&#039;
copied &#039;vm1/vm1.vbox-prev&#039; -&gt; &#039;vm1sub/vm1.vbox-prev&#039;
removed &#039;vm1/vm1.vbox-prev&#039;
copied &#039;vm1/vm1.vdi&#039; -&gt; &#039;vm1sub/vm1.vdi&#039;
removed &#039;vm1/vm1.vdi&#039;
&#x5B;root@ltp14 virtualbox]  rmdir vm1
&#x5B;root@ltp14 virtualbox]  mv vm1sub vm1
&#x5B;root@ltp14 virtualbox]  btrfs subvolume list . |grep vm1
ID 367 gen 1016224 top level 5 path virtualbox/vm1
&#x5B;root@ltp14 virtualbox]
</pre></div>


<p class="wp-block-paragraph">Afterwards, we can use the VM as before. </p>



<h4 id="h-create-a-snapshot" class="wp-block-heading">Create a snapshot</h4>



<p class="wp-block-paragraph">Now we will create a snapshot of it. Ideally we stop it before the snapshot. If we snapshot a running VM, there may be some application inconsistencies. For Oracle databases, do an &#8220;alter database begin backup&#8221; before and end backup afterwards keeping the database recoverable. What we can not do with btrfs, is the snapshot of the memory, so we can not restore it &#8220;running&#8221;. VirtualBox can do that, but it is not &#8220;online&#8221;, Our VM is freezed during the time of the snapshot.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; gutter: false; title: ; notranslate">
&#x5B;root@ltp14 virtualbox]   sudo -u mnb vboxmanage controlvm vm1 shutdown  #or poweroff
&#x5B;root@ltp14 virtualbox]  time  btrfs subvolume snapshot vm1 vm1_snap01
Create snapshot of &#039;vm1&#039; in &#039;vm1_snap01&#039;

real    0m0.030s
user    0m0.000s
sys     0m0.016s
&#x5B;root@ltp14 virtualbox]  sudo -u mnb vboxmanage startvm vm1
</pre></div>


<h4 id="h-delete-a-snapshot" class="wp-block-heading">Delete a snapshot</h4>



<p class="wp-block-paragraph">To delete a snapshot means, remove the subvolume of the old state. The big advantage compared to VirtualBox is, that we do not have to wait until the changed blocks are copied back in the &#8220;original&#8221; file. With btrfs, this is done &#8220;online&#8221; without influence of our running VM.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; gutter: false; title: ; notranslate">
&#x5B;root@ltp14 virtualbox]  btrfs subvolume delete vm1_snap
</pre></div>


<h4 id="h-restore-a-snapshot" class="wp-block-heading">Restore a snapshot</h4>



<p class="wp-block-paragraph">To restore a snapshot means, renaming the subvolumes:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; gutter: false; title: ; notranslate">
&#x5B;root@ltp14 virtualbox]  sudo -u mnb vboxmanage controlvm vm1 poweroff
&#x5B;root@ltp14 virtualbox]  mv vm1 vm1_bck
&#x5B;root@ltp14 virtualbox]  btrfs subvolume snapshot vm1_snap01 vm1  #now the vm can be restarted
&#x5B;root@ltp14 virtualbox]  btrfs subvolume delete vm1_bck  # (*)
Delete subvolume 367 (no-commit): &#039;/u00/virtualbox/vm1_bck&#039;
</pre></div>


<p class="wp-block-paragraph">(*) in VirtualBox restoring a snapshot asks for &#8220;Create a snapshot of the current machine state&#8221; De-selecting this option is similar to delte the subvolume. And instead of &#8220;Create a snapshot&#8230;&#8221;, simply keep the renamed subvolume.</p>



<p class="wp-block-paragraph">The &#8220;delete&#8221; snapshot of VirtualBox is equivalent to delete the current subvolume and rename the old subvolume back to the original name.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; gutter: false; title: ; notranslate">
&#x5B;root@ltp14 virtualbox]  sudo -u mnb vboxmanage controlvm vm1 poweroff
&#x5B;root@ltp14 virtualbox]  btrfs subvolume delete vm1_snap
&#x5B;root@ltp14 virtualbox]  mv vm1_snap vm1
</pre></div>


<h3 id="h-clone" class="wp-block-heading">Clone</h3>



<p class="wp-block-paragraph">The next subject is to clone a VM. I will demonstrate that by creating a master/template VM of Oracle Linux 10 (OL10) and then to create clones of it for different purposes.</p>



<h4 id="h-create-a-master-vm" class="wp-block-heading">Create a master VM</h4>



<p class="wp-block-paragraph">To define the VM you can start with the VirtualBox GUI. That will create the definition and an empty virtual disk. As described above, we will move it afterwards to a subvolume, then install and configure OL10 like every other VM. </p>



<p class="wp-block-paragraph">After you have prepared the VM as a master-VM, that means you have installed all software you need in each clone, especially the VirtualBox tools, stop it and create clones.</p>



<h4 id="h-create-a-new-vm-from-the-master-vm" class="wp-block-heading">Create a new VM from the master-VM</h4>



<p class="wp-block-paragraph">From the point of view of virtualbox, we create a full clone. From the point of view of the filesystem, it is similar to a linked clone (each VM stores its own modified blocks. But the old blocks are released when both VM&#8217;s have changed these blocks).</p>



<p class="wp-block-paragraph">We create a subvolume ol10a from ol10, then we remove all files in ol10a, except the disk image. This, we rename to ol10a.vdi. VirtualBox tracks the file by an uuid, so we have to set a new uuid for the cloned disk.</p>



<p class="wp-block-paragraph">Tip: look at the space consumption before and after cloning (df -k).</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; gutter: false; title: ; notranslate">
&#x5B;root@ltp14 virtualbox]   btrfs subvolume snapshot ol10 ol10a
Create snapshot of &#039;ol10&#039; in &#039;ol10a&#039;
&#x5B;root@ltp14 virtualbox]  cd ol10a/
&#x5B;root@ltp14 ol10a]  ls -l
total 3383436
drwx------ 1 mnb mnb         16 Sep 28 11:55 Logs
-rw------- 1 mnb mnb       4138 Sep 28 12:58 ol10.vbox
-rw------- 1 mnb mnb       6432 Sep 28 12:55 ol10.vbox-prev
-rw------- 1 mnb mnb 3466592256 Sep 28 12:58 ol10.vdi
&#x5B;root@ltp14 ol10a]   rm -f *.vbox* Logs/*
&#x5B;root@ltp14 ol10a]   mv ol10.vdi ol10a.vdi
&#x5B;root@ltp14 ol10a]   VBoxManage internalcommands sethduuid /u00/virtualbox/ol10a/ol10a.vdi
UUID changed to: 81927ab2-e2ac-4143-9077-98af702ec82d
</pre></div>


<p class="wp-block-paragraph">Afterwards, you can create a new VM with the GUI. But do not create an new disk. Attach the existing cloned disk.</p>



<p class="wp-block-paragraph">You can also create the VM on commandline which is recommended if you need many clones. You can do it with your useraccount, or if you prefer to do all steps as root, with &#8220;sudo -u your_username&#8221;. First, create the VM, then attach/modify the desired virtual hardware (disk-controllers, ram, cpus, network, and attach the cloned virtual disk to a controller).</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; gutter: false; title: ; notranslate">
root@ltp14 ol10a]  sudo -u mnb  VBoxManage  createvm --name ol10a --basefolder /u00/virtualbox/ol10a --register
Virtual machine &#039;ol10a&#039; is created and registered.
UUID: d983c059-2e2f-4e89-bad0-fd3676d567c7
Settings file: &#039;/u00/virtualbox/ol10a/ol10a/ol10a.vbox&#039;
&#x5B;root@ltp14 ol10a]  sudo -u mnb   VBoxManage modifyvm ol10a --memory 4096 --cpus 2 --ostype Oracle10_64 --vram 4
&#x5B;root@ltp14 ol10a]  sudo -u mnb VBoxManage storagectl ol10a --name &quot;SATA Controller&quot; --add sata --controller IntelAhci
&#x5B;root@ltp14 ol10a]  sudo -u mnb   VBoxManage storagectl ol10a --name &quot;IDE Controller&quot; --add ide --controller PIIX4
&#x5B;root@ltp14 ol10a]  sudo -u mnb   VBoxManage storageattach ol10a --storagectl &quot;SATA Controller&quot; --port 0 --device 0 --type hdd --medium /u00/virtualbox/ol10a/ol10a.vdi
&#x5B;root@ltp14 ol10a]  sudo -u mnb   VBoxManage modifyvm ol10a --nic1 hostonly --hostonlyadapter1 vboxnet0
&#x5B;root@ltp14 ol10a]  sudo -u mnb VBoxManage modifyvm ol10a --nic2 nat
</pre></div>


<p class="wp-block-paragraph">Now you are ready to boot your cloned VM ol10a. This can be done from commandline (as your user) or in the VirtualBox GUI. After booting, log in and change immediately the hostname. Afterwards, adapt the clone for your needs.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; gutter: false; title: ; notranslate">
hostnamectl hostname ol10a
</pre></div>


<p class="wp-block-paragraph"></p>
<p>L’article <a href="https://www.dbi-services.com/blog/snapshots-with-virtualbox-and-btrfs/">Snapshots with VirtualBox and btrfs</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/snapshots-with-virtualbox-and-btrfs/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>GoldenGate Instantiation CSN Explained</title>
		<link>https://www.dbi-services.com/blog/goldengate-instantiation-csn-explained/</link>
					<comments>https://www.dbi-services.com/blog/goldengate-instantiation-csn-explained/#respond</comments>
		
		<dc:creator><![CDATA[Julien Delattre]]></dc:creator>
		<pubDate>Mon, 28 Sep 2026 06:12:00 +0000</pubDate>
				<category><![CDATA[GoldenGate]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[26]]></category>
		<category><![CDATA[26ai]]></category>
		<category><![CDATA[aftercsn]]></category>
		<category><![CDATA[atcsn]]></category>
		<category><![CDATA[csn]]></category>
		<category><![CDATA[DataPump]]></category>
		<category><![CDATA[expdp]]></category>
		<category><![CDATA[extract]]></category>
		<category><![CDATA[flashback_scn]]></category>
		<category><![CDATA[impdp]]></category>
		<category><![CDATA[Initial load]]></category>
		<category><![CDATA[instantiation]]></category>
		<category><![CDATA[ogg]]></category>
		<category><![CDATA[ORA-01555]]></category>
		<category><![CDATA[preparecsn]]></category>
		<category><![CDATA[replicat]]></category>
		<category><![CDATA[scn]]></category>
		<category><![CDATA[snapshot too old]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=47082</guid>

					<description><![CDATA[<p>For more than ten years (GoldenGate 12.2, released in 2015), GoldenGate has provided a way of performing initial load of tables with a per-table instantiation CSN. But when migrating a database or just performing the initial load of a single table to prepare a GoldenGate replication, the known procedure is very often still the old [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/goldengate-instantiation-csn-explained/">GoldenGate Instantiation CSN Explained</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">For more than ten years (GoldenGate 12.2, released in 2015), GoldenGate has provided a way of performing initial load of tables with a <strong>per-table instantiation CSN</strong>.</p>



<p class="wp-block-paragraph">But when migrating a database or just performing the initial load of a single table to prepare a GoldenGate replication, the known procedure is very often still the old one: start an extract, note down an SCN, run <code>expdp</code> with <code>FLASHBACK_SCN=&lt;that SCN&gt;</code>, import the data on the target, and finally start a replicat with the <code>AFTERCSN</code> clause.</p>



<p class="wp-block-paragraph">It takes a long time to get used to new habits, so let’s refresh your memory, explaining how instantiation CSN work in GoldenGate.</p>



<h2 id="historic-flashback_scn--aftercsn-initial-load" class="wp-block-heading">Historic <code>FLASHBACK_SCN</code> + <code>AFTERCSN</code> initial load</h2>



<p class="wp-block-paragraph">Historically, precise instantiation of a table worked like this:</p>



<ul class="wp-block-list">
<li><code>START EXTRACT</code>. It is the first step, to ensure that no transaction is lost.</li>



<li>Wait for long running transactions to be committed.</li>



<li>Select an SCN, which should not be prior to the registration SCN of the extract.</li>



<li>Export the data with <code>expdp ... FLASHBACK_SCN=&lt;scn&gt;</code> so the dump is consistent.</li>



<li>Import the data with <code>impdp</code> on the target.</li>



<li>Start the replicat with the <code>AFTERCSN &lt;csn&gt;</code> clause, so the replicat does not replicate anything committed at or before the instantiation CSN.</li>
</ul>



<p class="wp-block-paragraph">While still perfectly valid, and even necessary under certain conditions, this method becomes hard to operate on complex replications or when the size of the database increases:</p>



<ul class="wp-block-list">
<li><code>UNDO</code> retention: very often, using the <code>FLASHBACK_SCN</code> clause will generate <code>ORA-01555: snapshot too old</code> errors.</li>



<li>Splitting the initial load is not possible, since the <code>AFTERCSN</code> clause will apply on the whole replicat.</li>
</ul>



<h2 id="instantiation-csn-in-practice" class="wp-block-heading">Instantiation CSN in practice</h2>



<p class="wp-block-paragraph">GoldenGate instantiation CSN provides a simple solution: a <strong>per table instantiation CSN, on the target database</strong>, instead of a single one applied on the replicat.</p>



<p class="wp-block-paragraph">This instantiation CSN is stored on the target database in the <code>DBA_APPLY_INSTANTIATED_OBJECTS</code> table, with one row per source object.</p>



<pre class="wp-block-code"><code>SET PAGES 100 LINES 200
COL source_object_owner FORMAT A20
COL source_object_name FORMAT A30
COL instantiation_scn FORMAT 999999999999999
SELECT source_object_owner, source_object_name, instantiation_scn
FROM dba_apply_instantiated_objects
ORDER BY 1, 2;</code></pre>



<p class="wp-block-paragraph">This table is <strong>populated by Data Pump</strong>, and is then <strong>read by GoldenGate</strong>. When applying changes, a replicat will compare the commit CSN of a record to the table’s instantiation CSN. If the commit CSN is higher, the transaction will be discarded.</p>



<p class="wp-block-paragraph">Because the comparison is done for every table, there is no need for them to share one instantiation CSN using <code>FLASHBACK_SCN</code>.</p>



<h2 id="why-flashback_scn-is-no-longer-required" class="wp-block-heading">Why <code>FLASHBACK_SCN</code> is no longer required</h2>



<p class="wp-block-paragraph">The instantiation CSN is the <strong>read-consistent SCN</strong> as of which Data Pump reads the table during export. It is stored in the dump and imported on the target when using <code>impdp</code>. It does <strong>not</strong> come from when the source table is prepared with <code>PREPARECSN</code>. <code>PREPARECSN</code> is what makes the table <em>eligible</em> for instantiation CSN.</p>



<p class="wp-block-paragraph">Let’s see the difference with three different scenarios:</p>



<ul class="wp-block-list">
<li>Standard initial load without <code>FLASHBACK_SCN</code></li>



<li>Historic method with <code>FLASHBACK_SCN</code></li>



<li>Instantiation with <code>PREPARECSN NONE</code></li>
</ul>



<p class="wp-block-paragraph">I will use the same two tables, <code>HR.EMPLOYEES</code> and <code>HR.DEPARTMENTS</code>.</p>



<h2 id="enable_instantiation_filtering-vs-atcsnaftercsn" class="wp-block-heading"><code>ENABLE_INSTANTIATION_FILTERING</code> vs <code>ATCSN</code>/<code>AFTERCSN</code></h2>



<p class="wp-block-paragraph">Before running the three scenarios, here is what the instantiation filtering replaces:</p>



<figure class="wp-block-table"><table><thead><tr><th></th><th><code>ATCSN</code>/<code>AFTERCSN</code></th><th><code>DBOPTIONS ENABLE_INSTANTIATION_FILTERING</code></th></tr></thead><tbody><tr><td>Boundary granularity</td><td>One CSN for the whole replicat</td><td>One CSN per table</td></tr><tr><td>Where the boundary is set</td><td>On the <code>START REPLICAT</code> command</td><td>Read from <code>dba_apply_instantiated_objects</code> on the target</td></tr><tr><td>Who sets the boundary</td><td>The operator, by hand</td><td>Data Pump automatically (or <code>SET INSTANTIATION CSN</code> manually)</td></tr><tr><td>Fits a load split across several <code>expdp</code>/<code>impdp</code> jobs at different SCNs</td><td>No (every mapped table must share the one CSN)</td><td>Yes</td></tr><tr><td>Extra source-side step</td><td>None</td><td><code>ADD TRANDATA</code>/<code>ADD SCHEMATRANDATA ... PREPARECSN</code> before export</td></tr></tbody></table></figure>



<h3 id="1-prepare-the-tables-on-the-source" class="wp-block-heading">1. Prepare the tables on the source</h3>



<p class="wp-block-paragraph">Using <a href="https://docs.oracle.com/en/database/goldengate/core/26/gclir/add-schematrandata.html" target="_blank" rel="noopener noreferrer"><code>ADD SCHEMATRANDATA</code></a>, we will start by preparing the table on the source. The full clause is <code>ADD SCHEMATRANDATA &lt;schema_name&gt; PREPARECSN {WAIT | LOCK | NOWAIT | NONE}</code>, and <code>NOWAIT</code> is the <strong>default</strong>. In other words, <code>ADD SCHEMATRANDATA</code> prepares tables for instantiation whether you include <code>PREPARECSN</code> or not.</p>



<pre class="wp-block-code"><code>OGG&gt; DBLOGIN USERIDALIAS gg_source DOMAIN OracleGoldenGate
OGG&gt; ADD SCHEMATRANDATA HR
2026-07-26 09:41:07  INFO    OGG-01788  SCHEMATRANDATA has been added on schema HR.
2026-07-26 09:41:07  INFO    OGG-10154  Schema level PREPARECSN set to mode NOWAIT on schema HR.</code></pre>



<p class="wp-block-paragraph">If you do not want instantiation CSN filtering for a schema, you can opt out explicitly with <code>ADD SCHEMATRANDATA HR PREPARECSN NONE</code>. It is the only way to get a table with zero rows in <code>dba_apply_instantiated_objects</code> after a load. Everything else on this page happens by default.</p>



<p class="wp-block-paragraph">The full clause, <code>PREPARECSN {WAIT | LOCK | NOWAIT | NONE}</code>, controls how invasive the preparation is on a live table:</p>



<figure class="wp-block-table"><table><thead><tr><th>Mode</th><th>Behavior</th></tr></thead><tbody><tr><td><code>NOWAIT</code></td><td>Prepares immediately without waiting on in-flight transactions; the default.</td></tr><tr><td><code>WAIT</code></td><td>Waits for currently open transactions on the table to complete before marking it prepared.</td></tr><tr><td><code>LOCK</code></td><td>Takes a lock on the table to guarantee a clean preparation point; the most disruptive, reserved for tables where <code>WAIT</code> cannot be tolerated.</td></tr><tr><td><code>NONE</code></td><td>Disables CSN instantiation.</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">For an OLTP table with a lot of concurrent DML, <code>WAIT</code> or <code>LOCK</code> can stall application sessions while GoldenGate waits for or takes the lock. <code>NOWAIT</code> is almost always the correct option.</p>



<p class="wp-block-paragraph">Confirm both tables are prepared:</p>



<pre class="wp-block-code"><code>OGG&gt; INFO SCHEMATRANDATA HR
Schema HR has 2 prepared tables for instantiation.</code></pre>



<h3 id="2-start-the-extract" class="wp-block-heading">2. Start the extract</h3>



<p class="wp-block-paragraph">Capture has to be running before the export, so that any change committed during and after the dump is safely in the trail:</p>



<pre class="wp-block-code"><code>OGG&gt; START EXTRACT EXTA</code></pre>



<h3 id="3-wait-for-long-running-transactions-to-finish" class="wp-block-heading">3. Wait for long running transactions to finish</h3>



<p class="wp-block-paragraph">A transaction that began before the extract could be missed, so wait for every long running transaction to finish before exporting. See <a href="https://www.dbi-services.com/blog/checking-long-running-transactions-in-goldengate/" target="_blank" rel="noopener noreferrer">Checking Long Running Transactions in GoldenGate</a> for how to list them with the <code>adminclient</code> and the REST API.</p>



<h3 id="4-export-without-flashback_scn" class="wp-block-heading">4. Export without <code>FLASHBACK_SCN</code></h3>



<pre class="wp-block-code"><code>expdp hr/*** dumpfile=hr.dmp schemas=HR</code></pre>



<p class="wp-block-paragraph">Without the <code>FLASHBACK_SCN</code> clause, each table’s boundary will be the SCN as of which Data Pump reads it during the export, recorded automatically because the table was prepared with <code>PREPARECSN</code>.</p>



<h3 id="5-import-on-the-target" class="wp-block-heading">5. Import on the target</h3>



<pre class="wp-block-code"><code>impdp gg_target/*** dumpfile=hr.dmp full=y</code></pre>



<p class="wp-block-paragraph">As part of this import, Data Pump populates <code>dba_apply_instantiated_objects</code> for every prepared table it loads. No extra option is needed.</p>



<h3 id="6-retrieve-the-instantiation-csn-for-each-table" class="wp-block-heading">6. Retrieve the instantiation CSN for each table</h3>



<p class="wp-block-paragraph">Let’s query the table that replaces the SCN you used to write down by hand:</p>



<pre class="wp-block-code"><code>SELECT source_object_owner, source_object_name, instantiation_scn
FROM dba_apply_instantiated_objects
WHERE source_object_owner = 'HR'
ORDER BY 1, 2;</code></pre>



<pre class="wp-block-code"><code>SOURCE_OBJECT_OWNER  SOURCE_OBJECT_NAME  INSTANTIATION_SCN
-------------------- ------------------- -----------------
HR                   DEPARTMENTS                  17662585
HR                   EMPLOYEES                    17662582</code></pre>



<p class="wp-block-paragraph">The two tables come from the same export, but with <strong>two different <code>INSTANTIATION_SCN</code></strong>. Without <code>FLASHBACK_SCN</code> on the export, each table was read (and stamped) at its own point as the dump progressed. That per-table granularity is the entire point, and it is exactly what a single <code>AFTERCSN</code> could never express.</p>



<h3 id="7-configure-the-replicat-and-start-it-without-aftercsn" class="wp-block-heading">7. Configure the replicat and start it, without <code>AFTERCSN</code></h3>



<pre class="wp-block-code"><code>REPLICAT REPA
DBOPTIONS ENABLE_INSTANTIATION_FILTERING
USERIDALIAS gg_target DOMAIN OracleGoldenGate
MAP HR.*, TARGET HR.*;</code></pre>



<pre class="wp-block-code"><code>OGG&gt; START REPLICAT REPA</code></pre>



<p class="wp-block-paragraph"><code>DBOPTIONS ENABLE_INSTANTIATION_FILTERING</code> tells the replicat to look each table’s boundary in <code>dba_apply_instantiated_objects</code> instead of expecting an <code>AFTERCSN</code> on the start command. The replicat discards trail records committed at or before its own boundary and applies everything after it. Both tables are in sync with the source, with no flashback SCN ever chosen.</p>



<h2 id="same-initial-load-with-flashback_scn" class="wp-block-heading">Same initial load with <code>FLASHBACK_SCN</code></h2>



<p class="wp-block-paragraph">Let’s run the same initial load again for a second schema, but add <code>FLASHBACK_SCN</code> to the export and watch what changes in the instantiation table. Pick an SCN and pass it to <code>expdp</code>:</p>



<pre class="wp-block-code"><code>expdp system/*** schemas=HR2 flashback_scn=17663448 dumpfile=hr2.dmp
impdp system/*** dumpfile=hr2.dmp full=y</code></pre>



<p class="wp-block-paragraph">Then the same step 6 query against the target:</p>



<pre class="wp-block-code"><code>SELECT source_object_owner, source_object_name, instantiation_scn
FROM dba_apply_instantiated_objects
WHERE source_object_owner = 'HR2'
ORDER BY 1, 2;</code></pre>



<pre class="wp-block-code"><code>SOURCE_OBJECT_OWNER  SOURCE_OBJECT_NAME  INSTANTIATION_SCN
-------------------- ------------------- -----------------
HR2                  DEPARTMENTS                  17663448
HR2                  EMPLOYEES                    17663448</code></pre>



<p class="wp-block-paragraph">This time, both tables carry the <strong>same instantiation CSN</strong>, and it is <strong>exactly the <code>FLASHBACK_SCN</code></strong> (<code>17663448</code>). <code>FLASHBACK_SCN</code> pins the whole export to one consistent point in time, so Data Pump stamps every table in the dump with that single SCN. Please note that <code>FLASHBACK_SCN</code> is still not <em>required</em> for the instantiation mechanism to work. It only gives a consistent export.</p>



<h2 id="same-initial-load-with-preparecsn-none" class="wp-block-heading">Same initial load with <code>PREPARECSN NONE</code></h2>



<p class="wp-block-paragraph">Let’s see what happens when we disable instantiation, by preparing a third schema with <code>PREPARECSN NONE</code> and run the same export and import:</p>



<pre class="wp-block-code"><code>OGG&gt; ADD SCHEMATRANDATA HR3 ALLCOLS, PREPARECSN NONE
INFO OGG-10154  Schema level PREPARECSN set to mode NONE on schema "HR3"
OGG&gt; INFO SCHEMATRANDATA HR3
Schema "HR3" has 0 prepared tables for instantiation</code></pre>



<pre class="wp-block-code"><code>expdp system/*** schemas=HR3 dumpfile=hr3.dmp
impdp system/*** dumpfile=hr3.dmp full=y</code></pre>



<p class="wp-block-paragraph">The import succeeds and the rows land on the target as normal, but the instantiation table stays empty for this schema:</p>



<pre class="wp-block-code"><code>SELECT source_object_owner, source_object_name, instantiation_scn
FROM dba_apply_instantiated_objects
WHERE source_object_owner = 'HR3';

no rows selected</code></pre>



<p class="wp-block-paragraph">In that case, a replicat running with <code>DBOPTIONS ENABLE_INSTANTIATION_FILTERING</code> would find no boundary for these tables and therefore would not filter them. It would apply every trail record it sees, including changes the dump already contains.</p>



<h3 id="the-boundary-outlives-the-schema" class="wp-block-heading">The boundary outlives the schema</h3>



<p class="wp-block-paragraph"><code>dba_apply_instantiated_objects</code> is independent from the schema it describes. Dropping the target schema with <code>DROP USER ... CASCADE</code> and recreating it does <strong>not</strong> clear its row:</p>



<pre class="wp-block-code"><code>SQL&gt; DROP USER hr4 CASCADE;

User dropped.

SQL&gt; CREATE USER hr4 IDENTIFIED BY Welcome1;

User created.

SQL&gt; SELECT source_object_owner, source_object_name, instantiation_scn
     FROM dba_apply_instantiated_objects WHERE source_object_owner='HR4';

SOURCE_OBJECT_OWNER  SOURCE_OBJECT_NAME  INSTANTIATION_SCN
-------------------- ------------------- -----------------
HR4                  EMPLOYEES                    52356545</code></pre>



<p class="wp-block-paragraph">A stale boundary from a previous initial load can silently attach itself to the next import of an object with the same name. The same table, re-imported a second time from a dump whose source was never prepared with <code>PREPARECSN</code>, does not delete the row from the first prepared initial load.</p>



<p class="wp-block-paragraph">A replicat with <code>ENABLE_INSTANTIATION_FILTERING</code> reading this table afterward would filter every record against a boundary that has no relationship to what the last import actually put on the target.</p>



<p class="wp-block-paragraph">A command exists in the <code>adminclient</code> to clear the instantiation table:</p>



<pre class="wp-block-code"><code>OGG&gt; DBLOGIN USERIDALIAS gg_target DOMAIN OracleGoldenGate
OGG&gt; CLEAR INSTANTIATION CSN FOR hr.employees FROM PDB_SOURCE
INFO OGG-10464  Instantiation CSN has been cleared successfully.</code></pre>



<pre class="wp-block-code"><code>SQL&gt; SELECT source_object_owner, source_object_name, instantiation_scn
     FROM dba_apply_instantiated_objects WHERE source_object_owner='HR';
no rows selected</code></pre>



<p class="wp-block-paragraph">Remember to check the <code>dba_apply_instantiated_objects</code> view before reusing a target schema name for an initial load.</p>



<h2 id="when-should-i-still-set-instantiation-scn-by-hand-" class="wp-block-heading">When should I still set instantiation SCN by hand ?</h2>



<p class="wp-block-paragraph">There are multiple scenarios where automatic instantiation filtering does not work.</p>



<ul class="wp-block-list">
<li>If your initial load is not done by Data Pump. GoldenGate initial extract, a manual <code>INSERT ... SELECT</code> over a database link, transportable tablespaces, do not alter the <code>dba_apply_instantiated_objects</code> view.</li>



<li>If the workload during the initial load is not just DML. Instantiation filtering does not work on DDL, for instance.</li>
</ul>



<p class="wp-block-paragraph">In that case, you can either go back to the <code>FLASHBACK_SCN</code> method, or set the instantiation CSN by hand in the <code>adminclient</code>:</p>



<pre class="wp-block-code"><code>OGG&gt; DBLOGIN USERIDALIAS gg_target DOMAIN OracleGoldenGate
OGG&gt; SET INSTANTIATION CSN FOR hr.legacy_orders CSN 12345678 FROM PDB_SOURCE</code></pre>



<h2 id="common-questions" class="wp-block-heading">Common questions</h2>



<h3 id="a-table-added-after-preparecsn-never-gets-a-boundary" class="wp-block-heading">A table added after <code>PREPARECSN</code> never gets a boundary</h3>



<p class="wp-block-paragraph">If a table is created on the source after you ran <code>ADD SCHEMATRANDATA HR</code>, it is not part of that preparation. Exporting it later with <code>expdp</code> means Data Pump has no CSN bookkeeping to carry into the dump, and <code>dba_apply_instantiated_objects</code> is not populated during import. The fix is to run <code>ADD TRANDATA ...</code> before exporting it.</p>



<h3 id="removing-the-parameter-once-instantiation-is-complete" class="wp-block-heading">Removing the parameter once instantiation is complete</h3>



<p class="wp-block-paragraph"><code>DBOPTIONS ENABLE_INSTANTIATION_FILTERING</code> can be removed from the replicat parameter file once it has processed every transaction past the instantiation CSN of every table it maps (there is no harm in leaving it in indefinitely).</p>



<h2 id="summary" class="wp-block-heading">Summary</h2>



<ul class="wp-block-list">
<li>The instantiation CSN is a per-table replication boundary, stored in <code>dba_apply_instantiated_objects</code> on the target, compared against each record’s commit CSN.</li>



<li>Data Pump stamps it automatically on <code>impdp</code>, because <code>ADD SCHEMATRANDATA</code>/<code>ADD TRANDATA</code> prepare tables for instantiation by default (<code>PREPARECSN NOWAIT</code>). Use <code>PREPARECSN NONE</code> to not use instantiation SCN.</li>



<li>Because that boundary is per table and set by Data Pump, <code>FLASHBACK_SCN</code> and <code>AFTERCSN</code> are no longer needed just to define where the dump ends and replication begins. Retrieve the boundary with a query instead of tracking an SCN by hand.</li>



<li><code>FLASHBACK_SCN</code> still has a use (making one large export internally consistent), but it is no longer needed just to drive the replication boundary. Data Pump records that boundary either way.</li>



<li>The boundary outlives the schema it describes. Dropping and recreating a target schema does not clear its row in <code>dba_apply_instantiated_objects</code>. Check the view, and use <code>CLEAR INSTANTIATION CSN</code> if you see stale rows.</li>
</ul>
<p>L’article <a href="https://www.dbi-services.com/blog/goldengate-instantiation-csn-explained/">GoldenGate Instantiation CSN Explained</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/goldengate-instantiation-csn-explained/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>GoldenGate 26ai AI Service: Full Setup With a Free Gemini Key</title>
		<link>https://www.dbi-services.com/blog/goldengate-26ai-ai-service-full-setup-with-a-free-gemini-key/</link>
					<comments>https://www.dbi-services.com/blog/goldengate-26ai-ai-service-full-setup-with-a-free-gemini-key/#respond</comments>
		
		<dc:creator><![CDATA[Julien Delattre]]></dc:creator>
		<pubDate>Thu, 24 Sep 2026 06:17:15 +0000</pubDate>
				<category><![CDATA[GoldenGate]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[26]]></category>
		<category><![CDATA[26ai]]></category>
		<category><![CDATA[ai service]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[embeddings]]></category>
		<category><![CDATA[gemini]]></category>
		<category><![CDATA[microservices]]></category>
		<category><![CDATA[ogg]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[restapi]]></category>
		<category><![CDATA[vector]]></category>
		<category><![CDATA[web ui]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=47089</guid>

					<description><![CDATA[<p>I sometimes get asked how the new AI Service of GoldenGate 26ai works, and the best way to show it is to see it in action. In this blog, I will set up the AI Service with Google Gemini, using a free API key in Google AI Studio. Most of what will be said here [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/goldengate-26ai-ai-service-full-setup-with-a-free-gemini-key/">GoldenGate 26ai AI Service: Full Setup With a Free Gemini Key</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">I sometimes get asked how the new <strong>AI Service</strong> of GoldenGate 26ai works, and the best way to show it is to see it in action. In this blog, I will <strong>set up the AI Service with Google Gemini</strong>, using a free API key in Google AI Studio. Most of what will be said here can be applied to the other providers supported by GoldenGate 26ai.</p>



<h2 id="new-ai-service-in-goldengate-26ai" class="wp-block-heading">New AI Service in GoldenGate 26ai</h2>



<p class="wp-block-paragraph">The AI Service is a <strong>Service Manager-level microservice</strong>, not a deployment-level one. Extract, replicat, Distribution and Receiver services belong to a deployment. The AI Service belongs to the Service Manager and is shared by every deployment on the host.</p>



<p class="wp-block-paragraph">If you already use GoldenGate 26ai, you probably know that the AI Service has its own binary:</p>



<pre class="wp-block-code"><code>&#091;oracle@vmogg bin]$ ps -ef|grep AIService
oracle     60905   60721  0 20:50 ?        00:00:00 /u01/app/oracle/product/ogg_23.26.3.0.3/bin/AIService</code></pre>



<p class="wp-block-paragraph">The AI Service holds two kinds of objects:</p>



<ul class="wp-block-list">
<li><strong>Providers</strong> (one per external AI service): a base URL and authentication details.</li>



<li><strong>Models</strong> (one per embedding model you want to call): attached to a provider.</li>
</ul>



<p class="wp-block-paragraph"><strong>None of this is stored in a deployment</strong>. This means that when configuring the AI Service, you only need to configure it once for all your deployments. It also means that every deployment can access every AI model you register.</p>



<p class="wp-block-paragraph">Four providers are supported with GoldenGate 26ai: <strong>Google Gemini, OpenAI, OCI Generative AI and Voyage AI</strong>. They can all do the same thing with GoldenGate. On top of this, you can also configure local models.</p>



<h2 id="getting-a-free-gemini-api-key" class="wp-block-heading">Getting a free Gemini API key</h2>



<p class="wp-block-paragraph">The first step when setting up a Gemini AI Service in GoldenGate is to retrieve the Gemini API key. You can create one for free in <strong>Google AI Studio</strong>, at <a href="https://aistudio.google.com/apikey" target="_blank" rel="noopener noreferrer">aistudio.google.com/apikey</a>:</p>



<ul class="wp-block-list">
<li>Sign in with a Google account and open the API keys page.</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="212" height="443" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/001_gemini-ai-service-aistudio-nav-api-keys.png" alt="" class="wp-image-47091" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/001_gemini-ai-service-aistudio-nav-api-keys.png 212w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/001_gemini-ai-service-aistudio-nav-api-keys-144x300.png 144w" sizes="auto, (max-width: 212px) 100vw, 212px" /></figure>
</div>


<ul class="wp-block-list">
<li>Click on <strong>Create API key</strong>.</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="487" height="261" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/002_gemini-ai-service-aistudio-create-a-key-dialog.png" alt="" class="wp-image-47092" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/002_gemini-ai-service-aistudio-create-a-key-dialog.png 487w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/002_gemini-ai-service-aistudio-create-a-key-dialog-300x161.png 300w" sizes="auto, (max-width: 487px) 100vw, 487px" /></figure>
</div>


<ul class="wp-block-list">
<li>Copy the key.</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1426" height="261" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/003_gemini-ai-service-aistudio-api-keys-list.png" alt="" class="wp-image-47096" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/003_gemini-ai-service-aistudio-api-keys-list.png 1426w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/003_gemini-ai-service-aistudio-api-keys-list-1024x187.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/003_gemini-ai-service-aistudio-api-keys-list-765x140.png 765w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/003_gemini-ai-service-aistudio-api-keys-list-300x55.png 300w" sizes="auto, (max-width: 1426px) 100vw, 1426px" /></figure>
</div>


<p class="wp-block-paragraph">There are two things you should know before using this key for GoldenGate.</p>



<ul class="wp-block-list">
<li><strong>Every Gemini API key is associated with a Google Cloud project.</strong> If you have multiple projects, make sure to select a project where the Gemini API is enabled (see below):</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="733" height="566" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/004_gemini-ai-service-google-cloud-api-enabled-dashboard-1.png" alt="" class="wp-image-47095" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/004_gemini-ai-service-google-cloud-api-enabled-dashboard-1.png 733w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/004_gemini-ai-service-google-cloud-api-enabled-dashboard-1-300x232.png 300w" sizes="auto, (max-width: 733px) 100vw, 733px" /></figure>
</div>


<ul class="wp-block-list">
<li><strong>Check the rate limits at <a href="https://aistudio.google.com/rate-limit" target="_blank" rel="noopener noreferrer">aistudio.google.com/rate-limit</a></strong> before sizing anything. Requests per minute, tokens per minute or requests per day are all important metrics that you should keep an eye on.</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="849" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/005_gemini-ai-service-aistudio-rate-limit-page-1024x849.png" alt="" class="wp-image-47097" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/005_gemini-ai-service-aistudio-rate-limit-page-1024x849.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/005_gemini-ai-service-aistudio-rate-limit-page-300x249.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/005_gemini-ai-service-aistudio-rate-limit-page-767x636.png 767w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/005_gemini-ai-service-aistudio-rate-limit-page.png 1437w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p class="wp-block-paragraph">On the free tier, the daily request will most likely be the limited factor. But if the data you are embedding is large, you will be affected by the tokens limit.</p>



<p class="wp-block-paragraph">For a lab, the default project and the key you just created are enough. For anything else, create the key in a dedicated Google Cloud project so quota and billing are isolated. A key created through AI Studio is already restricted to the Gemini API by default, so there is nothing extra to configure there.</p>



<h2 id="goldengate-prerequisites-before-using-the-ai-service" class="wp-block-heading">GoldenGate prerequisites before using the AI Service</h2>



<ul class="wp-block-list">
<li><strong>Outbound connectivity</strong>: An HTTP proxy should be used for an AI service outside your network. If your GoldenGate host reaches the Internet through one, set <code>HTTPS_PROXY</code> from the Service Manager <strong>Configuration</strong> page (in <em><strong>Deployments &gt; ServiceManager &gt; Configuration</strong></em>), as an Environment Variable.</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="168" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/006_goldengate-26ai-ai-service-https-proxy-config-1024x168.png" alt="" class="wp-image-47098" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/006_goldengate-26ai-ai-service-https-proxy-config-1024x168.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/006_goldengate-26ai-ai-service-https-proxy-config-764x125.png 764w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/006_goldengate-26ai-ai-service-https-proxy-config-300x49.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/006_goldengate-26ai-ai-service-https-proxy-config.png 1100w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<ul class="wp-block-list">
<li><strong>CA certificates</strong>: Oracle <strong>requires the use of CA certificates when connecting to any AI service provider</strong>, so the provider’s TLS chain has to be trusted by the Service Manager. Pull the chain with the following command:</li>
</ul>



<pre class="wp-block-code"><code>openssl s_client -showcerts -connect generativelanguage.googleapis.com:443</code></pre>



<p class="wp-block-paragraph">Then, add the CA certificates from the Service Manager certificate management page. The procedure is described in a blog about <a href="https://www.dbi-services.com/blog/ogg-30007-how-to-register-certificates-in-goldengate/" target="_blank" rel="noopener noreferrer">registering certificate in GoldenGate from the web UI</a>. If you skip this step, you will receive the following error when trying to use the AI Service from a replicat:</p>



<pre class="wp-block-code"><code>2026-09-12T08:20:54.578+0000  WARNING OGG-30679  Oracle GoldenGate Delivery for Oracle, REPAI.prm:  Response from EMBED endpoint using model gemini_embed returned error: code REMOTE_INFERENCE_FAILED, message 'SSL connection unexpectedly closed'.</code></pre>



<h2 id="registering-the-provider" class="wp-block-heading">Registering the provider</h2>



<p class="wp-block-paragraph">Again, everything happens in the <strong>Service Manager</strong> web UI.</p>



<ul class="wp-block-list">
<li>Log in to the Service Manager and open the <strong>AI Service</strong> page.</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="277" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/007_goldengate-26ai-ai-service-nav-left-panel-1024x277.png" alt="" class="wp-image-47099" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/007_goldengate-26ai-ai-service-nav-left-panel-1024x277.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/007_goldengate-26ai-ai-service-nav-left-panel-300x81.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/007_goldengate-26ai-ai-service-nav-left-panel-768x208.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/007_goldengate-26ai-ai-service-nav-left-panel.png 1440w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<ul class="wp-block-list">
<li>In the <strong>Providers</strong> section, click <strong>+</strong> and pick the provider type. For this blog, we will use <code>Gemini</code>. Fill in the form and submit.</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="720" height="400" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/008_goldengate-26ai-ai-service-add-provider-gemini-form.png" alt="" class="wp-image-47100" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/008_goldengate-26ai-ai-service-add-provider-gemini-form.png 720w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/008_goldengate-26ai-ai-service-add-provider-gemini-form-300x167.png 300w" sizes="auto, (max-width: 720px) 100vw, 720px" /></figure>
</div>

<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="261" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/009_goldengate-26ai-ai-service-provider-added-1024x261.png" alt="" class="wp-image-47101" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/009_goldengate-26ai-ai-service-provider-added-1024x261.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/009_goldengate-26ai-ai-service-provider-added-766x195.png 766w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/009_goldengate-26ai-ai-service-provider-added-300x76.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/009_goldengate-26ai-ai-service-provider-added.png 1100w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p class="wp-block-paragraph">For Gemini, you just need a URL and a key:</p>



<figure class="wp-block-table"><table><thead><tr><th>Field</th><th>Value</th></tr></thead><tbody><tr><td>Provider ID</td><td><code>gemini</code></td></tr><tr><td>Provider Name</td><td><code>GeminiAiStudio</code></td></tr><tr><td>Base URL</td><td><code>https://generativelanguage.googleapis.com/v1beta</code></td></tr><tr><td>API Key</td><td>the key from Google AI Studio</td></tr></tbody></table></figure>



<p class="wp-block-paragraph"><strong>Keep the base URL</strong>, ending with <code>/v1beta</code>. Gemini embedding calls are a <code>POST</code> to <code>/v1beta/models/&lt;model&gt;:embedContent</code>, so the model-specific part of the path belongs to the model definition, not the provider.</p>



<h2 id="registering-the-model" class="wp-block-heading">Registering the model</h2>



<p class="wp-block-paragraph">Still on the same <strong>AI Service</strong> page, in the <strong>Models</strong> section, click <strong>+</strong>, fill in the form and submit:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="720" height="560" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/010_goldengate-26ai-ai-service-add-model-gemini-form.png" alt="" class="wp-image-47102" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/010_goldengate-26ai-ai-service-add-model-gemini-form.png 720w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/010_goldengate-26ai-ai-service-add-model-gemini-form-300x233.png 300w" sizes="auto, (max-width: 720px) 100vw, 720px" /></figure>
</div>

<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="146" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/011_goldengate-26ai-ai-service-model-added-1024x146.png" alt="" class="wp-image-47103" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/011_goldengate-26ai-ai-service-model-added-1024x146.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/011_goldengate-26ai-ai-service-model-added-300x43.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/011_goldengate-26ai-ai-service-model-added-764x109.png 764w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/011_goldengate-26ai-ai-service-model-added.png 1100w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<figure class="wp-block-table"><table><thead><tr><th>Field</th><th>Value</th></tr></thead><tbody><tr><td>Model ID</td><td><code>gemini_embed</code></td></tr><tr><td>Model Name</td><td><code>gemini-embedding</code></td></tr><tr><td>Remote Model Name</td><td><code>gemini-embedding-001</code></td></tr><tr><td>Provider ID</td><td><code>gemini</code></td></tr><tr><td>Capabilities</td><td><code>Embedding</code></td></tr><tr><td>Enabled</td><td>on</td></tr><tr><td>Maximum Input Characters</td><td>see below</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Here is the meaning of each name given above:</p>



<ul class="wp-block-list">
<li><strong>Remote Model Name</strong> is the name known by the provider.</li>



<li><strong>Model ID</strong> is what will be used in the replicat when using <code>@AISERVICE</code>.</li>



<li><strong>Model Name</strong> is just there for you to organize your models.</li>
</ul>



<p class="wp-block-paragraph"><code>gemini-embedding-001</code> is the current general embedding model from Google. It defaults to <strong>3072 dimensions</strong> and accepts anything from 128 to 3072 through the request’s <code>output_dimensionality</code>, with 768, 1536 and 3072 as the recommended values. Querying the model directly (<code>GET /v1beta/models/gemini-embedding-001</code>) gives its input limit:</p>



<pre class="wp-block-code"><code>{
    "name": "models/gemini-embedding-001",
    "inputTokenLimit": 2048,
    "outputTokenLimit": 1,
    "supportedGenerationMethods": &#091;
        "embedContent",
        "countTextTokens",
        "countTokens",
        "asyncBatchEmbedContent"
    ]
}</code></pre>



<p class="wp-block-paragraph">One note on <strong>Maximum Input Characters</strong>: when I write these lines (September 2026, version <code>23.26.3</code>), I still have an ongoing support request with Oracle about this parameter. The description of the parameter is straightforward, but the feature does not work. No matter the size of the input, everything will be passed to the AI Service, and to the AI model. This means that you could very quickly reach token limits if you don’t pay attention. Until this bug is resolved, do not expect this feature to work as intended.</p>



<p class="wp-block-paragraph">Once a provider is enabled, the <strong>AI Service appears in the Services list</strong> on the Service Manager home page, the models become visible under the <strong>AI Service</strong> entry of the Microservices portal navigation, and they show up on a replicat’s <strong>Parameters</strong> page.</p>



<h2 id="calling-gemini-from-a-goldengate-replicat" class="wp-block-heading">Calling Gemini from a GoldenGate replicat</h2>



<p class="wp-block-paragraph">Here is the syntax for the <code>AISERVICE</code>:</p>



<pre class="wp-block-code"><code>@AISERVICE(embed, &lt;model_id&gt;, &lt;column_name&gt;)</code></pre>



<p class="wp-block-paragraph">Three arguments are needed:</p>



<ul class="wp-block-list">
<li>The capability, <code>embed</code>, is the only option available for now.</li>



<li>The <strong>Model ID</strong>, as registered in the AI Service (not the Model Name!)</li>



<li><strong>One source column</strong>. It cannot be a concatenation of columns. If you try to pass <code>first_column || ' ' || second_column</code> through the AI Service, you will get this error:</li>
</ul>



<pre class="wp-block-code"><code>2026-09-12 08:00:12  WARNING OGG-30081  Error in COLMAP clause. Invalid column mapping function or argument found in the COLMAP clause..
..._embed', name || ' - ' || desc...
                 ^.
2026-09-12 08:00:12  ERROR   OGG-00919  Error in COLMAP clause.</code></pre>



<p class="wp-block-paragraph">Here is an example of a replicat parameter file using <code>AISERVICE</code>:</p>



<pre class="wp-block-code"><code>REPLICAT repai
USERIDALIAS target_pdb26 DOMAIN OracleGoldenGate
DDL INCLUDE MAPPED
MAP PDB1.APP_PDB1.products, TARGET PDB26.APP_PDB26.products,
COLMAP (
    USEDEFAULTS,
    desc_vector = @AISERVICE(embed, 'gemini_embed', description));</code></pre>



<h2 id="the-target-column-has-to-exist-first" class="wp-block-heading">The target column has to exist first</h2>



<p class="wp-block-paragraph">If you edit an existing replicat file to add an embedding, you must create the column on the target first. The AI Service will not create it. The column should be an Oracle <code>VECTOR</code>, and its dimension count has to match what the model returns.</p>



<pre class="wp-block-code"><code>ALTER TABLE app_pdb26.products
ADD (desc_vector VECTOR(3072, FLOAT32));</code></pre>



<p class="wp-block-paragraph">Using the default output of <code>gemini-embedding-001</code> gives <code>VECTOR(3072, FLOAT32)</code>. The dimension shouldn’t be changed later.</p>



<h2 id="ogg-30679-when-the-key-is-wrong" class="wp-block-heading"><code>OGG-30679</code> when the key is wrong</h2>



<p class="wp-block-paragraph">Registering a provider or a model with a bad key produces no error at all, since nothing calls the provider at that point. Starting a replicat does not call it either, if there is no data waiting to be applied. It only happens <strong>when an <code>@AISERVICE</code> mapping processes a row.</strong></p>



<p class="wp-block-paragraph">An invalid key comes back as <strong>HTTP 400, not 401</strong>, with <code>API_KEY_INVALID</code> in the details. This is the full record from <code>ggserr.log</code>:</p>



<pre class="wp-block-code"><code>2026-09-12T09:26:59.205+0000  WARNING OGG-30679  Oracle GoldenGate Delivery for Oracle, REPAI.prm:  Response from EMBED endpoint using model gemini_badkey_model returned error: code REMOTE_INFERENCE_FAILED, message 'HTTP 400 - Bad Request: {
    "error": {
        "code": 400,
        "message": "API key not valid. Please pass a valid API key.",
        "status": "INVALID_ARGUMENT",
        "details": &#091;
        {
            "@type": "type.googleapis.com/google.rpc.ErrorInfo",
            "reason": "API_KEY_INVALID",
            "domain": "googleapis.com",
            "metadata": {
            "service": "generativelanguage.googleapis.com"
            }
        },
        {
            "@type": "type.googleapis.com/google.rpc.LocalizedMessage",
            "locale": "en-US",
            "message": "API key not valid. Please pass a valid API key."
        }
        ]
    }
    }
    '.</code></pre>



<p class="wp-block-paragraph">An <code>OGG-30679</code> error also happens when a key is in a Google Cloud project which has not enabled the Generative Language API. This returns <code>PERMISSION_DENIED</code> (403). Here is the full <code>ggserr.log</code> record:</p>



<pre class="wp-block-code"><code>2026-09-12T09:27:16.666+0000  WARNING OGG-30679  Oracle GoldenGate Delivery for Oracle, REPAI.prm:  Response from EMBED endpoint using model gemini_noaccess_model returned error: code REMOTE_INFERENCE_FAILED, message 'HTTP 403 - Forbidden: {
    "error": {
        "code": 403,
        "message": "Gemini API has not been used in project 293237196494 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/generativelanguage.googleapis.com/overview?project=293237196494 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.",
        "status": "PERMISSION_DENIED",
        "details": &#091;
        {
            "@type": "type.googleapis.com/google.rpc.ErrorInfo",
            "reason": "SERVICE_DISABLED",
            "domain": "googleapis.com",
            "metadata": {
            "serviceTitle": "Gemini API",
            "consumer": "projects/293237196494",
            "containerInfo": "293237196494",
            "activationUrl": "https://console.developers.google.com/apis/api/generativelanguage.googleapis.com/overview?project=293237196494",
            "service": "generativelanguage.googleapis.com"
            }
        },
        {
            "@type": "type.googleapis.com/google.rpc.LocalizedMessage",
            "locale": "en-US",
            "message": "Gemini API has not been used in project 293237196494 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/generativelanguage.googleapis.com/overview?project=293237196494 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry."
        }
        ]
    }
    }
    '.</code></pre>



<p class="wp-block-paragraph">When registering a model/provider, you will not get an error if it is not correctly configured. Running a replicat with an <code>@AISERVICE</code> mapping is the only test which can validate your model registration.</p>



<h2 id="replication-example" class="wp-block-heading">Replication example</h2>



<p class="wp-block-paragraph">Here is an <code>EXTAI</code>/<code>REPAI</code> replication example, inserting into <code>APP_PDB26.products_src</code> on the source:</p>



<pre class="wp-block-code"><code>INSERT INTO app_pdb26.products_src (id, name, description)
VALUES (9701, 'GoldenGate 26ai Live Demo Mug', 'A ceramic mug for GoldenGate engineers, printed with the AI Service architecture diagram.');
COMMIT;</code></pre>



<p class="wp-block-paragraph">On the target, a <code>VECTOR(3072, FLOAT32)</code> column is populated by Gemini:</p>



<pre class="wp-block-code"><code>SELECT id, name, VECTOR_DIMS(desc_vector) AS dims FROM app_pdb26.products WHERE id = 9701;</code></pre>



<pre class="wp-block-code"><code>        ID NAME                            DIMS
---------- ------------------------------ -----
      9701 GoldenGate 26ai Live Demo Mug   3072

# Vector content
&#091;-1.34540349E-002,1.69963725E-002,2.44766194E-002,-6.56813234E-002,-5.2943374E-003,-2.17550527E-003,1.45018185E-002,-1.24750044E-002,1.46362577E-002,...</code></pre>



<p class="wp-block-paragraph">The vector has 3072 dimensions, matching the default output of <code>gemini-embedding-001</code>.</p>



<h2 id="to-summarize" class="wp-block-heading">To summarize</h2>



<p class="wp-block-paragraph">To set up Gemini in GoldenGate 26ai, you need to:</p>



<ol class="wp-block-list">
<li>Create the API key at <a href="https://aistudio.google.com/apikey" target="_blank" rel="noopener noreferrer">aistudio.google.com/apikey</a>. The project must have the Gemini API enabled.</li>



<li>Set <code>HTTPS_PROXY</code> for the Service Manager if the host goes out through a proxy, and register the provider’s CA chain in the Service Manager.</li>



<li>Add the provider in <strong>AI Service</strong>, with the base URL <code>https://generativelanguage.googleapis.com/v1beta</code> and the API key.</li>



<li>Add the model, with <code>gemini-embedding-001</code> as the <em>Remote Model Name</em></li>



<li>Add the <code>VECTOR</code> column to the target table <strong>before</strong> altering the replicat parameter file, sized based on the dimension of the model output.</li>



<li>Add one <code>COLMAP</code> line, <code>USEDEFAULTS</code> and <code>col = @AISERVICE(embed, &lt;model_id&gt;, &lt;column_name&gt;)</code>, with a single column as the third argument.</li>



<li>Apply one row and check the target column. Until this happens, you cannot be sure that your replicat will behave as intended.</li>
</ol>
<p>L’article <a href="https://www.dbi-services.com/blog/goldengate-26ai-ai-service-full-setup-with-a-free-gemini-key/">GoldenGate 26ai AI Service: Full Setup With a Free Gemini Key</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/goldengate-26ai-ai-service-full-setup-with-a-free-gemini-key/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Oracle LDAP Timeouts</title>
		<link>https://www.dbi-services.com/blog/oracle-ldap-timeouts/</link>
					<comments>https://www.dbi-services.com/blog/oracle-ldap-timeouts/#respond</comments>
		
		<dc:creator><![CDATA[Martin Bracher]]></dc:creator>
		<pubDate>Tue, 22 Sep 2026 13:21:39 +0000</pubDate>
				<category><![CDATA[Database management]]></category>
		<category><![CDATA[Oracle]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=46960</guid>

					<description><![CDATA[<p>Introduction, Setup You are using 2 or more LDAP servers for Oracle name resolution to be highly available? Do you kown what happens if an ldap server is down or not reachable? You probably expect that it tries the next one? Short answer: Yes, but probably not with a behavior you expect&#8230; Let&#8217;s see my [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/oracle-ldap-timeouts/">Oracle LDAP Timeouts</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 id="h-introduction-setup" class="wp-block-heading">Introduction, Setup</h2>



<p class="wp-block-paragraph">You are using 2 or more LDAP servers for Oracle name resolution to be highly available? <br>Do you kown what happens if an ldap server is down or not reachable? You probably expect that it tries the next one?</p>



<p class="wp-block-paragraph">Short answer: Yes, but probably not with a behavior you expect&#8230;</p>



<p class="wp-block-paragraph">Let&#8217;s see my test configuration There are 2 ldap servers ol9a and ol9b. For the setup, see my former blog post: <a href="https://www.dbi-services.com/blog/setup-an-ldap-server-for-oracle-naming-on-enterprise-linux-9/" data-type="post" data-id="46966">Setup an LDAP server for Oracle naming on Enterprise Linux 9</a></p>



<pre class="wp-block-code"><code># ldap.ora
DIRECTORY_SERVERS=(ol9a:389:636,ol9b:389:636)
DEFAULT_ADMIN_CONTEXT = "dc=dbi-services,dc=com"
DIRECTORY_SERVER_TYPE = OID</code></pre>



<pre class="wp-block-code"><code># sqlnet.ora
NAMES.DEFAULT_DOMAIN=dbi-services.com
NAMES.DIRECTORY_PATH=(LDAP)</code></pre>



<p class="wp-block-paragraph">With <code>NAMES.DIRECTORY_PATH=(LDAP)</code> we enforce to only use LDAP. Often, you will allow other methods like <code>(LDAP,TNSNAMES,EZCONNECT)</code>. Oracle tries the name resolution in this order. </p>



<h2 id="h-tests-with-an-oracle-client-installation-tnsping" class="wp-block-heading">Tests with an Oracle client installation (tnsping)</h2>



<p class="wp-block-paragraph">Now let&#8217;s see what happens if ldap is not reachable. Note the difference: &#8220;server&#8221; refers to the ldap server process, &#8220;host&#8221; refers to the machine on which the ldap server runs (If the server is up, then logically the host is also up). &#8220;down&#8221; of a host is from the Oracle-client&#8217;s point of view and means that it is unreachable (will not respond), regardless of whether it is a host problem or just a network interruption. &#8220;1st&#8221; means the 1st host/server in the DIRECTORY_SERVERS parameter (in the example ora9a).</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
time tnsping DB1970
</pre></div>


<p class="wp-block-paragraph">We remember: the order is <code>DIRECTORY_SERVERS=(ol9a:389:636,ol9b:389:636)</code></p>



<h3 id="h-both-up" class="wp-block-heading">Both up</h3>



<p class="wp-block-paragraph">If both ldap servers are up, we get an answer in a fraction of a second (as expected).</p>



<h3 id="h-2nd-down" class="wp-block-heading">2nd down</h3>



<p class="wp-block-paragraph">If the 2nd server/host (ora9b) is down, we get an answer in a fraction of a second. I repeated this test several times, and it always responds immediately. That means, there is no round-robin selection of the servers in place.</p>



<h3 id="h-1st-down" class="wp-block-heading">1st down</h3>



<p class="wp-block-paragraph">if the 1st ldap server on ora9a is down (the process, not the host), we get the answer within a fraction of a second from ora9b. the Oracle client immediately detects that there is no ldap server running (error &#8220;Connection refused&#8221; on ldap port). </p>



<p class="wp-block-paragraph">But if the host itself does not respond (stopped, network interruption), then the Oracle client has to wait for a timeout and that is usually more than 10 seconds. Did you expect that? Most customers have never noticed this problem as they have never had an LDAP host failure. </p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
Used LDAP adapter to resolve the alias
Attempting to contact (DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=ltp14s-i)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=DB1970A.erfinder)))
OK (30 msec)

real    0m15.090s
</pre></div>


<p class="wp-block-paragraph">Is that acceptable for your application to wait for &gt;10 seconds? For an interactive login once a day, it is annoying, but probably OK. But with applications that make thousands of short-term logins? In the worst case, the application will get a timeout.</p>



<h2 id="h-configuration-optimization" class="wp-block-heading">Configuration optimization</h2>



<p class="wp-block-paragraph">Can we get around this long timeout? Yes, we can. Add the following parameter to sqlnet.ora:</p>



<pre class="wp-block-code"><code>NAMES.LDAP_CONN_TIMEOUT=1  #value in seconds</code></pre>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
time tnsping db1970

TNS Ping Utility for Linux: Version 19.0.0.0.0 - Production on 18-SEP-2026 16:46:37

Copyright (c) 1997, 2019, Oracle.  All rights reserved.

Used parameter files:
/u00/app/oracle/network/admin/ldap/sqlnet.ora

Used LDAP adapter to resolve the alias
Attempting to contact (DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=ltp14s-i)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=DB1970A)))
OK (10 msec)

real    0m1.040s
</pre></div>


<p class="wp-block-paragraph">Note: the timeouts may have some variations (after a few calls, the timeout was reduced to about 3 seconds for me). <br>The value <code>OK (10 msec)</code> refers only to the time for the listener connect, not for the name resolution. The output of <code>time</code> includes the total time of the tnsping execution.</p>



<h3 id="h-conclusion" class="wp-block-heading">Conclusion:</h3>



<ul class="wp-block-list">
<li>We can configure the ldap failover timeout in seconds. Minimum is 1 second, default seems to be 10-15 sec.</li>



<li>Timeouts only happen when the host is unreachable, not when the LDAP server (software) is stopped.</li>



<li>LDAP servers are used in the order of the DIRECTORY_SERVERS parameter. There is no round-robin for load-balancing.</li>
</ul>



<h2 id="h-tests-with-java-jdbc" class="wp-block-heading">Tests with Java/JDBC</h2>



<p class="wp-block-paragraph">To do the tests with Java jdbc, I will use Oracle&#8217;s <a href="https://www.oracle.com/database/sqldeveloper/technologies/download/" data-type="link" data-id="https://www.oracle.com/database/sqldeveloper/technologies/download/">SQL Developer</a> . </p>



<p class="wp-block-paragraph">I create a new connection using &#8220;Custom JDBC&#8221; and add the following string:</p>



<pre class="wp-block-code"><code>
jdbc:oracle:thin:@ldap://ol9a:389/DB1970,cn=OracleContext,dc=dbi-services,dc=com ldap://ol9b:389/DB1970,cn=OracleContext,dc=dbi-services,dc=com</code></pre>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="916" height="318" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-25.png" alt="" class="wp-image-47043" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-25.png 916w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-25-300x104.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-25-768x267.png 768w" sizes="auto, (max-width: 916px) 100vw, 916px" /></figure>



<p class="wp-block-paragraph">The behavior is like before. But wait&#8230; it isn&#8217;t! <br>I have now noticed that the ldap servers are used round-robin. Sometimes the connect is instantaneous, sometimes it takes the time of the timeout to failover to the other server. </p>



<p class="wp-block-paragraph">The jdbc:thin driver does not use our sqlnet.ora settings. So how can we configure this in Java? Fortunately there is a connection property<br><code> <a href="https://docs.oracle.com/en/database/oracle/oracle-database/21/jajdb/constant-values.html#oracle.jdbc.OracleConnection.CONNECTION_PROPERTY_THIN_JNDI_LDAP_CONNECT_TIMEOUT"> com.sun.jndi.ldap.connect.timeout</a></code> <br>In sqldeveloper you will configure it in the &#8220;Advanced&#8221; tab:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="529" height="118" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-26.png" alt="" class="wp-image-47045" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-26.png 529w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/09/image-26-300x67.png 300w" sizes="auto, (max-width: 529px) 100vw, 529px" /></figure>



<p class="wp-block-paragraph">With JDBC, the values are in milliseconds. Thus, in contrast to the normal client, we can also specify values of less than 1 second (in the example 500 = 0.5 sec.).</p>



<p class="wp-block-paragraph">In sqldeveloper it works. Does it also work with a &#8220;normal&#8221; java program (thanks to duck.ai to generate me the code). The class is named <code>T</code> (like Test).</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: java; title: ; notranslate">
// T.java
import java.sql.*;
import java.util.Properties;

class T {
  public static void main(String&#x5B;] args) throws Exception {
    String url =
        &quot;jdbc:oracle:thin:@ldap://ol9a:389/DB1970,cn=OracleContext,dc=dbi-services,dc=com ldap://ol9b:389/DB1970,cn=OracleContext,dc=dbi-services,dc=com&quot;;

    Properties env = new Properties();
    env.put(&quot;user&quot;, &quot;system&quot;);
    env.put(&quot;password&quot;, &quot;SystemPassword&quot;);
    env.put(&quot;com.sun.jndi.ldap.connect.timeout&quot;, &quot;2000&quot;);

    try (Connection c = DriverManager.getConnection(url, env);
         Statement s = c.createStatement();
         ResultSet r = s.executeQuery(&quot;select host_name from v$instance&quot;)) {
      if (r.next())
        System.out.println(r.getString(1));
    }
  }
}
</pre></div>


<p class="wp-block-paragraph">Then run the program</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
 $ORACLE_HOME/jdk/bin/javac -cp $ORACLE_HOME/jdbc/lib/ojdbc8.jar T.java
 time $ORACLE_HOME/jdk/bin/java -cp $ORACLE_HOME/jdbc/lib/ojdbc8.jar:. T
</pre></div>


<p class="wp-block-paragraph">We will see the same round-robin behavior as in sqldeveloper. Sometimes it takes 0.04-0.6 seconds (tries ol9b first), sometimes it takes 2.05-2.6 seconds (tries ol9a, wait configured timeout of 2sec. , try ol9b and connect)</p>



<h3 id="h-conclusion-0" class="wp-block-heading">Conclusion:</h3>



<ul class="wp-block-list">
<li>We can configure the ldap failover timeout in milliseconds (in contrast to seconds with OCI client like sqlplus)</li>



<li>Timeouts only happen when the host is unreachable, not when the LDAP server (software) is stopped.</li>



<li>LDAP servers defined in the DIRECTORY_SERVERS parameter are used in a rond-robin order which is ideal for load-balancing.</li>
</ul>



<h2 id="h-general-remarks-and-conclusions" class="wp-block-heading">General remarks and conclusions</h2>



<ul class="wp-block-list">
<li>a timeout does not occur when the ldap service is stopped. The client immediately receives an error message from the host and can ask the other ldap</li>



<li>If the first ldap server does not know the requested name, it will not try other ldap servers, but will try (if configured in names.directory_path) other naming methods (e.g. tnsnames.ora)</li>



<li>The configured timeout is the maximum timeout. If it finds out that the host is not reachable, it tries the next one (e.g. the hostname is unknown).</li>
</ul>



<p class="wp-block-paragraph">For normal sql*net clients using the *.ora files (TNS_ADMIN / &#8230;/network/admin; see my <a href="https://www.dbi-services.com/blog/tns_admin-which-ora-files-oracle-will-use/">blog post</a>), you can configure the timeout in sqlnet.ora</p>



<pre class="wp-block-code"><code>NAMES.LDAP_CONN_TIMEOUT=1  #value in seconds</code></pre>



<p class="wp-block-paragraph">For Java JDBC clients, set the property</p>



<pre class="wp-block-code"><code>com.sun.jndi.ldap.connect.timeout=1000  #value in milliseconds</code></pre>



<p class="wp-block-paragraph"></p>
<p>L’article <a href="https://www.dbi-services.com/blog/oracle-ldap-timeouts/">Oracle LDAP Timeouts</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/oracle-ldap-timeouts/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>DDL Filtering in GoldenGate Extract and Replicat</title>
		<link>https://www.dbi-services.com/blog/ddl-filtering-in-goldengate-extract-and-replicat/</link>
					<comments>https://www.dbi-services.com/blog/ddl-filtering-in-goldengate-extract-and-replicat/#respond</comments>
		
		<dc:creator><![CDATA[Julien Delattre]]></dc:creator>
		<pubDate>Mon, 21 Sep 2026 07:11:00 +0000</pubDate>
				<category><![CDATA[GoldenGate]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[26]]></category>
		<category><![CDATA[26ai]]></category>
		<category><![CDATA[ddl]]></category>
		<category><![CDATA[extract]]></category>
		<category><![CDATA[filtering]]></category>
		<category><![CDATA[ogg]]></category>
		<category><![CDATA[replicat]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=46803</guid>

					<description><![CDATA[<p>When replicating data with GoldenGate, you often want DDL changes (table alterations, new tables, dropped indexes, etc.) to follow alongside DML. But replicating all DDL is sometimes dangerous (TRUNCATE, DROP TABLE) or simply impossible (architecture differences between source and target). DDL filtering gives you precise control over this. This blog covers multiple aspects, including latest [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/ddl-filtering-in-goldengate-extract-and-replicat/">DDL Filtering in GoldenGate Extract and Replicat</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">When replicating data with GoldenGate, you often want DDL changes (table alterations, new tables, dropped indexes, etc.) to follow alongside DML. But replicating <em>all</em> DDL is sometimes dangerous (<code>TRUNCATE</code>, <code>DROP TABLE</code>) or simply impossible (architecture differences between source and target). DDL filtering gives you precise control over this.</p>



<p class="wp-block-paragraph">This blog covers multiple aspects, including latest changes introduced in GoldenGate 26ai:</p>



<ul class="wp-block-list">
<li><a href="#extract-vs-replicat-ddl-filtering">Difference between extract and replicat filtering</a></li>



<li><a href="#scopes-mapped-unmapped-other-all">DDL filtering model and syntax</a></li>



<li><a href="#andor-logic">AND/OR logic</a></li>



<li><a href="#ddloptions-parameter"><code>DDLOPTIONS</code> parameter</a></li>



<li><a href="#tag-based-ddl-filtering-excludetag-and-includetag">Tag-based filtering (<code>EXCLUDETAG</code>/<code>INCLUDETAG</code>)</a></li>



<li><a href="#edge-cases">Edge cases</a></li>
</ul>



<h2 id="extract-vs-replicat-ddl-filtering" class="wp-block-heading">Extract vs Replicat DDL filtering</h2>



<p class="wp-block-paragraph">Before diving into the syntax, you should understand that DDL filtering means something <strong>different for an extract and a replicat</strong>.</p>



<p class="wp-block-paragraph"><strong>For an extract</strong>, filtering controls what gets <strong>written to the trail file</strong>. If a DDL statement is excluded at the extract level, it is gone forever, and will never reach any downstream replicat. This makes extract-level filtering absolute and decisive. On the other side, it keeps trail files smaller and ensures no downstream replicat ever sees unwanted DDL.</p>



<p class="wp-block-paragraph"><strong>For a replicat</strong>, filtering controls what gets <strong>applied to the target database</strong>. In that case, the DDL statement is considered to be already in the trail file. The replicat simply chooses to apply it or skip it. This gives more flexibility. For instance, multiple replicats can read the same trail and each apply a different subset of DDL. Of course, the <strong>trail files are larger</strong>, and generate more I/O.</p>



<p class="wp-block-paragraph">This does not mean that you should choose one or another. A common use case is to do <strong>generic filtering at the extract level</strong> (removing clearly irrelevant DDL like <code>CREATE USER</code> or <code>GRANT</code>), and more <strong>targeted filtering for each replicat</strong> (for example, suppressing <code>TRUNCATE</code> on a target holding additional rows).</p>



<h2 id="enabling-ddl-replication" class="wp-block-heading">Enabling DDL Replication</h2>



<p class="wp-block-paragraph">DDL replication is <strong>disabled by default</strong>. You must explicitly enable it in both extract and replicat parameter files.</p>



<p class="wp-block-paragraph">The simplest form is:</p>



<div class="proof-block"><div class="code-block-wrapper"><pre tabindex="0" data-language="text"><code>DDL</code></pre></div></div>



<p class="wp-block-paragraph">This enables DDL replication with no filtering. All DDL is captured (extract) or applied (replicat). In practice this is almost never what you want. You will almost always pair it with <code>INCLUDE</code> or <code>EXCLUDE</code> clauses.</p>



<h2 id="scopes-mapped-unmapped-other-all" class="wp-block-heading">Scopes: <code>MAPPED</code>, <code>UNMAPPED</code>, <code>OTHER</code>, <code>ALL</code></h2>



<p class="wp-block-paragraph">Every DDL statement GoldenGate encounters is classified into one of four scopes based on whether the object it operates on matches your <code>TABLE</code> (extract) or <code>MAP</code> (replicat) parameter list.</p>



<figure class="wp-block-table"><table><thead><tr><th>Scope</th><th>Meaning</th></tr></thead><tbody><tr><td><code>MAPPED</code></td><td>The DDL object matches a <code>TABLE</code>/<code>MAP</code> entry</td></tr><tr><td><code>UNMAPPED</code></td><td>The DDL object does NOT match any <code>TABLE</code>/<code>MAP</code> entry</td></tr><tr><td><code>OTHER</code></td><td>DDL not associated with a specific object at all (e.g. <code>CREATE USER</code>, <code>CREATE TABLESPACE</code>)</td></tr><tr><td><code>ALL</code></td><td><code>MAPPED</code>, <code>UNMAPPED</code>, and <code>OTHER</code></td></tr></tbody></table></figure>



<p class="wp-block-paragraph">If you do not specify a scope, <strong>GoldenGate defaults to <code>ALL</code></strong>.</p>



<h3 id="example" class="wp-block-heading">Example</h3>



<p class="wp-block-paragraph">With this extract parameter file:</p>



<pre class="wp-block-code"><code>EXTRACT EXT
USERIDALIAS source_cdb DOMAIN OracleGoldenGate
EXTTRAIL pdb1/aa
SOURCECATALOG PDB1
DDL INCLUDE ALL
TABLE APP_SCHEMA.*;</code></pre>



<ul class="wp-block-list">
<li><code>CREATE TABLE APP_SCHEMA.ORDERS (...)</code> is <strong><code>MAPPED</code></strong> (matches <code>APP_SCHEMA.*</code>)</li>



<li><code>CREATE TABLE AUDIT_SCHEMA.LOGS (...)</code> is <strong><code>UNMAPPED</code></strong> (does not match <code>APP_SCHEMA.*</code>)</li>



<li><code>GRANT SELECT ON APP_SCHEMA.ORDERS TO READONLY</code> is <span class="proof-marker"><strong><code>MAPPED</code></strong> (a <code>GRANT</code> on a specific object follows that object’s own scope, not <code>OTHER</code>. <code>OTHER</code> is only for DDL with no target object at all, like <code>CREATE USER</code>)</span></li>
</ul>



<p class="wp-block-paragraph">Switching to <code>DDL INCLUDE MAPPED</code> would capture the first and third statements.</p>



<p class="wp-block-paragraph">The DDL statement’s scope depends on the operation: see “Interaction with <code>TABLE</code> and <code>MAP</code> Parameters” below for more details.</p>



<h2 id="filter-keywords" class="wp-block-heading">Filter Keywords</h2>



<p class="wp-block-paragraph">On top of scope filtering, you can also filter DDL by <strong>object type, operation type, object name, and DDL text content</strong>. These filters are specified as comma-separated conditions within a single <code>DDL</code> clause. All conditions in a single clause are added together (logical <code>AND</code>).</p>



<h3 id="objtype" class="wp-block-heading"><code>OBJTYPE</code></h3>



<p class="wp-block-paragraph">Filters by the type of database object the DDL operates on.</p>



<p class="wp-block-paragraph">Common Oracle object types: <code>TABLE</code>, <code>INDEX</code>, <code>SEQUENCE</code>, <code>VIEW</code>, <code>PROCEDURE</code>, <code>FUNCTION</code>, <code>TRIGGER</code>, <code>PACKAGE</code>, <code>TYPE</code>, <code>SYNONYM</code>, <code>DATABASE LINK</code>, <code>TABLESPACE</code>, <code>USER</code>.</p>



<div class="proof-block"><div class="code-block-wrapper"><pre tabindex="0" data-language="text"><code>-- Only capture DDL on tables
DDL INCLUDE MAPPED, OBJTYPE 'TABLE'

-- Only capture DDL on indexes
DDL INCLUDE MAPPED, OBJTYPE 'INDEX'</code></pre></div></div>



<h3 id="optype" class="wp-block-heading"><code>OPTYPE</code></h3>



<p class="wp-block-paragraph">Filters by the type of DDL operation.</p>



<p class="wp-block-paragraph">Common operation types: <code>CREATE</code>, <code>ALTER</code>, <code>DROP</code>, <code>RENAME</code>, <code>TRUNCATE</code>, <code>GRANT</code>, <code>REVOKE</code>, <code>COMMENT</code>.</p>



<div class="proof-block"><div class="code-block-wrapper"><pre tabindex="0" data-language="text"><code>-- Only capture CREATE TABLE statements
DDL INCLUDE MAPPED, OBJTYPE 'TABLE', OPTYPE CREATE

-- Exclude DROP operations on all object types
DDL EXCLUDE MAPPED, OPTYPE DROP</code></pre></div></div>



<p class="wp-block-paragraph"><span class="proof-marker"><code>OPTYPE RENAME</code> exists and works, but classification depends on the exact SQL used. A <code>RENAME old TO new;</code> statement matches <code>OPTYPE RENAME</code> (GoldenGate logs <code>OGG-10457 DDL RENAME found ... RENAME converted to ALTER TABLE</code> while writing it, then classifies the resulting <code>OGG-10451</code>/<code>OGG-10452</code> line as <code>optype [RENAME]</code>). But <code>ALTER TABLE ... RENAME TO ...</code> (the form most people write, since <code>RENAME</code> cannot be schema-qualified) matches <code>OPTYPE ALTER</code> instead, with no <code>RENAME</code> classification and no conversion message at all.</span></p>



<h3 id="objname" class="wp-block-heading"><code>OBJNAME</code></h3>



<p class="wp-block-paragraph">Filters by object name. Supports wildcards (<code>*</code> for any sequence of characters, <code>?</code> for a single character). For Oracle, use the <code>schema.object</code> format, or <code>container.schema.object</code> in multitenant. <span class="proof-marker">Write the value with no quotes at all. <code>OBJNAME 'APP_SCHEMA.*'</code> (single-quoted) abends with <code>OGG-06377 Single quote marks cannot be used to delimit OBJNAME</code>, and <code>OBJNAME "APP_SCHEMA.*"</code> (double-quoted) abends differently, with <code>OGG-06585 No schema is specified</code>. A double-quoted value is taken as one literal token and never splits on its dot into schema and object.</span></p>



<pre class="wp-block-code"><code>-- Only capture DDL for tables starting with ORD_ in APP_SCHEMA
DDL INCLUDE MAPPED, OBJTYPE 'TABLE', OBJNAME APP_SCHEMA.ORD_*

-- Exclude DDL on any staging table
DDL EXCLUDE MAPPED, OBJNAME APP_SCHEMA.*_STG</code></pre>



<h3 id="instr" class="wp-block-heading"><code>INSTR</code></h3>



<p class="wp-block-paragraph">Filters based on whether a literal string appears anywhere in the DDL text (case-sensitive). This is especially useful for <strong>excluding</strong> certain kinds of DDL.</p>



<div class="proof-block"><div class="code-block-wrapper"><pre tabindex="0" data-language="text"><code>-- Exclude any DDL containing NOLOGGING
DDL EXCLUDE MAPPED, INSTR 'NOLOGGING'

-- Exclude DDL referencing a specific tablespace by name
DDL EXCLUDE MAPPED, INSTR 'ARCHIVE_TBS'</code></pre></div></div>



<h3 id="instrwords" class="wp-block-heading"><code>INSTRWORDS</code></h3>



<p class="wp-block-paragraph">Similar to <code>INSTR</code>, but performs word-level matching. The order of the words does not matter, and partial matches within longer words are not counted.</p>



<div class="proof-block"><div class="code-block-wrapper"><pre tabindex="0" data-language="text"><code>-- Exclude DDL that contains both the words COMPRESS and OLTP (in any order)
DDL EXCLUDE MAPPED, INSTRWORDS 'COMPRESS OLTP'</code></pre></div></div>



<h3 id="eventactions" class="wp-block-heading"><code>EVENTACTIONS</code></h3>



<p class="wp-block-paragraph">Unlike the keywords above, <code>EVENTACTIONS</code> is not specific to <code>DDL</code>: it is a general GoldenGate keyword also usable on <code>TABLE</code> and <code>MAP</code> clauses, for triggering an action (<code>REPORT</code>, <code>LOG</code>, and others) whenever a record matches that clause. It happens to be usable inside a <code>DDL</code> clause too, comma-separated alongside <code>OBJTYPE</code>/<code>OPTYPE</code>/<code>OBJNAME</code>/<code>INSTR</code> like any other filter keyword, and it comes with real, DDL-specific behavior worth knowing.</p>



<p class="wp-block-paragraph"><code>EVENTACTIONS (REPORT)</code> forces the same <code>DDL replication statistics</code> block that <code>DDLOPTIONS REPORT</code> writes on demand (see the <code>DDLOPTIONS</code> section below). However, it <strong>only works on an <code>INCLUDE</code> clause</strong>:</p>



<pre class="wp-block-code"><code>DDL INCLUDE MAPPED, EVENTACTIONS (REPORT)</code></pre>



<div class="proof-block"><div class="code-block-wrapper"><pre tabindex="0" data-language="text"><code>2026-09-05 11:52:47  INFO    OGG-01487  DDL found, operation [create table ddltest.evt1 (id number) (size 37)], start SCN [24368602], commit SCN [24368634] instance [ (1)], DDL seqno [0], marker seqno [0].

2026-09-05 11:52:47  INFO    OGG-10451  DDL operation included [INCLUDE MAPPED, EVENTACTIONS (REPORT)], optype [CREATE], objtype [TABLE], catalog "PDB1", objowner "DDLTEST", objname "EVT1".

***********************************************************************
*                   ** Run Time Statistics **                         *
***********************************************************************


Report at 2026-09-05 11:52:47.388472 (activity since 2026-09-05 11:50:36.261708)

Output to dt:



DDL replication statistics:

                    Operations:         0
             Mapped operations:         0
           Unmapped operations:         0
              Other operations:         0
           Excluded operations:         0


No records extracted.</code></pre></div></div>



<p class="wp-block-paragraph"><strong>This is verbose.</strong> A second <code>CREATE TABLE</code> matching the same clause produced a second, identical-shaped block right after its own <code>OGG-10451</code> line. This means that every matching DDL gets its own full statistics dump on top of the usual <code>OGG-01487</code>/<code>OGG-10451</code>/<code>OGG-10452</code> lines. On a replication with any real amount of DDL traffic, this multiplies report file growth well past what plain <code>DDLOPTIONS REPORT</code> alone produces.  Try to restrict <code>EVENTACTIONS (REPORT)</code> to a narrow <code>INCLUDE</code> clause: a specific <code>OBJTYPE</code>, <code>OPTYPE</code>, or <code>OBJNAME</code> you want to log in the report file.</p>



<div class="proof-block"><p>Please note that the behavior is different for <code>EXCLUDE</code> clauses. The same <code>EVENTACTIONS (REPORT)</code> written on an <code>EXCLUDE</code> clause instead (see below example) excludes a <code>TRUNCATE</code> normally (<code>OGG-10452 DDL operation excluded [EXCLUDE MAPPED, OPTYPE TRUNCATE, EVENTACTIONS (REPORT)]</code>), but no <code>DDL replication statistics</code> block follows it.</p></div>



<pre class="wp-block-code"><code>DDL INCLUDE MAPPED &amp;
    EXCLUDE MAPPED, OPTYPE TRUNCATE, EVENTACTIONS (REPORT)</code></pre>



<h2 id="andor-logic" class="wp-block-heading"><code>AND</code>/<code>OR</code> Logic</h2>



<p class="wp-block-paragraph"><span class="proof-marker"><strong>Only one <code>DDL</code> parameter is allowed per parameter file.</strong> A parameter file with two separate <code>DDL</code> lines abends at startup with <code>OGG-00403 There can be only one DDL filtering statement</code>: “Only one DDL parameter can be used in a parameter file, but you can combine multiple inclusion and exclusion options to filter the DDL to the required level.” Everything below happens <strong>inside that single <code>DDL</code> parameter</strong>: each clause after the first drops the leading <code>DDL</code> keyword and starts directly with <code>INCLUDE</code> or <code>EXCLUDE</code>, and the whole thing is continued with <code>&amp;</code>.</span></p>



<h3 id="and-conditions-within-a-single-ddl-clause" class="wp-block-heading"><code>AND</code>: conditions within a single <code>DDL</code> clause</h3>



<p class="wp-block-paragraph">A DDL statement must satisfy <strong>all</strong> conditions to match.</p>



<div class="proof-block"><div class="code-block-wrapper"><pre tabindex="0" data-language="text"><code>-- Capture only CREATE TABLE in APP_SCHEMA (all three conditions must be true)
DDL INCLUDE MAPPED, OBJTYPE 'TABLE', OPTYPE CREATE, OBJNAME APP_SCHEMA.*</code></pre></div></div>



<p class="wp-block-paragraph">A <code>DROP TABLE APP_SCHEMA.ORDERS</code> would not match this clause because <code>OPTYPE DROP</code> is different from <code>OPTYPE CREATE</code>.</p>



<h3 id="or-multiple-includeexclude-clauses" class="wp-block-heading"><code>OR</code>: multiple <code>INCLUDE</code>/<code>EXCLUDE</code> clauses</h3>



<p class="wp-block-paragraph">Only one <code>DDL</code> parameter is allowed per parameter file, but that parameter can carry multiple <code>INCLUDE</code>/<code>EXCLUDE</code> clauses, separated with <code>&amp;</code>. Multiple <code>INCLUDE</code> clauses are evaluated as a logical <code>OR</code>: a DDL statement is captured if it matches <strong>any</strong> <code>INCLUDE</code> clause. The indentation is optional.</p>



<div class="proof-block"><div class="code-block-wrapper"><pre tabindex="0" data-language="text"><code>-- Capture CREATE TABLE or CREATE SEQUENCE (either clause is sufficient)
DDL INCLUDE MAPPED, OBJTYPE 'TABLE', OPTYPE CREATE &amp;
    INCLUDE MAPPED, OBJTYPE 'SEQUENCE', OPTYPE CREATE</code></pre></div></div>



<h3 id="exclude-always-wins-over-include" class="wp-block-heading"><code>EXCLUDE</code> always wins over <code>INCLUDE</code></h3>



<p class="wp-block-paragraph">If a DDL statement matches both an <code>INCLUDE</code> clause and an <code>EXCLUDE</code> clause, the <code>EXCLUDE</code> wins. This lets you set broader <code>INCLUDE</code> rules and choose specific exceptions. An <code>EXCLUDE</code> clause always needs a corresponding <code>INCLUDE</code> clause in the same <code>DDL</code> parameter, it cannot stand alone.</p>



<div class="proof-block"><div class="code-block-wrapper"><pre tabindex="0" data-language="text"><code>-- Include all MAPPED DDL, but exclude TRUNCATE
DDL INCLUDE MAPPED &amp;
    EXCLUDE MAPPED, OPTYPE TRUNCATE</code></pre></div></div>



<p class="wp-block-paragraph"><span class="proof-marker">A lone <code>EXCLUDE</code> clause with no corresponding <code>INCLUDE</code> still abends (<code>OGG-06374 Invalid DDL statement: No INCLUDE</code>). <code>EXCLUDE</code> narrows an <code>INCLUDE</code>; it cannot stand alone.</span> Every multi-clause example in this post uses this single-<code>DDL</code>-parameter, <code>&amp;</code>-continued form.</p>



<h2 id="filtering-examples" class="wp-block-heading">Filtering Examples</h2>



<p class="wp-block-paragraph">You can build nearly all sorts of DDL filtering in GoldenGate. But you should <strong>always ensure</strong> that they are <strong>relevant to the workload on the source and target</strong> databases !</p>



<h3 id="example-1-structural-ddl-only-no-destructive-operations" class="wp-block-heading">Example 1: Structural DDL only, no destructive operations</h3>



<p class="wp-block-paragraph">Goal: replicate <code>CREATE</code> and <code>ALTER</code> on tables and sequences, but never <code>DROP</code> or <code>TRUNCATE</code>.</p>



<div class="proof-block"><div class="code-block-wrapper"><pre tabindex="0" data-language="text"><code>DDL INCLUDE MAPPED, OBJTYPE 'TABLE', OPTYPE CREATE &amp;
    INCLUDE MAPPED, OBJTYPE 'TABLE', OPTYPE ALTER &amp;
    INCLUDE MAPPED, OBJTYPE 'SEQUENCE', OPTYPE CREATE &amp;
    INCLUDE MAPPED, OBJTYPE 'SEQUENCE', OPTYPE ALTER</code></pre></div></div>



<p class="wp-block-paragraph">Any <code>DROP TABLE</code>, <code>TRUNCATE TABLE</code>, or <code>DROP SEQUENCE</code> on a mapped object will be silently ignored.</p>



<h3 id="example-2-everything-except-nologging-directives" class="wp-block-heading">Example 2: Everything except <code>NOLOGGING</code> directives</h3>



<p class="wp-block-paragraph">Here, the goal is to replicate all <code>MAPPED</code> DDL, but exclude any DDL containing the <code>NOLOGGING</code> directive.</p>



<div class="proof-block"><div class="code-block-wrapper"><pre tabindex="0" data-language="text"><code>DDL INCLUDE MAPPED &amp;
    EXCLUDE MAPPED, INSTR 'NOLOGGING'</code></pre></div></div>



<h3 id="example-3-replicat-applies-only-a-subset-of-a-rich-trail" class="wp-block-heading">Example 3: Replicat applies only a subset of a rich trail</h3>



<p class="wp-block-paragraph">If a trail was generated with <code>DDL INCLUDE ALL</code> at the extract level, and you need the replicat to apply only <code>CREATE TABLE</code> and <code>ALTER TABLE</code> on mapped objects:</p>



<div class="proof-block"><div class="code-block-wrapper"><pre tabindex="0" data-language="text"><code>DDL INCLUDE MAPPED, OBJTYPE 'TABLE', OPTYPE CREATE &amp;
    INCLUDE MAPPED, OBJTYPE 'TABLE', OPTYPE ALTER
MAP APP_SCHEMA.*, TARGET TARGET_SCHEMA.*;</code></pre></div></div>



<p class="wp-block-paragraph">All other DDLs in the trail (<code>DROP</code>, <code>TRUNCATE</code>, index changes, sequences) are skipped by this replicat.</p>



<h3 id="example-4-mapped-objects-plus-a-specific-unmapped-schema" class="wp-block-heading">Example 4: Mapped objects plus a specific unmapped schema</h3>



<div class="proof-block"><div class="code-block-wrapper"><pre tabindex="0" data-language="text"><code>-- Capture DDL for APP_SCHEMA (mapped) and also for SHARED_SCHEMA (not in the TABLE filtering)
DDL INCLUDE MAPPED &amp;
    INCLUDE UNMAPPED, OBJNAME SHARED_SCHEMA.* &amp;
    EXCLUDE MAPPED, OPTYPE TRUNCATE &amp;
    EXCLUDE UNMAPPED, OPTYPE DROP
TABLE APP_SCHEMA.*;</code></pre></div></div>



<h2 id="ddloptions-parameter" class="wp-block-heading"><code>DDLOPTIONS</code> parameter</h2>



<p class="wp-block-paragraph"><code>DDLOPTIONS</code> often comes with <code>DDL</code> and controls what happens when DDL is processed. It is a global setting which applies to <strong>all</strong> DDL replication.</p>



<h3 id="report" class="wp-block-heading"><code>REPORT</code></h3>



<p class="wp-block-paragraph">Writes each DDL statement encountered (whether included or excluded) to the extract or replicat report file.</p>



<pre class="wp-block-code"><code>DDLOPTIONS REPORT</code></pre>



<p class="wp-block-paragraph">With <code>DDL INCLUDE ALL</code>, a <code>CREATE TABLE DDLTEST.PROMOTIONS</code> on the source produces entries like these in the report file:</p>



<div class="proof-block"><div class="code-block-wrapper"><pre tabindex="0" data-language="text"><code>2026-09-05 16:10:12  INFO    OGG-01487  DDL found, operation [create table ddltest.promotions (id number, discount number) (size 60)], start SCN [23026101], commit SCN [23026117] instance [ (1)], DDL seqno [0], marker seqno [0].
2026-09-05 16:10:12  INFO    OGG-10451  DDL operation included [INCLUDE ALL], optype [CREATE], objtype [TABLE], catalog "PDB1", objowner "DDLTEST", objname "PROMOTIONS".</code></pre></div></div>



<p class="wp-block-paragraph">This is very useful for <strong>testing, or when the DDL volume is low</strong>. However, <strong>never include <code>DDLOPTIONS REPORT</code></strong> if you have a lot of DDLs. Your report files will grow without control.</p>



<p class="wp-block-paragraph">A running process also keeps a running count of DDL statements by scope, separate from the per-statement <code>DDLOPTIONS REPORT</code> lines above. Request it on demand with <code>SEND EXTRACT &lt;name&gt;, REPORT</code> (or <code>SEND REPLICAT &lt;name&gt;, REPORT</code>) through the <code>adminclient</code>. It also gets written automatically whenever the process stops.</p>



<div class="proof-block"><div class="code-block-wrapper"><pre tabindex="0" data-language="text"><code>***********************************************************************
*                   ** Run Time Statistics **                         *
***********************************************************************

Report at 2026-09-05 11:34:23.315905 (activity since 2026-09-05 11:31:27.204191)

DDL replication statistics:

                    Operations:         1
             Mapped operations:         1
           Unmapped operations:         0
              Other operations:         0
           Excluded operations:         0</code></pre></div></div>



<p class="wp-block-paragraph">The report (<code>Mapped</code>/<code>Unmapped</code>/<code>Other</code>/<code>Excluded</code>) mirrors the scope model from the “Scopes” section above, so it is a quick way to check whether your filtering is doing what you expect without scrolling through every individual <code>OGG-01487</code>/<code>OGG-10451</code>/<code>OGG-10452</code> line.</p>



<h3 id="ddlerror-replicat-only" class="wp-block-heading"><code>DDLERROR</code> (Replicat only)</h3>



<p class="wp-block-paragraph">Controls what happens when a DDL statement fails on the target. The default is to abend.</p>



<pre class="wp-block-code"><code>DDLERROR DEFAULT DISCARD</code></pre>



<p class="wp-block-paragraph"><code>DDLERROR</code> is a top-level parameter, not a <code>DDLOPTIONS</code> sub-keyword. As you can imagine, use <code>DISCARD</code> with caution. It could silently leave the target schema out of sync.</p>



<h2 id="tag-based-ddl-filtering-excludetag-and-includetag" class="wp-block-heading">Tag-Based DDL Filtering: <code>EXCLUDETAG</code> and <code>INCLUDETAG</code></h2>



<p class="wp-block-paragraph">Oracle GoldenGate 26ai adds a second, independent filtering layer on top of everything above. You can now filter by <strong>tag</strong> rather than by scope or object. Every DDL statement GoldenGate encounters carries a tag identifying its origin.</p>



<p class="wp-block-paragraph">By default, an extract applies <code>DDLOPTIONS EXCLUDETAG +</code>, which <strong>excludes all tagged DDL</strong> unless a tag is explicitly allowed with <code>INCLUDETAG</code>:</p>



<div class="proof-block"><div class="code-block-wrapper"><pre tabindex="0" data-language="text"><code>-- Exclude every tagged DDL statement by default (implicit default)
DDLOPTIONS EXCLUDETAG +

-- Explicitly allow DDL carrying tag 00 (Data Pump)
DDLOPTIONS INCLUDETAG 00</code></pre></div></div>



<p class="wp-block-paragraph">The practical impact is on tools that stamp a session tag on the DDL they issue. For instance, <code>impdp</code> tags its DDL with tag <code>00</code>. Under GoldenGate 26ai default behavior, that DDL is excluded from replication unless the extract explicitly adds <code>DDLOPTIONS INCLUDETAG 00</code>. Please note that this is a behavioral <strong>change from earlier versions</strong> of GoldenGate. Before, <code>impdp</code> DDL was captured without any extra configuration needed. If an import via <code>impdp</code> is expected to replicate its DDL, check for this setting before assuming the default behavior still applies.</p>



<p class="wp-block-paragraph"><code>EXCLUDETAG</code>/<code>INCLUDETAG</code> do not replace the scope and filter-keyword model. A DDL statement still has to pass the <code>DDL INCLUDE</code>/<code>DDL EXCLUDE</code> scope and keyword filtering described above. Both filtering systems have to allow the DDL.</p>



<h2 id="interaction-with-table-and-map-parameters" class="wp-block-heading">Interaction with <code>TABLE</code> and <code>MAP</code> Parameters</h2>



<p class="wp-block-paragraph">Here are the scope (<code>MAPPED</code>/<code>UNMAPPED</code>/…) assignment rules for standard <code>TABLE</code> DDL.</p>



<div class="proof-block"><div class="table-scroll">




























<table><thead><tr><th>DDL Operation</th><th>Scope evaluated on</th></tr></thead><tbody><tr><td><code>CREATE TABLE</code></td><td>The <em>new</em> object (checked against <code>TABLE</code>/<code>MAP</code> wildcard)</td></tr><tr><td><code>ALTER TABLE</code></td><td>The <em>existing</em> object</td></tr><tr><td><code>DROP TABLE</code></td><td>The <em>dropped</em> object (its name before the drop)</td></tr><tr><td><code>RENAME TABLE</code></td><td>The <em>original</em> name (before renaming)</td></tr><tr><td><code>TRUNCATE TABLE</code></td><td>The <em>existing</em> object</td></tr></tbody></table></div></div>



<h2 id="edge-cases" class="wp-block-heading">Edge Cases</h2>



<h3 id="ddl-errors-from-cascading-object-dependencies" class="wp-block-heading">DDL errors from cascading object dependencies</h3>



<p class="wp-block-paragraph">Some DDL operations have cascading effects that GoldenGate does not replicate automatically.</p>



<div class="proof-block"><p><strong>Source action:</strong></p><div class="code-block-wrapper"><pre tabindex="0" data-language="sql"><code>DROP TABLE DDLTEST.CUSTOMERS CASCADE CONSTRAINTS;</code></pre></div><p>GoldenGate captures and replicates the <code>DROP TABLE</code>. On the source, any views or constraints that depended on <code>DDLTEST.CUSTOMERS</code> are automatically dropped or invalidated. On the target, dependent objects created outside of the GoldenGate replication remain, as invalid objects.</p><p>For instance, if you create a view named <code>DDLTEST_TGT.CUSTOMERS_V</code> directly on the target (outside of GoldenGate) on <code>DDLTEST_TGT.CUSTOMERS</code>, the <code>DROP TABLE ... CASCADE CONSTRAINTS</code> on the source replicates and applies cleanly:</p><div class="code-block-wrapper"><pre tabindex="0" data-language="log"><code>2026-09-05 20:23:38  INFO    OGG-00482  DDL found, operation [drop table ddltest.customers cascade constraints].
2026-09-05 20:23:38  INFO    OGG-00489  DDL is of mapped scope, after mapping new operation [drop table "DDLTEST_TGT"."CUSTOMERS" cascade constraints].
2026-09-05 20:23:38  INFO    OGG-10451  DDL operation included [INCLUDE MAPPED], optype [DROP], objtype [TABLE], catalog "PDB1", objowner "DDLTEST_TGT", objname "CUSTOMERS".
2026-09-05 20:23:38  INFO    OGG-00484  Executing DDL operation.
2026-09-05 20:23:38  INFO    OGG-00483  DDL operation successful.</code></pre></div><p>But <code>DDLTEST_TGT.CUSTOMERS_V</code> is left behind, now referencing a table that no longer exists:</p><div class="code-block-wrapper"><pre tabindex="0" data-language="sql"><code>SELECT object_name, object_type, status FROM dba_objects WHERE owner = 'DDLTEST_TGT' AND object_name = 'CUSTOMERS_V';

OBJECT_NAME    OBJECT_TYPE  STATUS
-------------- ------------ -------
CUSTOMERS_V    VIEW         INVALID</code></pre></div><p>There is no built-in GoldenGate mechanism for cascading DDL effects. You must either manage dependent objects manually, or filter the <code>DROP</code> and handle cleanup separately.</p></div>



<h2 id="complete-parameter-file-examples" class="wp-block-heading">Complete Parameter File Examples</h2>



<p class="wp-block-paragraph">Here is an example of an extract/replicat pair, and how you could build complex DDL handling.</p>



<div class="proof-block"><div class="code-block-wrapper"><pre tabindex="0" data-language="text"><code>EXTRACT EXT
USERIDALIAS source_cdb DOMAIN OracleGoldenGate
EXTTRAIL pdb1/aa
SOURCECATALOG PDB1

-- Capture structural DDL on mapped objects, exclude storage directives,
-- and also capture DDL on a shared utility schema not in the TABLE list
DDL INCLUDE MAPPED, OBJTYPE 'TABLE', OPTYPE CREATE &amp;
    INCLUDE MAPPED, OBJTYPE 'TABLE', OPTYPE ALTER &amp;
    INCLUDE MAPPED, OBJTYPE 'TABLE', OPTYPE RENAME &amp;
    INCLUDE MAPPED, OBJTYPE 'SEQUENCE', OPTYPE CREATE &amp;
    INCLUDE MAPPED, OBJTYPE 'SEQUENCE', OPTYPE ALTER &amp;
    EXCLUDE MAPPED, INSTR 'NOLOGGING' &amp;
    EXCLUDE MAPPED, INSTR 'COMPRESS' &amp;
    INCLUDE UNMAPPED, OBJNAME SHARED_SCHEMA.*, OBJTYPE 'TABLE', OPTYPE CREATE &amp;
    INCLUDE UNMAPPED, OBJNAME SHARED_SCHEMA.*, OBJTYPE 'TABLE', OPTYPE ALTER

-- Write DDL activity to the report file for auditing
DDLOPTIONS REPORT

TABLE APP_SCHEMA.*;
TABLE SHARED_SCHEMA.*;</code></pre></div></div>



<div class="proof-block"><div class="code-block-wrapper"><pre tabindex="0" data-language="text"><code>REPLICAT REP
USERIDALIAS target_db DOMAIN OracleGoldenGate

-- Apply only CREATE and ALTER TABLE on mapped objects, plus shared-schema DDL;
-- skip sequences, drops, truncates, etc.
DDL INCLUDE MAPPED, OBJTYPE 'TABLE', OPTYPE CREATE &amp;
    INCLUDE MAPPED, OBJTYPE 'TABLE', OPTYPE ALTER &amp;
    INCLUDE MAPPED, OBJNAME SHARED_SCHEMA.*

-- Write DDL activity to report file
DDLOPTIONS REPORT

-- Write discarded/failed DDL to discard file rather than abending
DDLERROR DEFAULT DISCARD

MAP APP_SCHEMA.*, TARGET TARGET_SCHEMA.*;
MAP SHARED_SCHEMA.*, TARGET SHARED_SCHEMA.*;</code></pre></div></div>



<h2 id="summary" class="wp-block-heading">Summary</h2>



<p class="wp-block-paragraph">DDL filtering in GoldenGate is a layered system:</p>



<ul class="wp-block-list">
<li><strong>Scope</strong> (<code>MAPPED</code>/<code>UNMAPPED</code>/<code>OTHER</code>/<code>ALL</code>) restricts DDL replication, based on your <code>TABLE/MAP</code> configuration</li>



<li><strong>Filter keywords</strong> (<code>OBJTYPE</code>, <code>OPTYPE</code>, <code>OBJNAME</code>, <code>INSTR</code>, <code>INSTRWORDS</code>) restricts DDL replication within the scope</li>



<li><strong>Only one <code>DDL</code> parameter is allowed per parameter file</strong>, but it can carry multiple <code>INCLUDE</code>/<code>EXCLUDE</code> clauses continued with <code>&amp;</code>. <strong><code>AND</code> logic</strong> applies within a single clause, while <strong><code>OR</code> logic</strong> applies across clauses. <strong><code>EXCLUDE</code> always wins</strong> over <code>INCLUDE</code> and always needs a corresponding <code>INCLUDE</code></li>



<li><strong><code>DDLOPTIONS</code></strong> controls what happens when DDL is captured or replicated.</li>



<li><strong>Extract filtering is irreversible</strong>. You should filter at the replicat level when multiple replicats need different DDL settings.</li>
</ul>
<p>L’article <a href="https://www.dbi-services.com/blog/ddl-filtering-in-goldengate-extract-and-replicat/">DDL Filtering in GoldenGate Extract and Replicat</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/ddl-filtering-in-goldengate-extract-and-replicat/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 
Lazy Loading (feed)

Served from: www.dbi-services.com @ 2026-10-02 15:53:15 by W3 Total Cache
-->