DBA Blogs
New JOIN TO ONE clause in 26.2 SELECT
I've just published a short video on the new JOIN TO ONE clause in SELECT statements in Oracle 26ai 26.2
This clause allows you to let the database automatically determine JOIN columns based on Primary Key and Foreign Key relationships configured in the database. JOIN TO ONE defaults to doing a LEFT OUTER JOIN so I also demonstrate how to use it for INNER JOINs
Tracing a Power BI DirectQuery Refresh in Oracle
In today's video I have demonstrated how Power BI can use DirectQuery to query an Oracle database and refresh reports without actually storing the data in the Power BI file (as would be done if "Import" was used instead of DirectQuery).
I have used SQL Tracing in the Database Instance to identify the SQL statement that Power BI executes
For the first visual in Power BI which shows total salary by Department, the Power BI module and SQL statement are identified as :
MODULE NAME:(msmdsrv.exe)
CLIENT DRIVER:(ODPM.NET : 23.6.0.0.0)
sqlid='c8a9qd2dzks8h'
SELECT * FROM (
SELECT
*
FROM
(
SELECT
"t1"."DEPARTMENT_NAME" "c6", SUM ( "t4"."SALARY" )
"a0"
FROM
((
select "$Table"."EMPLOYEE_ID" as "EMPLOYEE_ID",
"$Table"."FIRST_NAME" as "FIRST_NAME",
"$Table"."LAST_NAME" as "LAST_NAME",
"$Table"."EMAIL" as "EMAIL",
"$Table"."PHONE_NUMBER" as "PHONE_NUMBER",
"$Table"."HIRE_DATE" as "HIRE_DATE",
"$Table"."JOB_ID" as "JOB_ID",
"$Table"."SALARY" as "SALARY",
"$Table"."COMMISSION_PCT" as "COMMISSION_PCT",
"$Table"."MANAGER_ID" as "MANAGER_ID",
"$Table"."DEPARTMENT_ID" as "DEPARTMENT_ID"
from "HR"."EMPLOYEES" "$Table"
) "t4"
LEFT OUTER JOIN
(
select "$Table"."DEPARTMENT_ID" as "DEPARTMENT_ID",
"$Table"."DEPARTMENT_NAME" as "DEPARTMENT_NAME",
"$Table"."MANAGER_ID" as "MANAGER_ID",
"$Table"."LOCATION_ID" as "LOCATION_ID"
from "HR"."DEPARTMENTS" "$Table"
) "t1" on
(
"t4"."DEPARTMENT_ID" = "t1"."DEPARTMENT_ID"
)
)
GROUP BY "t1"."DEPARTMENT_NAME"
)
"MainTable"
WHERE
(
NOT(
(
"a0" IS NULL
)
)
)
ORDER BY "a0"
DESC
,"c6"
ASC
) WHERE ROWNUM (lessthan) 1001
MODULE NAME:(msmdsrv.exe)
CLIENT DRIVER:(ODPM.NET : 23.6.0.0.0)
sqlid='dh7nbfqsy942q'
SELECT
"t1"."DEPARTMENT_NAME" "c6",
COUNT("t4"."EMPLOYEE_ID")
"a0"
FROM
((
select "$Table"."EMPLOYEE_ID" as "EMPLOYEE_ID",
"$Table"."FIRST_NAME" as "FIRST_NAME",
"$Table"."LAST_NAME" as "LAST_NAME",
"$Table"."EMAIL" as "EMAIL",
"$Table"."PHONE_NUMBER" as "PHONE_NUMBER",
"$Table"."HIRE_DATE" as "HIRE_DATE",
"$Table"."JOB_ID" as "JOB_ID",
"$Table"."SALARY" as "SALARY",
"$Table"."COMMISSION_PCT" as "COMMISSION_PCT",
"$Table"."MANAGER_ID" as "MANAGER_ID",
"$Table"."DEPARTMENT_ID" as "DEPARTMENT_ID"
from "HR"."EMPLOYEES" "$Table"
) "t4"
LEFT OUTER JOIN
(
select "$Table"."DEPARTMENT_ID" as "DEPARTMENT_ID",
"$Table"."DEPARTMENT_NAME" as "DEPARTMENT_NAME",
"$Table"."MANAGER_ID" as "MANAGER_ID",
"$Table"."LOCATION_ID" as "LOCATION_ID"
from "HR"."DEPARTMENTS" "$Table"
) "t1" on
(
"t4"."DEPARTMENT_ID" = "t1"."DEPARTMENT_ID"
)
)
GROUP BY "t1"."DEPARTMENT_NAME"
Thus, every refresh runs a number of queries -- some to synchronise the schema from Oracle to Power BI and others to refresh the numbers to present in the Visuals.
This proves that the actual load of computing the GROUP BY and aggregations is in the *database instance* (because that is where the data actually resides) and not in the Power BI file (because no data is copied into the Power BI file)Dealing with JSON serialization and how to convert JSON object strings back and forth
A simple reminder about how JSON PL/SQL methods deal with JSON values, it easy to get confused when you mix up JSON objects and their serialized counterparts, especially if some if these parts are coming from JSON SQL functions and you need to combine them with other parts generated by PL/SQL.
The code below should clarify the difference between a "real" JSON value and its textual representation, especially when you are assembling a JSON object with values containing other JSON objects or their serialized representation.
When you PUT a serialized JSON string into a new JSON, the method escapes all the special characters that otherwise would break the syntax (lines 10-16).
In order to reconstruct a valid JSON string, something that you can PARSE as JSON, you need to retrieve the value with GET_STRING or GET_CLOB if it is large (lines 18-20).
If you need to include a serialized JSON object into a new JSON object thus avoiding the automatic escaping, then you need to convert the serialized JSON string into a proper JSON object and then PUT it inside the new object (lines 26-29).
declare
c varchar2(255) := '{"key": 1, "value": "X"}';
d varchar2(255);
j json_object_t;
j1 json_object_t;
j2 json_object_t;
begin
if c is json then
dbms_output.put_line('c is a string containing a valid JSON');
j := json_object_t.parse(c);
j1 := new json_object_t;
j1.put('document', c);
dbms_output.put_line('c is now escaped and becomes a string literal value');
dbms_output.put_line(j1.to_string());
dbms_output.new_line;
d := j1.get_string('document');
dbms_output.put_line('c is converted back into the original JSON object string');
dbms_output.put_line(d);
dbms_output.new_line;
dbms_output.new_line;
j2 := new json_object_t;
j2.put('document', j);
dbms_output.put_line('c is still a json object value, now embedded in a new JSON object');
dbms_output.put_line(j2.to_string());
else
dbms_output.put_line('NOT JSON');
end if;
end;
/Watch out for NULL values because GET_STRING and GET_CLOB show two different behaviors in older releases of Oracle 19c.
Bug using SQL_MACRO (TABLE) with table parameter
Oracle RAC Concepts (gestion des instances / hang / reconfiguration)
ORA-04031 when explain plan of a very big and complex query
Does TLS 1.3 supported in the current OEM 24ai version
DBMS_SCHEDULER commit_semantics => 'ABSORB_ERRORS' How to Handle Exceptions
i am facing issue in fra as space is getting filled and not deleting flashback log filling the mount point on the server
Database Design/Data Modelling
CREATE UNIQUE INDEX <NAME> ON <TABLE> (ID DESC);
Smart Select
View vs function SQL_MACRO
Tracking Deletes on a table
Coordinated Replicats: The Best Way to Do Initial Load
Coordinated vs parallel replicat for Oracle GoldenGate initial loads: why coordinated wins and scales a single table.
The post Coordinated Replicats: The Best Way to Do Initial Load appeared first on DBASolved.
Using INCLUDE Files and Macros in OCI GoldenGate
OCI GoldenGate drops the dirprm and dirmac directories, but INCLUDE files and macros still work. Here is how to create and reference them in the cloud console.
The post Using INCLUDE Files and Macros in OCI GoldenGate appeared first on DBASolved.
Demystifying Netfilter and nftables: How Linux Packet Filtering Really Works
Understanding how Linux handles network packets at the kernel level can feel overwhelming — until you see how the pieces fit together. Netfilter provides the foundation, while nftables gives us a modern, flexible way to define firewall rules, NAT, and packet mangling.
Whether you’re debugging connectivity issues, writing security tools, or optimizing performance, knowing these internals helps you work more effectively with Linux networking.
Netfilter: The Kernel’s Packet Processing FrameworkNetfilter is the Linux kernel’s packet filtering and mangling infrastructure. It defines well-known hook points where packets can be inspected and modified as they flow through the system:
- PREROUTING — Right after a packet arrives, before routing decisions
- INPUT — Packets destined for the local system
- FORWARD — Packets being routed through the host
- OUTPUT — Locally generated packets
- POSTROUTING — After routing, before leaving the host
Chains attached to these hooks let you enforce security policies, perform NAT, or influence routing.
nftables: The Modern Replacement for iptablesnftables brings a cleaner, more consistent syntax and better performance compared to the older iptables framework. It organizes configuration into tables, chains, rules, sets, and expressions.
Core nftables Building Blocks TablesContainers that group related chains, sets, and rules. Common families include ip (IPv4), ip6 (IPv6), and inet (both).
nft add table ip myfirewall
Chains
Sequences of rules. Base chains attach directly to Netfilter hooks and define behavior (filter, nat, route).
nft add chain ip myfirewall input { type filter hook input priority 0 \; }
Rules
Define matching conditions and actions (accept, drop, jump, etc.).
nft add rule ip myfirewall input tcp dport 22 accept
Sets
Efficient collections for matching (IP addresses, ports, etc.).
nft add set ip myfirewall trusted_ips { type ipv4_addr \; }
nft add element ip myfirewall trusted_ips { 192.168.1.10, 10.0.0.5 }
Practical Example: Simple Firewall
Here’s how to create a basic firewall that allows SSH from trusted IPs and drops everything else:
nft add table ip myfirewall
nft add chain ip myfirewall input { type filter hook input priority 0 \; }
nft add set ip myfirewall trusted_ips { type ipv4_addr \; }
nft add element ip myfirewall trusted_ips { 192.168.1.1, 192.168.1.2 }
nft add rule ip myfirewall input ip saddr @trusted_ips accept
nft add rule ip myfirewall input drop
Behind the Scenes: User Space to Kernel
Tools like nft use libmnl and libnftnl to communicate with the kernel via Netlink. This allows atomic batch operations — multiple changes applied together or not at all — ensuring consistent firewall state.
Best Practices for Production- Use named sets for frequently updated lists (trusted IPs, blocked addresses)
- Keep base chains simple and explicit with a final drop rule
- Leverage priorities to control execution order
- Batch operations when making multiple changes
- Monitor and log dropped packets for visibility
Netfilter and nftables form a powerful, unified framework for packet processing in Linux. Understanding how tables, chains, rules, and sets work together helps you build more effective firewalls, troubleshoot network issues faster, and appreciate the elegance of the modern Linux networking stack.
Whether you’re securing servers, implementing complex NAT rules, or exploring kernel internals, nftables gives you the tools to control traffic with precision and clarity.
Mastering High Availability Connection Strings in Oracle: What Really Happens Behind the Scenes
Most Oracle DBAs and developers copy-paste the same “recommended” TNS connection string for RAC and Data Guard without fully understanding how each parameter affects real-world behavior. That changes today.
This guide breaks down the critical parameters in a typical HA connect descriptor, shows measurable timing impacts, and gives clear guidance on when to tune what — so your applications stay resilient during switchovers, failovers, and maintenance.
The Standard HA Connect StringHere’s the common pattern you’ll see in MAA documentation:
(DESCRIPTION =
(CONNECT_TIMEOUT=90)(RETRY_COUNT=100)(RETRY_DELAY=3)
(TRANSPORT_CONNECT_TIMEOUT=1000ms)
(ADDRESS_LIST = (LOAD_BALANCE=on) (ADDRESS = ...))
(ADDRESS_LIST = (LOAD_BALANCE=on) (ADDRESS = ...))
(CONNECT_DATA = (SERVICE_NAME = my_service))
)
Let’s explore what each setting actually does and how changing it impacts connection behavior.
1. FAILOVER = ON (Default)Controls whether the client tries alternate addresses when one fails. Keep this ON unless you have a very specific reason to disable it. Turning it OFF makes connections order-dependent and can prevent reaching an available site during role transitions.
2. LOAD_BALANCE = ONRandomizes the starting address in an ADDRESS_LIST. This prevents one SCAN IP from being hammered and helps spread load. Strongly recommended when you have multiple addresses, especially during partial outages or maintenance.
3. RETRY_COUNT & RETRY_DELAYRETRY_COUNT defines how many additional rounds the client makes through the address list. RETRY_DELAY adds a pause between rounds so the service has time to become available after a switchover or failover.
Tip: Use RETRY_DELAY=3 (seconds) as a good starting point. Tight loops (RETRY_DELAY=0) create unnecessary load and should be avoided in production.
4. TRANSPORT_CONNECT_TIMEOUTThis is crucial when an IP or port is unreachable. It caps how long the client waits for a TCP connect before moving to the next address. Set it low enough to fail fast during outages, but high enough to handle normal network jitter (1000ms is a common balanced value).
5. CONNECT_TIMEOUTLimits the total time for a single connection attempt, including server process creation. Set this higher than TRANSPORT_CONNECT_TIMEOUT (commonly 60–90 seconds) to allow normal connects under load while protecting against hanging attempts.
Practical Recommendations- For frequent role changes (Fast-Start Failover): Use LOAD_BALANCE=on and moderate RETRY_COUNT
- For stable primary with rare switchovers: Prefer LOAD_BALANCE=off with clear site ordering
- Always set TRANSPORT_CONNECT_TIMEOUT explicitly — don’t rely on defaults
- Align your application connection pool timeouts with the worst-case client wait time
- Use the latest Oracle client (26ai recommended) for millisecond precision support
Don’t treat the HA connection string as magic copy-paste code. Understand what each parameter controls and tune it to your environment’s failover patterns and network characteristics. Small changes here can dramatically improve application resilience during planned maintenance and unplanned outages.
Test your connection strings under simulated failure scenarios (service down, network blocked) and measure real connect times. The better you understand your client behavior, the more predictable and reliable your high-availability applications will be.
Oracle AI Database 26ai Supercharges Active Data Guard: Faster Failovers, Stronger Multicloud Resilience
Mission-critical applications demand minimal downtime and lightning-fast recovery. With Oracle AI Database 26ai, Oracle has dramatically improved Data Guard and Active Data Guard role transitions, making high-availability architectures faster and more reliable than ever.
These enhancements push Oracle Maximum Availability Architecture (MAA) Platinum tier capabilities across Oracle’s multicloud ecosystem, giving organizations consistent, enterprise-grade resilience no matter where they run.
Game-Changing Performance ImprovementsOracle’s testing shows impressive gains:
- Up to **5x faster failovers** — often completing in under 30 seconds
- Up to **3.4x faster switchovers**
- Consistent results across both small and large workloads
- No changes required to your applications
These optimizations span database recovery, checkpoint processing, service management, and multitenant operations — delivering real reductions in Recovery Time Objectives (RTO).
MAA Platinum Tier Now Available Across MulticloudOrganizations using Oracle Database@Azure, Oracle Database@AWS, or Oracle Database@Google Cloud can now standardize on the same Platinum MAA architecture:
- Local HA with RTO under 10 seconds
- Regional DR with RTO under 30 seconds
- Zero or near-zero Recovery Point Objective (RPO)
This consistency lets teams apply the same proven best practices, operational procedures, and resiliency strategies across all their multicloud deployments.
Why This Matters for Your Business- Less Downtime — Faster planned maintenance and unplanned recovery
- Better User Experience — Minimal disruption during role transitions
- Simplified Operations — Standardize high-availability practices across environments
- Future-Proof Architecture — Built for the most demanding mission-critical workloads
Existing Exadata and Exadata Database Service customers running Active Data Guard will see immediate benefits from moving to Oracle AI Database 26ai. The performance gains make Platinum MAA tier objectives much more achievable without major architectural overhauls.
Next StepsIf you’re running mission-critical databases, now is the perfect time to evaluate Oracle AI Database 26ai. The combination of Exadata performance, Active Data Guard, and these accelerated role transitions creates one of the strongest availability platforms available today.
Explore the updated MAA reference architectures and multicloud certification matrix to see how you can strengthen your high-availability strategy across Oracle Cloud and major hyperscalers.
Connect to Oracle Like It’s Kafka: OKafka Authentication Made Simple
One of the nicest things about OKafka is how familiar it feels if you’ve used Kafka before. You configure connections with Properties objects, just like kafka-clients. The big difference? You’re talking directly to Oracle Database Transactional Event Queues instead of a separate broker.
Here’s how to set up authentication cleanly for development and production.
Two Main Authentication Paths 1. PLAINTEXT (Great for Local Dev)Simple username/password setup using an ojdbc.properties file:
Properties props = new Properties();
props.put("security.protocol", "PLAINTEXT");
props.put("bootstrap.servers", "your-host:port");
props.put("oracle.service.name", "your_service_name");
props.put("oracle.net.tns_admin", "/path/to/config/dir");
Your ojdbc.properties file should contain:
user=testuser
password=YourStrongPassword123
2. SSL / mTLS (Production Ready)
Use Oracle Wallet for secure connections. Point to your wallet directory and specify the TNS alias:
props.put("security.protocol", "SSL");
props.put("oracle.net.tns_admin", "/path/to/wallet");
props.put("tns.alias", "your_tns_alias");
Full Working Example
Here’s a complete snippet to create an AdminClient and make a topic:
try (Admin admin = AdminClient.create(props)) {
NewTopic topic = new NewTopic("MY_EVENTS", 5, (short) 0);
admin.createTopics(Collections.singletonList(topic)).all().get();
System.out.println("Topic created successfully");
}
Pro Tips for Smooth Sailing
- Always use uppercase topic names with OKafka
- Store wallet files securely and never commit them to version control
- Test with Oracle Database Free + Testcontainers for quick iterations
- Move to mTLS early in your development cycle
OKafka makes connecting to Oracle feel just like connecting to any other Kafka cluster — but you get all the power, security, and transactional guarantees of the database built right in.
No extra infrastructure. No separate cluster to manage. Just reliable event streaming where your data already lives.


