Oracle RAC 19c Masterclass — Part 18: Cache Fusion Deep Dive: GCS, GC Waits, Hot Blocks & Block Pinging

Part 17 focused on GES, locks, blocking sessions, and deadlocks.

Now we move to the other half of RAC:

GCS — Global Cache Service

If GES is primarily about global locking, GCS is about global access to database blocks.

This is one of the most important areas to master if you want to troubleshoot Oracle RAC at an advanced level.

1. The Core RAC Problem

Imagine a 2-node RAC:

                RAC
                 |
        +--------+--------+
        |                 |
      ORCL1             ORCL2
        |                 |
       SGA               SGA
        |                 |
     Buffer Cache     Buffer Cache

Both instances have their own buffer cache.

But they access the same database.

So what happens when:

ORCL1 needs a block

that is currently cached and modified in:

ORCL2

Oracle doesn’t simply read the block from disk.

Instead, RAC coordinates the block between instances through Cache Fusion.

2. Cache Fusion

The basic idea:

ORCL1 Buffer Cache
       |
       | Request block
       ↓
   Interconnect
       |
       ↓
ORCL2 Buffer Cache

The block can be transferred through the RAC interconnect.

This is called:

Cache Fusion

It is one of the fundamental technologies that makes Oracle RAC work.

3. Why Cache Fusion Matters

Without Cache Fusion, RAC would have to constantly write blocks to disk and reread them.

That would be extremely expensive.

Instead:

Instance 1
     |
     | memory-to-memory
     ↓
RAC Interconnect
     |
     ↓
Instance 2

The block can move directly between buffer caches.

This is much faster than:

Buffer Cache
     ↓
Disk
     ↓
Disk
     ↓
Buffer Cache

But Cache Fusion isn’t free.

Heavy cross-instance block transfers can become a significant source of RAC overhead.

4. Local vs Remote Block Access

Suppose SQL running on ORCL1 needs block 100.

Local

ORCL1
  |
  ↓
Buffer Cache
  |
  ↓
Block 100

Very efficient.

Remote

ORCL1
  |
  ↓
Interconnect
  |
  ↓
ORCL2 Buffer Cache
  |
  ↓
Block 100

Now the request involves:

  • GCS
  • RAC interconnect
  • Remote instance
  • Global resource coordination

This is where GC wait events appear.

5. The Most Important GC Waits

For Oracle RAC performance tuning, memorize these:

gc cr request
gc current request
gc current block busy
gc cr block busy
gc buffer busy

You don’t need to memorize them blindly.

Understand what they mean.

6. gc cr request

Example:

gc cr request

This generally means a session is requesting a consistent-read version of a block through the global cache.

Think:

SQL
 ↓
Needs CR block
 ↓
Block is remote
 ↓
Request through Cache Fusion

High values can indicate significant remote consistent-read activity.

7. gc current request

This is particularly important.

It generally indicates that the session is requesting the current version of a block from another RAC instance.

Conceptually:

ORCL1
  |
  | Need CURRENT block
  ↓
ORCL2
  |
  | Owns current version
  ↓
Transfer through interconnect

Heavy gc current request activity deserves investigation.

8. CR vs CURRENT

This distinction is essential.

CR = Consistent Read

Used when Oracle needs a version of the block consistent with the query’s read-consistency requirements.

CURRENT

The current version of the block.

Simplified:

SELECT
   ↓
CR block

UPDATE
   ↓
CURRENT block

This is simplified, but it’s a useful mental model.

9. gc current block busy

This event deserves particular attention.

It indicates that the requested current block is not immediately available because the remote instance is busy with that block.

Conceptually:

ORCL1
  |
  | Request current block
  ↓
ORCL2
  |
  | Block busy
  ↓
Wait

Possible causes include:

  • Hot blocks
  • Heavy concurrent modification
  • High cross-instance activity
  • Block contention

10. gc cr block busy

Similar concept, but for a consistent-read request.

gc cr block busy

can indicate that the requested CR block isn’t immediately available.

Again, don’t jump directly to:

“The interconnect is slow.”

The interconnect may be perfectly healthy.

The workload itself may be generating excessive block contention.

11. gc buffer busy

This one often appears in RAC investigations.

A session wants to access a buffer, but the buffer is currently busy with another operation.

It can be associated with:

  • Hot blocks
  • Concurrent access
  • Block transfers
  • Cache Fusion activity

You need to investigate the object and SQL rather than treating the event as the root cause.

12. The Most Important Principle

If you see:

gc current request

don’t immediately conclude:

RAC network problem.

Instead ask:

Why does this session need a block
from another instance?

That’s the expert question.

13. Example

Imagine:

ORCL1
Sales application

and:

ORCL2
Batch application

Both update:

ORDERS

The workload becomes:

ORCL1
  |
  | UPDATE ORDERS
  ↓
Block A

ORCL2
  |
  | UPDATE ORDERS
  ↓
Block A

The block keeps moving between instances.

This is sometimes called:

Block pinging

14. Block Pinging

Conceptually:

ORCL1 owns block
       ↓
ORCL2 requests block
       ↓
Block moves
       ↓
ORCL1 requests block
       ↓
Block moves back
       ↓
ORCL2 requests block
       ↓
Block moves again

You get:

ORCL1 ↔ ORCL2

repeatedly.

This can cause significant RAC overhead.

15. The Real Problem Is Often Workload Placement

Suppose:

ORCL1 → SALES
ORCL2 → SALES

and both instances heavily update the same objects.

You may have:

       SALES
         |
   +-----+-----+
   |           |
 ORCL1       ORCL2
   |           |
 UPDATE      UPDATE
   |           |
   +-----+-----+
         |
    Cache Fusion

A better architecture might be:

ORCL1
 SALES

ORCL2
 REPORTING

depending on the application’s requirements and service architecture.

This is why RAC services are a performance tool, not just a connection-routing feature.

16. Cache Fusion and Services

A good RAC design tries to keep workloads that frequently access the same data closer together.

For example:

SERVICE: SALES_APP
Preferred: ORCL1
Available: ORCL2

and:

SERVICE: REPORTING
Preferred: ORCL2
Available: ORCL1

The objective isn’t simply:

“50% of connections on each node.”

The objective is:

Efficient workload placement.

17. Measuring GC Waits

Start with:

SELECT inst_id,
       event,
       total_waits,
       time_waited_micro / 1000000 AS time_waited_sec
FROM gv$system_event
WHERE event LIKE 'gc %'
ORDER BY time_waited_micro DESC;

This gives you an overview of GC waits by instance.

18. Current GC Waits

During an active incident:

SELECT inst_id,
       event,
       COUNT(*) AS sessions
FROM gv$session
WHERE status = 'ACTIVE'
AND event LIKE 'gc %'
GROUP BY inst_id, event
ORDER BY sessions DESC;

Example:

INST  EVENT                    SESSIONS
----  -----------------------  --------
1     gc current request            12
2     gc current block busy          8
2     gc cr request                  15

Now you know which instance is experiencing the most activity.

19. Historical GC Analysis With ASH

If the incident happened earlier:

SELECT instance_number,
       event,
       COUNT(*) AS samples
FROM dba_hist_active_sess_history
WHERE sample_time BETWEEN
      TIMESTAMP '2026-08-08 09:00:00'
  AND TIMESTAMP '2026-08-08 09:30:00'
AND event LIKE 'gc %'
GROUP BY instance_number, event
ORDER BY samples DESC;

This is much more useful than looking only at current statistics.

20. Find the SQL Generating GC Waits

Now drill down:

SELECT sql_id,
       event,
       COUNT(*) AS samples
FROM dba_hist_active_sess_history
WHERE sample_time BETWEEN
      TIMESTAMP '2026-08-08 09:00:00'
  AND TIMESTAMP '2026-08-08 09:30:00'
AND event LIKE 'gc %'
AND sql_id IS NOT NULL
GROUP BY sql_id, event
ORDER BY samples DESC
FETCH FIRST 30 ROWS ONLY;

Example:

SQL_ID       EVENT
-----------  -----------------------
8a12abc      gc current request
8a12abc      gc current block busy

Now we have a SQL candidate.

21. Find the Service

Add service information:

SELECT service_name,
       event,
       COUNT(*) AS samples
FROM dba_hist_active_sess_history
WHERE sample_time BETWEEN
      TIMESTAMP '2026-08-08 09:00:00'
  AND TIMESTAMP '2026-08-08 09:30:00'
AND event LIKE 'gc %'
GROUP BY service_name, event
ORDER BY samples DESC;

Example:

SERVICE       EVENT
------------  -----------------------
SALES_APP     gc current request
BATCH         gc current request

Now you can correlate the RAC wait with the workload.

22. Find the Instance

SELECT instance_number,
       service_name,
       sql_id,
       event,
       COUNT(*) samples
FROM dba_hist_active_sess_history
WHERE sample_time BETWEEN
      TIMESTAMP '2026-08-08 09:00:00'
  AND TIMESTAMP '2026-08-08 09:30:00'
AND event LIKE 'gc %'
GROUP BY instance_number,
         service_name,
         sql_id,
         event
ORDER BY samples DESC;

This gives you:

Instance
+
Service
+
SQL
+
Wait

That’s already a very strong diagnostic picture.

23. Find the Object

ASH contains object-related information for many sampled activities.

Start with:

SELECT current_obj#,
       COUNT(*) samples
FROM dba_hist_active_sess_history
WHERE sample_time BETWEEN
      TIMESTAMP '2026-08-08 09:00:00'
  AND TIMESTAMP '2026-08-08 09:30:00'
AND event LIKE 'gc %'
AND current_obj# > 0
GROUP BY current_obj#
ORDER BY samples DESC;

Then resolve the object:

SELECT owner,
       object_name,
       object_type
FROM dba_objects
WHERE object_id = :object_id;

Now:

GC Wait
   ↓
SQL
   ↓
Object

24. Find Hot Objects

Suppose you discover:

OWNER = SALES
OBJECT = ORDERS
TYPE = TABLE

Then investigate:

  • Which SQL modifies it?
  • Which instances access it?
  • Is it partitioned?
  • Is there a hot index?
  • Are there sequential inserts?
  • Are transactions too large?
  • Is batch processing overlapping with OLTP?

25. Hot Index Blocks

Indexes are particularly interesting.

Consider:

ORDER_ID

with continuously increasing values:

100001
100002
100003
100004
...

A conventional B-tree index can have heavy activity around the right-hand side of the index.

If multiple RAC instances insert concurrently:

ORCL1 → right-most index block
ORCL2 → right-most index block
ORCL1 → right-most index block
ORCL2 → right-most index block

you can create significant contention.

26. But Don’t Automatically Blame the Index

A high index activity doesn’t automatically mean:

“Drop the index.”

The index may be necessary.

You need to determine:

  • Is it actually hot?
  • Is contention caused by inserts?
  • Is the index badly designed?
  • Is workload distribution causing the problem?
  • Would partitioning help?
  • Is the sequence/application design contributing?

27. The Importance of SQL Design

Consider:

UPDATE orders
SET status = 'COMPLETE'
WHERE customer_id = :1;

If thousands of sessions repeatedly update the same small set of rows or blocks, you can create hot-block contention.

Now compare with a workload that distributes updates across many blocks.

Same table.

Different concurrency pattern.

Therefore:

RAC performance depends heavily on data-access patterns, not just hardware.

28. Global Cache Efficiency

A useful concept is the relationship between:

Logical work

and:

Global cache transfers

A system can have powerful hardware but poor RAC performance if too much work crosses instances.

Think:

Local access
    ↓
Cheap

Remote block access
    ↓
More expensive

Repeated remote block pinging
    ↓
Potentially very expensive

29. AWR RAC Sections

When reading a RAC AWR report, pay particular attention to sections related to:

  • Global Cache
  • Cluster statistics
  • Global Cache Transfer Statistics
  • Wait Events
  • Instance Activity
  • SQL by cluster-related metrics

The exact report layout can vary by Oracle version and report generation mode.

30. Cache Fusion Diagnostic Workflow

When GC waits are high:

GC Wait
   ↓
Which instance?
   ↓
Which service?
   ↓
Which SQL?
   ↓
Which object?
   ↓
Which block?
   ↓
Why remote?
   ↓
Why frequently transferred?
   ↓
Can workload be localized?

This is the workflow I recommend.

31. Example Production Incident

Let’s say users report:

“The SALES application becomes slow every day around 18:00.”

AWR shows:

DB Time ↑

Top event:

gc current request

ASH:

INSTANCE 2
SERVICE SALES_APP
SQL_ID 8a12abc

Object:

SALES.ORDERS

Then you discover:

ORCL1 → nightly batch
ORCL2 → sales OLTP

The batch modifies:

ORDERS

while users are simultaneously updating:

ORDERS

Now the picture is:

                ORDERS
                  |
        +---------+---------+
        |                   |
      ORCL1               ORCL2
        |                   |
      BATCH              OLTP
        |                   |
        +--------+----------+
                 |
            Cache Fusion
                 |
           GC waits ↑

32. First Possible Solution

Move the batch workload to the instance where the majority of the relevant data activity occurs, or otherwise redesign service placement.

For example:

ORCL1
  |
  +-- SALES_APP

ORCL2
  |
  +-- BATCH

But don’t blindly move services.

You need to measure the workload first.

33. Second Possible Solution

Reduce the amount of data being modified.

For example, review:

UPDATE orders
SET status = 'X'
WHERE ...

Ask:

  • Can the predicate be improved?
  • Is the correct index available?
  • Is the transaction too large?
  • Can the batch be divided into smaller units?
  • Can the processing window be changed?

34. Third Possible Solution: Partitioning

If the workload naturally separates by:

DATE
REGION
CUSTOMER
BUSINESS_UNIT

partitioning can sometimes reduce contention and improve workload locality.

For example:

ORDERS
 |
 +-- PARTITION_2026_07
 +-- PARTITION_2026_08
 +-- PARTITION_2026_09

The right partitioning strategy depends entirely on access patterns.

Partitioning should never be applied simply because:

“RAC is slow.”

35. RAC Interconnect

Now we need to investigate the network.

Remember:

ORCL1
   |
   | Cache Fusion
   ↓
RAC Interconnect
   |
   ↓
ORCL2

If the interconnect has:

  • Packet loss
  • High latency
  • Errors
  • Saturation
  • NIC problems

Cache Fusion performance can suffer.

36. But Separate Two Problems

This is an important troubleshooting rule:

Problem A
Bad workload
   ↓
Too many block transfers
Problem B
Bad interconnect
   ↓
Block transfers are slow

They can produce similar symptoms.

Your job is to determine which one you actually have.

37. Check RAC Interconnect Configuration

On the database:

SELECT inst_id,
       name,
       ip_address,
       is_public,
       source
FROM gv$cluster_interconnects
ORDER BY inst_id;

This allows you to see the interconnect configuration from the Oracle perspective.

38. Check OS-Level Network Health

On Linux:

ip -s link

or:

ip -s link show <interface>

Look for:

RX errors
TX errors
dropped
overruns

Also:

ethtool <interface>

Check:

Speed
Duplex
Link detected
Errors

The exact commands depend on your OS and network architecture.

39. Check Interface Statistics

For example:

cat /proc/net/dev

Look for abnormal:

errors
dropped

You can also monitor traffic with:

sar -n DEV 1 10

and:

sar -n EDEV 1 10

40. Network Latency Matters

A RAC interconnect isn’t just about bandwidth.

Latency matters enormously.

Conceptually:

Low latency
   ↓
Fast block transfer
   ↓
Good Cache Fusion performance

versus:

High latency
   ↓
Slower block transfer
   ↓
Longer GC waits

But again:

Don’t diagnose the network until you’ve demonstrated that the workload actually requires excessive remote block transfers.

41. A Practical RAC GC Report

Here is a useful starting script:

SET LINESIZE 220
SET PAGESIZE 100

PROMPT =========================================
PROMPT GLOBAL CACHE WAIT EVENTS
PROMPT =========================================

SELECT inst_id,
       event,
       total_waits,
       ROUND(time_waited_micro / 1000000,2) wait_seconds
FROM gv$system_event
WHERE event LIKE 'gc %'
ORDER BY time_waited_micro DESC;

PROMPT =========================================
PROMPT CURRENT GLOBAL CACHE WAITS
PROMPT =========================================

SELECT inst_id,
       event,
       COUNT(*) sessions
FROM gv$session
WHERE status = 'ACTIVE'
AND event LIKE 'gc %'
GROUP BY inst_id, event
ORDER BY sessions DESC;

PROMPT =========================================
PROMPT RAC INTERCONNECTS
PROMPT =========================================

SELECT inst_id,
       name,
       ip_address,
       is_public,
       source
FROM gv$cluster_interconnects
ORDER BY inst_id;

This is a good baseline for your RAC toolkit.

42. Advanced ASH Query

Now let’s combine everything:

SELECT instance_number,
       service_name,
       sql_id,
       event,
       current_obj#,
       COUNT(*) samples
FROM dba_hist_active_sess_history
WHERE sample_time BETWEEN
      TIMESTAMP '2026-08-08 09:00:00'
  AND TIMESTAMP '2026-08-08 09:30:00'
AND event LIKE 'gc %'
GROUP BY instance_number,
         service_name,
         sql_id,
         event,
         current_obj#
ORDER BY samples DESC
FETCH FIRST 50 ROWS ONLY;

This is an extremely useful query during a RAC performance investigation.

It can give you:

Instance
Service
SQL
Wait
Object
Samples

all in one result.

43. Turning the Object ID Into a Name

You can then join to DBA_OBJECTS.

For example:

SELECT ash.instance_number,
       ash.service_name,
       ash.sql_id,
       ash.event,
       o.owner,
       o.object_name,
       o.object_type,
       COUNT(*) samples
FROM dba_hist_active_sess_history ash
LEFT JOIN dba_objects o
       ON o.object_id = ash.current_obj#
WHERE ash.sample_time BETWEEN
      TIMESTAMP '2026-08-08 09:00:00'
  AND TIMESTAMP '2026-08-08 09:30:00'
AND ash.event LIKE 'gc %'
GROUP BY ash.instance_number,
         ash.service_name,
         ash.sql_id,
         ash.event,
         o.owner,
         o.object_name,
         o.object_type
ORDER BY samples DESC
FETCH FIRST 50 ROWS ONLY;

Now your output can become:

INSTANCE SERVICE    SQL_ID     EVENT                 OBJECT
-------- ---------- ---------- --------------------- ----------------
2        SALES_APP  8a12abc    gc current request    SALES.ORDERS
2        SALES_APP  8a12abc    gc current block busy SALES.ORDERS
1        BATCH      4xyz789    gc current request    SALES.ORDERS

That is a very strong indication of a workload-locality problem.

44. The RAC Performance Triangle

When you see GC waits, investigate three things:

                 SQL
                /   \
               /     \
              /       \
          OBJECT ---- INSTANCE
              \       /
               \     /
                SERVICE

More practically:

SQL
 ↓
Object
 ↓
Which instance?
 ↓
Which service?
 ↓
Why is another instance accessing it?

45. The Most Common Mistake

A junior DBA sees:

gc current request

and says:

“The RAC interconnect needs tuning.”

An experienced DBA asks:

“Which SQL is requesting these blocks?”

Then:

“Which object?”

Then:

“Which instance owns the current version?”

Then:

“Why is this workload distributed across instances?”

Only after answering those questions should the interconnect become a primary suspect.

46. RAC Cache Fusion Troubleshooting Checklist

Waits
  • gc cr request
  • gc current request
  • gc cr block busy
  • gc current block busy
  • gc buffer busy
SQL
  • Top SQL by GC samples
  • Execution plan
  • SQL execution frequency
  • Logical reads
  • Physical reads
Objects
  • Hot table
  • Hot index
  • Object access pattern
  • Partitioning
  • Block contention
RAC
  • Instance distribution
  • Service distribution
  • Cache Fusion traffic
  • Workload locality
Network
  • Interconnect
  • Latency
  • Packet drops
  • NIC errors
  • Bandwidth

47. A Senior DBA’s Decision Tree

When you see high GC waits:

                 GC waits high
                      |
                      ↓
              Which GC event?
                      |
          +-----------+-----------+
          |                       |
        CR                       CURRENT
          |                       |
          ↓                       ↓
   Read workload           Modification workload
          |                       |
          +-----------+-----------+
                      |
                      ↓
                  Which SQL?
                      |
                      ↓
                  Which object?
                      |
                      ↓
              Which instance?
                      |
                      ↓
               Which service?
                      |
                      ↓
             Why remote access?
                      |
             +--------+--------+
             |                 |
        Workload issue    Network issue
             |                 |
             ↓                 ↓
       Tune workload      Tune infrastructure

This is the approach I want you to internalize.

48. Part 18 Summary

We’ve now covered the other major side of RAC internals:

Architecture
  • GCS
  • Cache Fusion
  • CR vs CURRENT blocks
  • Local vs remote blocks
Wait events
  • gc cr request
  • gc current request
  • gc cr block busy
  • gc current block busy
  • gc buffer busy
Troubleshooting
  • ASH analysis
  • SQL identification
  • Object identification
  • Service analysis
  • Instance analysis
  • Hot blocks
  • Block pinging
Infrastructure
  • RAC interconnect
  • Network latency
  • NIC errors
  • Network drops
Architecture optimization
  • Service placement
  • Workload locality
  • Batch vs OLTP separation
  • Partitioning considerations

The Key Lesson

Remember this:

High GC waits
      ≠
Bad RAC
      ≠
Bad Network

Instead:

High GC waits
      ↓
Find SQL
      ↓
Find Object
      ↓
Find Instance
      ↓
Find Service
      ↓
Understand Workload
      ↓
Determine Why Blocks Move
      ↓
Then decide what to fix

That’s the difference between RAC monitoring and RAC performance engineering.

Bookmark the permalink.
Loading Facebook Comments ...

Leave a Reply