The Oracle database buffer cache is also referred to as buffer cache.
The buffer cache stores copies of data blocks in memory (the SGA). These copies are stored in what is called buffers by Oracle. Naturally, the size of such a buffer equals the data block size.
The buffer cache is shared among all sessions that are connected to an instance.
A notable distinction between the Shared Pool (which is also shared globally) and the buffer cache is that the shared pool primarily caches metadata while the buffer cache stores data.
The goal is to keep frequently used data blocks in the buffer cache in order to improve I/O by having less physical reads or writes.
The buffers in the cache are organized in linked chains under a hash value calculated for the buffer (DB block).
The linked list for a given hash is protected by a cache buffers chains latch.
Blocks of «cached» objects that are read into the buffer cache as part of a full table are placed at the most recently used end of the LRU list. Thus, they tend to stay longer in the buffer cache. Typically, objects are attributed with cache if they're small and used to look up data.
A dirty block is a block whose content was modified but is not yet flushed back to the datafile by DBWR.
Cache hit vs cache miss
When a database needs data, Oracle checks with the buffer cache if the relevant data block is already copied into the buffer cache.
If this is the case, this is referred to as a cache hit.
If not, this is a cache miss. In this case, a copy from the data block needs to be copied into the buffer cache.
Bypassing the buffer cache with direct path insert and read
Oracle has the ability to write data into a data file without first writing them into the buffer cache. In such an operation, the data is appended behind the high water mark (HWM) of a table.
A direct path insert can be performed with NOLOGGING to reduce the amount of redo that is generated.
Similarly, a direct path read reads data from a data file directly into the PGA, again bypassing the buffer cache.
The values of some interesting (imho) hidden init parameters that are related to the buffer cache can be queried with the following query:
select
par.ksppinm name,
par.ksppdesc description,
v.ksppstvl value
from
x$ksppi par join
x$ksppsv v on par.indx = v.indx
where
-- par.ksppinm like '_db_block%'
par.ksppinm in (
'_db_block_buffers' ,
'_db_block_hash_buckets' ,
'_db_block_hash_latches' ,
'_db_block_lru_latches' ,
'_db_block_max_cr_dba' ,
'_db_block_table_scan_buffer_size',
'_db_blocks_per_hash_latch'
)
order by
par.ksppinm;
TODO
MOS Note 947152.1 says that the buffer cache minum size is 4MB * num_cpus.
When executing cartesian joins, the buffer cache is bypassed and the blocks of the inner table are stored in the PGA, see the plan operation BUFFER SORT.
v$db_cache_advice (which is populated when the db_cache_advice parameter is enabled) shows the simulated miss rates for a range of potential buffer cache sizes (See MOS Note 148511.1)