Automatic Shared Memory Management in Oracle 10g

Posted by Zahid on December 29, 2009.

Oracle instance in memory consists of two major areas SGA (system/shared global area)and PGA (program/private global area). The SGA is shared by all sessions and consists of a few pools for different purposes. A few of them are as follows: 1. DEFAULT buffer cache :- used to store oracle data blocks when they are read or updated. 2. DEFAULT nK buffer cache :- used to store oracle data blocks having different size then the default block size (db_block_size). 3. KEEP buffer cache :- used to store oracle data blocks from the objects which are not supposed to age out from memory. 4. RECYCLE buffer cache :- used to store oracle data blocks from the objects which are not supposed to be kept in the memory. 5. log buffer cache :- used to store redo entries to reconstruct the operations in case of an instance crash. 6. shared pool :- used to parse and store session queries, define execution plans for queries etc. 7. large pool :- used for backup/recovery operations and batch job processing etc. 8. java pool :- All session's java related activities are done here. 9. streams pool :- used for oracle streams. Sizing these pools manually in the SGA is a great pain and it is almost impossible to use all available memory efficiently to different pools. Lets take a scenario where the database is being used for OLTP application in the daytime and there are some huge batch jobs scheduled to run every night. We have 1G of memory available for SGA out of which we have given 400m to the DB Buffer Cache, 300m to Shared Pool, 100m to Large Pool and rest of the memory i.e. 200m to other pools in the SGA. In the daytime the DB Buffer Cache is being used extensively for OLTP transactions and a very little of Large Pool say 5 to 10 megabytes. Keeping this in view, even when DB Buffer Cache is in contention and 400m is not sufficient enough for it we are wasting a lot of memory in Large Pool where nothing is being happening. While during nights when there is no OLTP activity and we need more memory for Large Pool, a lot of memory is being wasted in the DB Buffer cache. Having this problem in hand now lets go through the ASMM (Automatic Shared Memory Management) feature introduced in Oracle 10g and see how it can help us with our problem. ASMM when switched on, it controls the sizes of the certain components in the SGA by making sure they get the memory they need and it does that by shrinking the components which are not using all of memory allocated to them and growing the ones which need more then the allocated memory. ASMM adopts to the workload changes and maximize the utilization of the memory. This happens with the help of MMAN (Memory Manager) background process which is all the time capturing the workload during the instance run and uses the memory advisers to decide what should be size of components. Components like db_nk_caches, keep/recycle buffer cache and log buffer cache are manually tuned. ASMM does the auto tuning for the following pools: 1. DEFAULT buffer cache 2. Shared Pool 3. Large Pool

Java Pool 5.4. db_cache_size 2. $ sqlplus / as sysdba SQL> alter system set sga_max_size=1G scope=spfile. Total System Global Area 1073741824 Fixed Size 1223540 Variable Size 738198668 Database Buffers 327155712 Redo Buffers 7163904 Database mounted. SQL> shutdown immediate Database closed. 1.----------. large_pool_size 4. which means that the total size of SGA will be 500m and after allocating the defined sizes to the non-auto tuned pools and memory areas Oracle will dynamically manage all the auto tuned pools in the remaining memory space. I have met people having a perception that sga_target is the limit for . System altered. In oracle 10g these initialization parameters are called "auto tuned parameters". System altered.--------------------sga_max_size big integer 1G SQL> According to the configuration we just made the SGA_TARGET is 500m. SQL> alter system set sga_target=500m scope=both. SQL> startup ORACLE instance started.--------------------sga_target big integer 500M SQL> show parameter sga_max_size NAME TYPE VALUE --------------------------. shared_pool_size 3. SQL> show parameter sga_target bytes bytes bytes bytes bytes NAME TYPE VALUE --------------------------. streams_pool_size To switch to ASMM you need to set the initialization parameters SGA_TARGET to a non-zero value which must be less then or equal to value of parameter SGA_MAX_SIZE. Streams Pool (10g R2+) When ASMM is disabled the following initialization parameters are used to set the sizes for auto tuned pools in SGA. ORACLE instance shut down. Database dismounted. But the total size of the SGA will never exceed 500m.----------. java_pool_size 5. Database opened.

sga_max_size is nothing more then a maximum limit which defines how big your sga_target can be. Whenever an oracle instance is started it allocates the SGA memory equal to the value of sga_target. Now lets come back to our example where we have set sga_target to 500m. The SGA will stay in the boundaries of sga_target. keep/recycle buffer cache etc) is 100m.---------shared pool 172 large pool 4 java pool 4 streams pool 0 DEFAULT buffer cache 292 . then rest of 400m will be used for adjusting the sizes of auto tuned pools according to the workload.--------------------global_context_pool_size string java_pool_size big integer 0 large_pool_size big integer 0 olap_page_pool_size big integer 0 shared_pool_size big integer 0 streams_pool_size big integer 0 SQL> SQL> select component . it doesn't effect memory allocation for the SGA in the oracle instance. But othe other hand if initially you set sga_target to 500m and sga_max_size to 1G then you have a window of at lease 500m to increase your sga_target without shutting down your database.2) size_mb 2 from v$sga_dynamic_components 3 where component like '%pool' 4 OR component ='DEFAULT buffer cache'. If the total size of all non-auto tuned areas (log buffer cache.--------------------db_cache_size big integer 0 SQL> show parameter pool_size NAME TYPE VALUE --------------------------. ASMM is not suppose to touch the size of manually tuned memory areas. period. Lets say you have set both sga_target and sga_max_size to 500m initially but later on after a couple of months you find out that 500m is not enough memory for your components to be managed in an efficient manner.sum of non-auto tuned areas sizes). Lets have a look at the current allocation of the auto tuned pools: $ sqlplus / as sysdba SQL> show parameter db_cache_size NAME TYPE VALUE --------------------------. The memory that will be used for the auto tuned pools is (sga_target . it doesn't mean all of this 500m will be used for auto tuned pools. Now if you want to increase the sga_taget to 1G. After we enable the automatic memory management Oracle start managing the pools for us and set reasonable sizes for all the pools according to their nature and the type of work they do.----------. COMPONENT SIZE_MB ------------------------------. you will have to increase the sga_max_size to 1G also because sga_target cannot be larger then sga_max_size.the SGA but if the current_sizes are not enough for the components in the SGA it may grow upto sga_max_size which is incorrect. round(current_size/1024/1024. The reason why sga_max_size is usually larger then sga_target is the relationship between these two and the static nature of the sga_max_size parameter. so it doesn't really matter how big you set your sga_max_size.----------.

It is clear now that when Large Pool needed space Oracle squeezed both buffer cache and shared pool and gave required space to large pool.. 6 / PL/SQL procedure successfully completed. so it is gonna stay in my Large Pool until I exit out the session.100000 loop 3 myPack. create or replace package myPack is TYPE myType is table of char(2000) index by binary_integer. Now lets open another console and connect with a normal oracle user to put the ASMM to the test. COMPONENT SIZE_MB ---------------------------------. / Package created. Also notice (132 + . /* */ $ sqlplus scott/tiger@mydb SQL> 2 3 4 5 6 This is another console where we login with user scott. 4 end loop. /* Now we are back to the sysdba session */ SQL> select component . If we sum them up (172 + 4 + 4 + 292 = 472) is the total size where auto tuning is suppose to happen. v$sga_dynamic_component shows us the current sizes of all these components in SGA. keep/recycle cache sizes and any db_nk_cache_sizes if configured. I created a packaged PL/SQL table of type char(2000) and populated 100000 elements in it. The sysdba session is still intact in the other console. myTable myType. Being char(2000) each element's size is 2000 bytes no matter hat I assign to it. 5 end. so any variables I declare will be stored in the Large Pool where my UGA is being maintained. Hence after the population of the PL/TABLE it is going to be around 200m in size.myTable(i) := i. Once I exit from the session the variable should be cleaned out releasing space from Larg Pool.Notice all the auto tuned parameters are set to 0 (we will discuss about this later). Rest of 28m is for other areas in SGA like log buffer. SQL> exit I established this session using shared server mode. round(current_size/1024/1024. Since it is a packaged variable. SQL> begin 2 for i in 1.2) size_mb 2 from v$sga_dynamic_components 3 where component like '%pool' 4 OR component ='DEFAULT buffer cache'. end.---------shared pool 132 large pool 232 java pool 4 streams pool 0 DEFAULT buffer cache 104 Notice the current size of all these pools.

SQL> / 325576 rows created. SQL> / 162788 rows created. Lets go back to our normal session and create a heavy work load on Default buffer cache /* */ $ sqlplus scott/tiger@mydb Open another console and connect with a normal oracle user. SQL> / 1302304 rows created. SQL> select table_name . SQL> commit. Table analyzed.2) size_mb 2 from user_tables 3 where table_name = 'BIG_TABLE'. Now these sizes will stay like this until any pool needs more memory then it has and that is when these sizes will adjust again. SQL> insert into big_table select * from big_table.---------BIG_TABLE 283. Table created. SQL> create table big_table as select * from all_objects. Commit complete. The sysdba session is still open in the other console. round(blocks*8192/1024/1024.21 SQL> . TABLE_NAME SIZE_MB -----------------------------.232 + 4 + 104 = 472). SQL> / 81394 rows created. SQL> analyze table big_table compute statistics. SQL> / 651152 rows created. 40697 rows created.

round(current_size/1024/1024. Total System Global Area 1073741824 bytes Fixed Size 1223540 bytes Variable Size 671089804 bytes Database Buffers 394264576 bytes Redo Buffers 7163904 bytes Database mounted. /* Now we are back to the sysdba session */ SQL> select component . Database opened.---------shared pool 108 large pool 4 java pool 4 streams pool 0 DEFAULT buffer cache 356 See the buffer cache is larger the all others. COMPONENT SIZE_MB ----------------------------------.2) size_mb 2 from v$sga_dynamic_components 3 where component like '%pool' 4 OR component ='DEFAULT buffer cache'. SQL> shutdown immediate Database closed.2) size_mb 2 from v$sga_dynamic_components 3 where component like '%pool' 4 OR component ='DEFAULT buffer cache'. The dynamically adjusted sizes are retained through instance shutdowns if you are using server parameter file (i. spfile). Lets go back to sysdba session and see what are the current sizes of these components. When these queries are processed there is an extensive aging out and loading of rows from big_table in buffer cache causing high physical reads and low cache hit ratio. MMAN (memory manager) captures it and signals the adjustment in the size of buffer cache as there is a plenty of free space in Large Pool. The free space has been taken away from Large Pool and even some from Shared Pool also to accommodate heavy workload on buffer cache.3 million rows here in the table big_table which is 283m in size i. As the current component sizes stand (108 + 4 + 4 + 356 = 472) Oracle is managing then within the boundary of 472m. round(current_size/1024/1024. COMPONENT SIZE_MB --------------------------------. SQL> startup ORACLE instance started. SQL> select component . Database dismounted.We have processed about 1.---------shared pool 108 large pool 4 java pool 4 streams pool 0 DEFAULT buffer cache 356 /* .e. ORACLE instance shut down.e quite larger then the whole buffer cache as its current size is 104m.

LAST_OPER_TYPE.------.ksppinm LIKE '%pool_size%'). round(current_size/1024/1024.------------.ksppinm "Parameter". If you open your spfile in any text editor you will see these parameters set there as well. MIN_SIZE.ksppinm LIKE '%db_cache_size%' 11 OR a. 3 b.ksppinm LIKE '/_/_%' escape '/' AND 10 (a.Even after a shutdown and restart the components are of the same size. 6 x$ksppsv b 7 WHERE 8 a. SQL> SQL> SQL> 2 3 4 5 set lines 10000 column component format a20 select component . Parameter -----------------------------__shared_pool_size __large_pool_size __java_pool_size __streams_pool_size __db_cache_size Value ---------113246208 4194304 4194304 0 373293056 How is this happening? Actually whenever these components size is changed it is updated in undocumented siblings of auto tuned parameters. OPER_COUNT. COMPONENT SIZE_MB LAST_OPER_TYP OPER_COUNT -------------------.2) size_mb.indx AND 9 a.ksppstvl "Value" 4 FROM 5 x$ksppi a.indx = b. */ SQL> SELECT 2 a. The above query shows how to read undocumented oracle parameters and their values from tables x$ksppi (contains parameter names) and x$ksppsv (contains parameter values for the instance) owned by sys.---------shared pool 112 GROW 1 large pool 4 SHRINK 114 java pool 4 STATIC 0 streams pool 0 STATIC 0 DEFAULT buffer cache 352 GROW 115 SQL> A few more things to know about ASMM: . Here are some other useful columns in the view v$sga_dynamic_components where you can see the Operations have been happening with these components along their minimum and maximum sizes. MAX_SIZE from v$sga_dynamic_components where component like '%pool' OR component ='DEFAULT buffer cache'. On the instance start up these undocumented parameters are read and the components are allocated accordingly.

----------. which means 0 is the minimum size for this component and this component can be re-sized to 0 to allow other components use all of its memory.----------. System altered. If we change them as follows: SQL> alter system set db_cache_size=100m scope=both. rather it is considered as a minimum size for that component. SQL> 2 3 4 select component . When setting the auto tuned parameters manually if you set a size larger then its current size and the increase in the size can be supported by shrinking other components then the change is done immediately.-------------------db_cache_size big integer 100M SQL> This means 100m is the minimum size for the buffer cache. SQL> show parameter db_cache_size NAME TYPE VALUE -------------------------.When the ASMM is switched all auto tuned parameter sizes are managed by the oracle it self and any sizes manually defined for these parameters are no more considered as the max size that component may have. COMPONENT SIZE_MB -------------------.-------------------db_cache_size big integer 0 SQL> show parameter pool_size NAME -------------------------global_context_pool_size java_pool_size large_pool_size olap_page_pool_size shared_pool_size streams_pool_size SQL> TYPE ----------string big integer big integer big integer big integer big integer VALUE -------------------0 0 0 0 0 All auto tuned parameter values are set to 0. no matter what happens to the other components this 100m will never be taken away from the Default buffer cache.---------shared pool 112 . Manual settings of the auto tuned parameters is useful when you don't want one of components to suffer too much because of auto adjustments in sizes.2) size_mb from v$sga_dynamic_components where component like '%pool' OR component ='DEFAULT buffer cache'. round(current_size/1024/1024. $ sqlplus / as sysdba SQL> show parameter db_cache_size NAME TYPE VALUE -------------------------.

you will get an error like this. round(current_size/1024/1024. SQL> 2 3 4 select component . SQL> alter system set shared_pool_size = 450m scope=both.---------shared pool 120 large pool 4 java pool 4 streams pool 0 DEFAULT buffer cache 344 .2) size_mb from v$sga_dynamic_components where component like '%pool' OR component ='DEFAULT buffer cache'. COMPONENT SIZE_MB -------------------. System altered. alter system set shared_pool_size = 450m scope=both * ERROR at line 1: ORA-02097: parameter cannot be modified because specified value is invalid ORA-04033: Insufficient memory to grow pool SQL> When an auto tuned parameters are set to a value lower then their current size then the change is not done immediately. System altered. And when there is no space available to grow the pool to the size you specified. SQL> alter system set shared_pool_size = 100m scope=both. COMPONENT SIZE_MB -------------------. SQL> 2 3 4 select component .2) size_mb from v$sga_dynamic_components where component like '%pool' OR component ='DEFAULT buffer cache'. round(current_size/1024/1024.large pool java pool streams pool DEFAULT buffer cache 4 4 0 352 SQL> alter system set shared_pool_size = 120m scope=both.---------shared pool 120 large pool 4 java pool 4 streams pool 0 DEFAULT buffer cache 344 We increased the size of shared pool from 112m to 120m and there was space in buffer cache that was available for allocating to shared pool so our change came into effect immediately.

--------------------db_cache_size big integer 344M SQL> show parameter pool_size NAME --------------------------global_context_pool_size java_pool_size large_pool_size olap_page_pool_size shared_pool_size streams_pool_size SQL> TYPE ----------string big integer big integer big integer big integer big integer VALUE --------------------4M 4M 0 120M 0 .SQL> Now according to the workload if a situations comes where Oracle has to shrink shared pool then the shared will be squeezed to 100m and the shrinking will stop since 100m is the minimum value for shared pool. If you disable the ASMM then all the components that are being managed by the auto tuning will be freezed at their current sizes and become static unless you enable the ASMM again. System altered. SQL> alter system set sga_target=0 scope=both.----------. SQL> show parameter db_cache_size NAME TYPE VALUE --------------------------.