06 Buffer Cache
06 Buffer Cache
#.2
In This Section
latch: cache buffers chains
Buffer Cache
Locks
Network
IO
#.4
Oracle Memory Structures
SGA
Log Library Buffer
Buffer Cache Cache
Buffer Cache
Log Buffer
DBWR
LGWR
User1
User2
User3
Query
Select ename from emp where empno = 12;
0. Parse statement
2. Find object information in data dictionary
3. Calculate execution plan
4. If full table scan
Look at all blocks of table
5. If index find root of index and follow to key
6. Data Dictionary will have info about table or index block
File #
Block #
7. Once you know the block DBA (file# + block#) …
#.7
Is Block in cache?
Now you have a file# and block#
How do you know if a block is
cached?
Shadow
Process
?
Do you search all the blocks?
Could be 1000s of blocks to search.
Buffer caches are in the multi
Gig
#.8
Buffer Cache
Find a block by:
1) Hash of What is a hash value
What are Buckets
Data file #
What is the linked list?
Block#
2) Result = Bucket #
3) Search linked list for that
bucket #
#.9
Concepts
To understand contention on the buffer cache,
need to understand :
3. Linked Lists
4. Hashing
5. Buckets
#.10
Hashing Function
Simple hash could be a Mod function
1 mod 4 = 1
2 mod 4 = 2
3 mod 4 = 3
4 mod 4 = 0
5 mod 4 = 1
6 mod 4 = 2
7 mod 4 = 3
8 mod 4 = 0
Cache
ADDR 03C38F60 03C39000 03C39478
NXT_HASH 03C39000 03C39478
PRV_HASH 03C38F60 03C39000
#.16
NXT_HASH
x$bh PRV_HASH
ADDR
DBARFIL
DBABLK
OBJ DBARFIL
HLADDR
NXT_HASH DBABLK
PRV_HASH OBJ
To Find a Block
#.17
Shadow
Process
2 3 4 5
latches Hash
Sessions Buckets Block
Headers Data
Blocks
s5
s3
s2
s1
Examples
1. Look up Table
S1 S2 S3 S4
t1 t2
Index_t2
2. Nested Loops
Select t1.val, t2.val
from t1, t2
where t1.c1 = {value}
and t2.id = t1.id;
#.20
CBC Solutions
Find SQL ( Why is application hitting the block so hard? )
Nested loops, possibly
Hash Partition
Uses Hash Join
Hash clusters
Look up tables (“select language from lang_table where ...”)
Change application
Use plsql function
Spread data out to reduce contention
Select from dual
Possibly use x$dual
select
count(*),
sql_id,
nvl(o.object_name,ash.current_obj#) objn,
substr(o.object_type,0,10) otype,
CURRENT_FILE# fn,
SQL Statement:
CURRENT_BLOCK# blockn
from v$active_session_history ash
Success
, all_objects o
where event like 'latch: cache buffers chains'
and o.object_id (+)= ash.CURRENT_OBJ# Extra: Hot block
group by sql_id, current_obj#, current_file#,
current_block#, o.object_name,o.object_type
order by count(*)
/
CBC: OEM
#.25
CBC: ADDM
Problem
SQL Statement
Solution?
#.26
CBC – Further Investigation
select * from v$event_name
where name = 'latch: cache buffers chains'
EVENT# NAME
---------- ----------------------------
58 latch: cache buffers chains
s1 s2
Update Select
#.32
CBC: Consistent Read Blocks
Hash Block
latches Buckets Headers
s5
Cache Buffer Chain
s4
s3
Max length :
s2 _db_block_max_cr_dba
10g = 6
s1
CBC : Solution
Fine the SQL causing the problem
Change Application Logic
select
Eliminate hot spots ash.sql_id,
count(*),
Look up tables
sql_text
Uses pl/sql functions from v$active_session_history ash,
Minimize data per block v$sqlstats sql
Possibly using x$dual instead of dual where
Index Nested loops event='latch: cache buffers chains'
and sql.sql_id(+)=ash.sql_id
Hash join group by ash.sql_id, sql_text;
Hash partition index
Hah Cluster
Updates, inserts , select for update on blocks while reading those
blocks
Cause multiple copies
#.35
= entry in x$bh
#.41
X$bh
Describes Buffer Headers
SQL> desc x$bh
Name Type
---------------------- ---------
ADDR RAW(4)
DBARFIL NUMBER
DBABLK NUMBER
OBJ NUMBER
HLADDR
HLADDR Cache RAW(4)
RAW(4)
NXT_HASH
NXT_HASH buffer RAW(4)
RAW(4)
PRV_HASH
PRV_HASH chains RAW(4)
RAW(4)
NXT_REPL RAW(4)
LRU
PRV_REPL RAW(4)
#.42
LRU Chain
ADDR 03C38F60 03C39000 03C39478
NXT_HASH 03C39000 03C38F60
PRV_HASH 03C38F60 03C39000
“Hot” “Cold”
LRU = Least Recently Used
MRU = Most Recently Used
Hot End
Mid-Point
Find Free
Insertion
Block
Mid-Point
Insertion
LRU Latch 1
Set 2
LRU Latch 2
_db_block_lru_latches = 8
10gR2 with cpu_count = 2
X$KCBWDS – set descriptor
#.52
Working Sets
select
ds.set_id,
ds.blk_size ,
SET_ID BLK_SIZE BUFFERS NAME
bp.BUFFERS, ---------- ---------- -------- -------
nvl(bp.name.’unused’) 16 32768
15 32768
from 14 16384
x$kcbwds ds, 13 16384
12 8192
v$buffer_pool bp
11 8192
where 10 4096
9 4096
ds.set_id >= bp.lo_setid (+) and
8 2048
ds.set_id <= bp.hi_setid (+) 7 2048
/ 6 8192 4972 DEFAULT
5 8192 4972 DEFAULT
4 8192
3 8192
2 8192
1 8192
#.53
Test Case
8 Sessions
reading separate tables
Tables were too big to hold in cache
cache option set on each table
from v$active_session_history
where event='latch free'
P2 COUNT(*)
group by p2 ---------- ----------
127 3556
Group “other” is
very small
compared to I/O
wait time – not a
problem
#.57
3
User2
User1
#.59
BBW Solution Paths
There is a hot block,
eliminate the hot block
1. Find Block type Block Types:
Resolve if possible Undo Header
use AUM (or add more RBS)
2. Tune SQL Undo Block – hot spot in UNDO
Find SQL Data
How often is it called index – hot spot, partition
table – free lists, ASSM, partition
By how many Users
Segment header – free lists
3. Eliminate Hot Block table datablock -> freelists
Find Object Freelist blocks – free lists groups
Find Block Type File Header Block – look at extent
allocation
#.60
BBW: Statspack
Top 5 Timed Events Avg %Total
~~~~~~~~~~~~~~~~~~ wait Call
Event Waits Time(s) (ms) Time
------------------------ ----- ------- ----- ------
buffer busy waits 5,832 263 45 28.2
log file parallel write 248 125 505 13.4
read Class
by other session Waits Wait
902 Time103 114
(s) Avg Time 11.1
(ms)
db file parallel write 2,166 94 43 10.1
------------------ ----- ------------- -------------
db file sequential read 653 81 125 8.7
file header block 264 203 769
data block 6,070 162 27
undo header 355 0 1
segment header 44 0 1
fails to find Object
#.61
BBW: ASH
Finds
Object
Block Type
SQL Statement
CNT OBJ OTYPE SQL_ID BLOCK_TYPE TBS
--- --------------- ----- ------------- ----------------- --------
2 BBW_INDEX_VAL_I INDEX 635xhydd6fzgg segment header SYSTEM
2 0 635xhydd6fzgg usn 5 header UNDOTBS1
3 0 1hsb81ypyrfs5 file header block UNDOTBS1
32 BBW_INDEX_VAL_I INDEX 1hsb81ypyrfs5 data block SYSTEM
33 BBW_INDEX_VAL_I INDEX 6avm49ys4k7t6 data block SYSTEM
34 BBW_INDEX_VAL_I INDEX 5wqps1quuxqr4 data block SYSTEM
BBW: OEM #.62
Solutions #.63
#.64
BBW Block Types
select rownum
n,ws.class
from v$waitstat;
select * from v$event_name N CLASS
where name = 'buffer busy waits'
--- ------------------
1 data block
NAME P1 P2 P3
2 sort block
----------------- ----- ------ ----- 3 save undo block
buffer busy waits file# block# class# 4 segment header
5 save undo header
6 free list
7 extent map
Note: Before 10g, P3 was BBW type
8 1st level bmb
If P3 in 100,110,120,130 then read 9 2nd level bmb
10 3rd level bmb
Now “read by other session” 11 bitmap block
12 bitmap index block
Else Write, P3 in 200,210,220,230, 13 file header block
231 14 unused
15 system undo header
16 system undo block
#.65
Joining ASH with v$waitstat
select
o.object_name obj,
o.object_type otype,
ash.SQL_ID,
w.class
from v$active_session_history ash,
( select rownum class#, class from v$waitstat ) w,
all_objects o
where event='buffer busy waits'
and w.class#(+)=ash.p3
and o.object_id (+)= ash.CURRENT_OBJ#
Order by sample_time;
OBJ OTYPE SQL_ID CLASS
------ ------ ------------- ------------------
TOTO1 TABLE 8gz51m9hg5yuf data block
TOTO1 TABLE 8gz51m9hg5yuf data block
TOTO1 TABLE 8gz51m9hg5yuf segment header
TOTO1 TABLE 8gz51m9hg5yuf data block
#.66
Alternative to ASH: AWR
select
to_char(BEGIN_INTERVAL_TIME,'DD-MON HH:MI'),
o.name,
s.BUFFER_BUSY_WAITS_DELTA
from dba_hist_seg_stat s,
dba_hist_snapshot sn,
obj$ o
where
BUFFER_BUSY_WAITS_DELTA > 100
and sn.snap_id = s.snap_id
and o.obj# = s.obj#;
TO_CHAR(BEGI NAME BUFFER_BUSY_WAITS_DELTA
------------ ----- ----------------------
11-JAN 10:21 TOTO1 58447
#.67
4 Sessions running
Insert into toto
values (null, ‘a’);
Commit;
S1 S2 S3 S4
OBJN OTYPE FILEN BLOCKN SQL_ID BLOCK_TYPE
----------- ------ ------ ------ ------------- ------------
54962 TOTO1 TABLE 16 45012 8gz51m9hg5yuf data block
54962 TOTO1 TABLE 16 161 8gz51m9hg5yuf segment header
#.69
S1 S2 S3 S4
4 Sessions running
Insert into toto values (null, ‘a’);
Commit;
#.70
Solution 2: ASSM
Multiple Bitmap Blocks Track Free Space
Unformatted
Up to 25% Free
Up to 50% Free
Up to 75% Free
Full
Solution 2: ASSM
Header
BBW: ASSM
Consider using Freelists instead of ASSM
Normally waits on ASSM blocks should be
too small to warrant using Freelists
ASSM is easier, automatically managed
Session 1
Increasing index
key creates a hot
Session 2 spot on the leading
index leaf
Session 3
#.75
Solution is make initial and next extent larger in Temp Table Space
#.82
Sessio
DBWR
n
#.84
Buffer Exterminate
Buffer cache dynamically resized