Sizing the SGA in Oracle 9i and above
A rather nice question was asked on OTN today. It’s repeated here for easier reading
how to change the sga size and how the effects take place in 9i and 10g DB
An early follow up remarked on various initialisation parameters, though not in my view perhaps in an entirely clear way.
In 9i you can dynamically change db_cache_size, and shared_pool_size and large_pool_size, provided you don’t use db_block_buffers (which disables the feature) and you stay below sga_max_size.
However sga_max_size is not a dynamic parameter so you would need to issue
alter system set sga_max_size=<something ridiculously big> scope=spfile
and bounce the database.On 10g you don’t need to set db_cache_size etc anymore, but you need to set sga_max_size and sga_target_size
As this is a common type of question I thought a brief summary might be useful here, together with a little discussion of the history of the SGA from Oracle 7/8/8i through to 11g Release 1, if you are coming across this post in the future via a web search engine - after Oracle Database Release 12 has been made available you may find the discussion has changed again since the area of memory management in Oracle seems to be under constant evolution.
Lets start with a definition - this one is drawn straight from the 9i documentation
The System Global Area (SGA) is a shared memory region that contains data and control information for one Oracle instance. Oracle allocates the SGA when an instance starts and deallocates it when the instance shuts down. Each instance has its own SGA. Users currently connected to an Oracle server share the data in the SGA. [text ommitted]
The information stored in the SGA is divided into several types of memory structures, including the database buffers, redo log buffer, and the shared pool
The important points to note are that the SGA is instance specific, shared across users and that it includes both data and control information. Notably it includes the instances cache of database blocks (buffer cache), the shared pool (which in turn contains shared SQL parse and execution trees and so on ). Sizing the SGA appropriately therefore is a basic system wide tuning activity since the memory you allocate here will directly affect the caches available for both data and program execution information.
Oracle’s instance wide configuration is largely controlled by an initialisation parameter file - either a text file or a binary server side file (from 9i) called an spfile. This file contains as the name I have chosen here rather indicates initialisation parameters and their values for the instance. Any unlisted values are either calculated from parameters that are listed or else take their default values. Oracle reads the file at initialisation and sets up the instance accordingly.
First the history. In older versions of Oracle the size of both the SGA and it’s constituent parts was fixed. Sizing the SGA was a simple matter of setting the relevant initialisation parameters. These were:
-
db_block_buffers - the number of data blocks that could be cached in memory by the instance
-
shared_pool_size - the size of the shared pool
-
large_pool_size - the size of the large pool (not in 7)
-
log_buffer - the size of the redo log buffer
All of these parameters are fixed and the SGA could therefore only be changed by an instance restart.
This picture changed rather dramatically with the release of Oracle 9i, both the number and nature of the various SGA components changed significantly with this release assuming that you chose to use the new features. Firstly 9i allowed multiple block sizes within a single database, and therefore multiple database buffer caches were introduced. These were all controlled by the initialisation parameters
- db_cache_size
- db_nK_cache_size
Where the first listed parameter controlled the size of the default cache and the nK parameters controlled the size of the caches for non standard database blocks. These parameters were measured in size, rather than blocks. In addition Oracle introduced a new fixed parameter SGA_MAX_SIZE which specified the maximum amount of shared memory that Oracle could use for the SGA in the instance, making this change allowed Oracle to make (some of) the existing parameters dynamic, so you could dynamically change the composition of the SGA always providing that in total the amount of memory requested did not exceed the SGA_MAX_SIZE limit.
In Oracle 10g things progressed still further. With this release Oracle added yet another new parameter SGA_TARGET and if this was set then the meaning of the 9i parameters changed, specifically if SGA_TARGET was set then the 9i parameters specified a minimum amount of memory to use for that component. In this release the idea of Oracle deciding memory allocations was introduced, the DBA told Oracle how much memory was available for the SGA as a whole (SGA_TARGET) and then Oracle would allocate memory to the SGA components based on Oracle’s assessment of the need. In this release a sensible strategy often looked like
- Set SGA_TARGET to specify how much memory is available for Oracle to manage the SGA
- Set the XXX_CACHE and XXX_POOL_SIZE parameters to ensure a minimum allocation for each component in case Oracle underallocates.
In addition I often set SGA_MAX_SIZE to ensure that I had a bit of headroom.
In Oracle 11 there has been still further movement towards taking memory management out of the hands of the DBA with the introduction of the MEMORY_TARGET and MEMORY_MAX_TARGET parameters. If these two parameters are set then Oracle can manage both the SGA and the PGA automatically reallocating components as it sees appropriate between the SGA and the available PGA for all server processes. I haven’t had real production experience with 11 yet but it seems likely that a sensible strategy for 11 will look something like
- Set MEMORY_MAX_TARGET to tell Oracle how much memory there will be for it to use
- Set MEMORY_TARGET to tell Oracle how much memory to use for now for automatic memory management
- Set the XXX_CACHE and XXX_POOL_SIZE parameters to ensure a minimum allocation for each component in case Oracle underallocates.
