S hared P ool

Library Cache

Dictionary Cache

Control Structure

ALL ABOUT POOL
Tapas Kumar Oracle DBA

SHARED
S QL Area PL?SQL Procedure Control Struct Object definition Latch LOCK

TATA CONSULTANCY SERVICES

INTRODUCTION What is shared pool? This first query that comes, let us have a brief introduction regarding shared pool here first. Most of the people knows that shared pool is the part of System Global Area (SGA) it’s true but little else, What exactly the shared pool? Shared pool are contain lots of key memory areas of Oracle and in Instance tuning the major area that we have to tune is shared pool if shared pool defined improperly the overall database performance will suffer. INTERNAL STRUCTURE –

A shared SQL area contains the parse tree and execution plan for a single SQL statement, or for similar SQL statements. Oracle saves memory by using one shared SQL area for multiple similar DML statements, particularly when many users execute the same application. A shared SQL area is always in the shared pool. Oracle allocates memory from the shared pool when a SQL statement is parsed; the size of this memory depends on the complexity of the statement. If a SQL statement requires a new shared SQL area and the entire shared pool has already been allocated, Oracle can deallocate items from the pool using a modified least Recently used algorithm until there is enough free space for the new statement's shared SQL area. A private SQL area contains data such as bind information and runtime buffers. Each session that issues a SQL statement has a private SQL area. Each user that submits an identical SQL statement has his or her own private SQL area that uses a single shared SQL area; many private SQL areas can be associated with the same shared SQL area. A private SQL area contains data such as bind information and runtime buffers. Each session that issues a SQL statement has a private SQL area. Each user that submits an identical SQL statement has his or her own private SQL area that uses a single shared SQL area; many private SQL areas can be associated with the same shared SQL area. A private SQL area has a persistent area and a runtime area: • The persistent area contains bind information that persists across executions, code for datatype conversion (in case the defined datatype is not the same as the datatype of the selected column), and other state information (like recursive or remote cursor numbers or the state of a

Majority shared pool related to the two part of SGA one is fixed are which is relatively constant to a oracle instance for a particular version and the second part is Variable area which gradually shrink and grow for user and application requirement. Now we should do a close look of various component of Shared Pool – Basically Shared Pool could be divided in three major parts – 1. Library Cache 2. Dictionary Cache 3. Control Structure Library Cache – Memory Part where all the SQL and PL/SQL statement executed, all execution plan reside here for SQL statement stored here. We can further subdivide this Library Chache into – 1. Shared and Private SQL Area 2. PL/SQL Procedure Part Shared and Private SQL Area –

----------------------------------. If more than one user executes the same program unit. the runtime area is somewhat smaller for INSERT.g. shared area is used by all users. For queries. the runtime areas. – select * from X$KSMSS where KSMSSNAM = 'sql_area' and KSMSSLEN <> 0 .---------000000011049B268 28 1 1501552 PL/SQL DIANA 1 000000011049B268 37 1 1357968 PL/SQL MPCODE 1 Oracle creates the runtime area as the first step of an execute request. the persistent areas and. Oracle frees the runtime area only after all rows are fetched or the query is cancelled. for SELECT statements. the persistent area is larger if many columns are specified in a query. The size of the runtime area depends on the type and complexity of the SQL statement being executed and on the sizes of the rows that are processed by the statement. PL/SQL Procedure Part – Oracle processes PL/SQL program units (procedures. PL/SQL DIANA stands for the PL/SQL code size in the shared pool at runtime. these SQL statements use a shared area to hold their parsed representations and a private area for each session that executes the statement.---------. Oracle allocates a private area to hold values specific to the session that executes the program unit. while each user maintains a separate copy of his or her private SQL area. then a single. compiled form of a program unit. packages. Oracle frees the runtime area after the statement has been executed.---------.---------ADDR INDX KSMSSNAM 000000011049B268 sql area INST_ID KSMSSLEN KSMDSIDX 29 1 13480352 1 PL/SQL MPCODE stands for machine dependent pseudocode.---------. are kept in the SGA (x$ksmms) table provide the runtime information regarding SQL area in Library Cache which is suppose to be allocated to a particular Oracle Instance – E. ADDR INDX INST_ID KSMSSLEN KSMSSNAM KSMDSIDX ---------------. In general. functions. private SQL areas are located in the user's PGA.g.----------------------------------. if a session is connected via the multi-threaded server. However.• parallel query). UPDATE and DELETE statements than it is for SELECT statements. For INSERT. ---------------. and DELETE statements. particularly when the SELECT statement requires a sort. Individual SQL statements contained within a PL/SQL program unit are processed as described in the previous sections. anonymous blocks. Library Cache Manager – . global. and package variables (also known as package instantiation) and buffers for executing SQL. The runtime area contains information used while the SQL statement is being executed. – select * from X$KSMSS where KSMSSNAM like 'PL/SQL%' and KSMSSLEN <> 0 .---------. The location of a private SQL area depends on the type of connection established for a session. If a session is connected via a dedicated server. UPDATE. The size of the persistent area depends on the number of binds and columns specified in the statement. (x$ksmms) table provide the runtime information regarding PL/SQL area in Library Cache which is suppose to be allocated to a particular Oracle Instance – E. Despite their origins within a PL/SQL program unit. Oracle allocates a shared area to hold the parsed. For example. holding values specific to his or her session. and database triggers) much the same way it processes individual SQL statements. including local.

The library cache manager will apply a modulo hash function to a given object’s namespace. access to the hash table is blocked (by freezing access to the child latches) as one user allocates new buckets to double the size of the hash table and then uses the least significant bits of the hash value to determine which new bucket a handle belongs to. shared cursors. this is a rare and inexpensive operation that may cause a short (approximately 3-5 second) hiccup in the system. packages. the library cache manager will create an empty object with the given name. KGL. and an authorisation table (to name a few). The next . Each library cache object handle points to a library cache object and has a reference list. object name. however. It then walks down the corresponding linked list to see if the object is there. it will call the heap manager (KGH) to allocate it. which contains the identity (name) of the object. When the library cache. a child table. form definitions). functions. 2039. The library cache handle then points us to one or more the library cache objects and their contents. 4093. needs more memory. numbers are the next higher prime value. owner. the client would read from disk. call the heap manager to allocate memory. The library cache caches different types of library objects (e. The library cache object is further broken down into other components such as a dependency table. table definitions. and request the client load it by calling the client's environment-dependent load function. anonymous PL/SQL blocks. the number of buckets will increase when the number of objects in the table exceeds the next number. 16381. The initial number of the hash buckets is 251. The hash table never shrinks. insert it in the hash table. and load the object. which consists of an array of hash buckets. rehashing the library cache objects from the old table to the new table. 509. If the object does not exist. A hashing mechanism is used to locate a handle. Each hash bucket is a doubly linked list of library cache object handles. 8191. and database link to determine the hash bucket where the object should be found. and 4292967293 where the "n+1"th size is approximately twice the "n"th size. The resulting expansion of the hash table will involve allocating a new hash table at the next prime size. They are 251. Library cache memory is allocated out of the top most heap or the generic SGA heap.The main purpose of the library cache is to provide a mechanism to locate and store any library cache object quickly. Library Cache Handle – Library Cache Manager (Hash Table and Hash Bucket) – The hash table is an array of hash buckets. view definitions. The library cache consists of a hash table. procedures. 131071. Throughout this procedure. Basically.g. Contrary to common belief. 32749. 65521. and freeing the space allocated from the old hash table. 1021.

a reference list. A library cache handles points to a library cache object. one for triggers. The namespace describes the type of an item kept in the library cache. there are basically four type of classes – . a timestamp. It contains the name of the library object. A handle can be freed if there are no current references to it and it has not been expressly marked to be kept.----------------------------------.ora file and can’t be changed without shutting down the database.---------. one for indexes. one for package bodies and table bodies. This chunk is supposed to be larger then the size of the object as it also contains the header information.---------.---------- Shared Pool Chunks – Have close looks of Shared Pool. ADDR INDX INST_ID KSMSSLEN KSMSSNAM KSMDSIDX ---------------. the process session and transaction arrays. select * from X$KSMSS where KSMSSNAM like 'PL/SQL%' and KSMSSLEN <> 0 . a list of locks locking the object and a list of pins pinning the object. even anonymous PL/SQL blocks. one for shared cursors. We use this to determine when a handle should be unpinned in memory. The name consists of the object owner name. A comprehensive list can be viewed from v$librarycache. which describe the purpose of allocation. These are examples of different types of namespaces: one namespace holds all namespaces depended on PL/SQL objects. The column KSMCHCLS represent the class. The size of these arrays depends on the setting of Initialisation parameter of Init. the namespace. The library cache manager will generate a name for every object.---------------. The handle uses namespaces to partition library cache objects by types. the object name. the database link name. Dictionary Cache – Table definition against which an application user suppose to do a query. it include table’s associated Index and Columns and privilege information regarding table as we as columns. Each object is uniquely identified by the name within its namespace. For that we should have a close look at x$ksmsp each row in this table shows a chunk of shared pool – KSMCHCOM KSMCHPTR KSMCHSIZ KSMCHCLS ---------------. it also contain buffer header. and the database link owner name.-------sql area 0700000005D85750 1360 freeabl 0700000005D846F8 4184 freeabl KGL handles 0700000005D84520 472 recr library cache 0700000005D84478 168 freeabl 0700000005D84150 808 recr KQR PO 0700000005D83D20 1072 recr KGL handles 0700000005D83B48 472 recr library cache 0700000005D83AA0 168 freeabl 0700000005D83778 808 recr 0700000005D83450 808 freeabl KGL handles 0700000005D83300 336 recr When each shared pool chunk is allocated the code is passed to a function that does the work of allocation and this address is visible to KSMCHCOM column. and one for clusters.000000011049AE88 dictionary cache 60 2 1 1092352 Control Structure This contain the information regarding Internal Latch and Locks (Data Structure).---------.

ORA-04331 ‘unable to allocate x bytes of shared pool’ when all the free memory fully exhausted (Later we will discuss the shared pool fragmentation). If an application has no dynamic sql then the amount of memory can simply be measured after the application has run for a while by just selecting it out of the shared pool as follows: select sum(sharable_mem) from v$sqlarea. NAME COUNT(KSMCHCOM) RECREATABLE FREEABLE ---------------. then a certain amount of memory will be needed for the shared sql plus more for the dynamic sql.----------. and removing these object from memory is based on LRU(Least Recent Used) means those objects that are frequently pinned kept in the memory and those are unpinned we generally remove those objects from the memory. To determine the shared pool size for a production system it is generally necessary to develop the application run it on a test environment (should be enough like production system) get some test result and on the basis of that calculate the shared pool size. So the overall summary select KSMCHCOM name.---------PARAMETER ENTRY 4 192 PARAMETER TABLE 1 2064 PL/SQL DIANA 237 12816 479672 PL/SQL MPCODE 23 11792 50336 PLS cca hp desc 1 376 PLS non-lib hp 1 2136 PRESENTATION TA 1 2064 SERVICE NAME EN 2 152 SERVICE NAMES T 1 2064 character set m 5 31936 reserved size. Then it try to remove chunk containing recreatable object from shared pool to get the desired size of chunk. Approximated memory could be calculated by the following: .ora parameter file.'freeabl'. You can just measure their size directly with the following statement: select sum(sharable_mem) from V$DB_OBJECT_CACHE. Object those required again known as transient and other known as recurrent. sum(decode(KSMCHCLS. count(KSMCHCOM).'recr'. Parm – contained by the permanent object. character set o 4 318648 LRU List – When a process starts it allocate some memory and when it’ fails to allocated required memory. Recr – contain by temporary objects. here REQUEST_MISS shows the number of times the request miss for a large chunk.KSMCHSIZ)) RECREATABLE. With the help of v$shared_pool_reserved we can see SQL The amount of memory needed to store sql statements in the shared pool is more difficult to measure because of the needs of dynamic sql. If the application has a moderate or large amount of dynamic sql like most applications do. sum(decode(KSMCHCLS. There are some few step which we should consider while calculating the shared pool – STORED OBJECTS – The amount of shared pool that needs to be allocated for objects that are stored in the database like packages and views is easy to measure. it generally 5% of the total size of Shared Pool and reserved size is defined by SHARED_POOL_RESERVED_SIZE parameter in Init.Freeable – can be freed only contain the objects needed for the session call. Sufficient memory should be allocated so that the dynamic sql does not age the shared sql out of the shared pool.KSMCHSIZ)) FREEABLE from x$ksmsp group by KSMCHCOM . Free – free and not contained by valid object. There is one list maintained which known as Reserved List. SHARED_POOL SIZE CALCULATION – The shared pool size is highly application dependent.--------------.

v$statname n where s.name = 'opened cursors current' -.For a test system -. free_mem number.name = 'session uga memory' and s.For MTS add mts contribution also.replace 23 with session id of user being measured The per-user per-cursor memory is one of the classes of memory that shows up as 'library cache' in v$sgastat. -.put_line ('Shared sql: '||to_char (shared_sql) || ' bytes'). v$statname n where s. OVERHEAD – You will need to add a minimum of 30% overhead to the values calculated above to allow for unexpected and unmeasured usage of the shared pool. dbms_output. v$statname n -. The remaining memory in v$sqlarea is for dynamic sql. begin -.Display results dbms_output. you can measure this as follows: select sum(250 * users_opening) from v$sqlarea.sid = 23.statistic# -.statistic# = n.name = 'session uga memory max'.where s.replace 23 with session id of user being measured A more conservative value to use is the maximum session memory that was ever allocated by the user: select value sess_max_mem from v$sesstat s. -.3*(object_mem+shared_sql+cursor_me m+mts_mem)).Free (unused) memory in the SGA: gives an indication of how much memory -. PER-USER PER-CURSOR MEMORY – You will need to allow around 250 bytes of memory in the shared pool per concurrent user for each open cursor that the user has whether the cursor is shared or not.replace 23 with session id of user being measured To select this value for all the currently logged on users the following query can be used: .Shared SQL -.run this during peak usage select sum(250*users_opening) into cursor_mem from v$sqlarea.statistic# = n. used_pool_size := round(1. -. Estimating Procedure (From Metalink) – set serveroutput on.statistic#=n. -.name = 'opened cursors current' and s. -. -.statistic# and n. cursors and 30% overhead. v$statname n where s.statistic# and n. MTS – If you are using multi-threaded server. pool_size varchar2(100). -.Stored objects (packages.is being wasted out of the total allocated. v$statname n where s. -.and n. multiply by # users -. -. select bytes into free_mem from v$sgastat where name = 'free memory'.sid = 25. then you will need to allow enough memory for all the shared server users to put their session memory in the shared pool.statistic# and n. cursor_mem number.statistic# = n.where 25 is the sid of the process -.select sum(sharable_mem) from v$sqlarea where executions > 5.name = 'session uga memory max' and s. -.during peak period).used_pool_size := round(1.select (250 * value) bytes_per_user -. -.statistic# = n.from v$sesstat s. v$statname n where s. In a test system you can measure it by selecting the number of open cursors for a test user and multiplying by the total number of users: select 250 * value bytes_per_user from v$sesstat s. -. shared_sql number. used_pool_size number.This query computes a total for all currently logged on users (run -.MTS memory needed to hold session information for shared server users -. shared sql.sid = 23. select sum(value) all_sess_mem from v$sesstat s. select sum(value) into mts_mem from v$sesstat s.statistic# = n.statistic# and n.User Cursor Usage -. views) select sum(sharable_mem) into object_mem from v$db_object_cache. Alternatively calculate for a single user and -.and s.need to have additional memory if dynamic SQL used select sum(sharable_mem) into shared_sql from v$sqlarea.multiply by # users. declare object_mem number.sid = 23.put_line ('Obj mem: '||to_char (object_mem) || ' bytes'). select value into pool_size from v$parameter where name='shared_pool_size'. mts_mem number.get usage for one user.For non-MTS add up object. During the peak usage time of the production system. This can be measured for one user with the following query: select value sess_mem from v$sesstat s.name='session uga memory max'.statistic# and n.3*(object_mem+shared_sql+cursor_me m)).

put_line ('Shared pool utilization (total): '|| to_char(used_pool_size) || ' bytes ' || '(' || to_char(round(used_pool_size/1024/1024. a.SQL_TEXT. a.SQLAREA SUMMARY REPORT REM Mapping between user and sql area usage. max(c.dba_users b where a.KSPPSTVL)/(1024*1024))sum(a. create table temp_sql_report as (select b. dbms_output.username.indx = c. but some time the reason may be other of hogh percentage of shared pool. Volume I.put_line ('Shared pool allocation (actual): '|| pool_size ||' bytes ' || '(' || to_char(round(pool_size/1024/1024.')and b. (max(c.RUNTIME_MEM from v$sqlarea a. 'library cache'.KSMSSLEN)/(1024*1024) Pool_used.0933857 If shared percentage (POOL_PCT) in nineties then we need to increase the size of shared pool. a. The above scripts should run periodically to get a summary of Shared Usage at peak and normal time.SHARABLE_MEM.PARSING_USER_ID = b. 'PL/SQL DIANA'. 'table definiti'. 'dictionary cache'. Shared Pool usage we can see at a given point of time from the following script – select sum(a. x$ksppi b. Col Col Col Col username for a20 heading USER sharable_mem for a25 heading SHARABLE persistent_mem for a20 heading PERSIS run_time for a20 heading RUNTIME The out of the above script - start title80 ‘SQL AREA SUMMARY REPORT’ Spool sql_area_summary_report . First report will shown here the individual mapping of user with shared pool – MONITORING & TUNING – Let begin with major part which is knows as shared pool tuning and Oracle recommend that the default size of Shared Pool in Init. So how we can see that what is in the shared pool? Whether is being properly used or not. 'sql area'.0101166 28. POOL_USED POOL_SIZE POOL_AVAIL POOL_PCT ---------------. Now we should focus on high percentage usage of shared pool why it high (more then 90%).O.---------------. a.KSPPSTVL))*100 pool_pct from x$ksmss a.98988342 32 23.that produces a summary report for each user.indx and b.KSPPINM='shared_pool_size' Create a temporary table to hold the information related to sql area for all users. We should see whether the shared pool fill with reusable sql or with bad sql.load. dbms_output. dbms_output.PERSISTENT_MEM. a.KSMSSLEN)/(1024*1024)) pool_avail. From V$SGASTAT and V$SQLAREA we will get this information.2)) || 'M)').put_line ('Cursors: '||to_char (cursor_mem) || ' bytes'). 'SEQ S. x$ksppcv c where a. The other shared pool parameter controls how to the variable space area in the shared pool is parsed out. Technical Reports Compendium.ora parameter should be ¼ of the Total SGA in a general scenario. (sum(a.KSMSSNAM in ( 'reserved stopper'.USER_ID SQL SUMMARY REPORT – REM <-. it might be possible to flush the shared pool would resolved the high percentage issue of shared pool.put_line ('Free memory: '||to_char (free_mem) || ' bytes ' || '(' || to_char(round(free_mem/1024/1024. For that we can generate some common useful report.put_line ('MTS session: '||to_char (mts_mem) || ' bytes'). a. 1996 Shared Pool Internals dbms_output. Now a question comes in our mind what are the key area should be monitored by the DBA to get the knowledge that the shared pool size is small.------8.user_executing a. According to the suggestion give by Oracle if our total SGA size is 100 MB then we should set our Shared Pool size 25 MB and latter increase gradually as needed by the system.dbms_output.KSPPSTVL)/(1024*1024) pool_size.put_line ('Percentage Utilized: '|| to_char (round(used_pool_size/pool_size*100)) || '%'). dbms_output.execution. before increase the size of shared pool we should examine all the key areas.2)) || 'M)').2)) || 'M)'). end.KSMSSLEN)/max(c.

P_FACILITY mv_edimessages. P_MESSAGE_NO mv_edimessages.message_no%type := NULL. users_executing. Now try to analyse the summary report.booking_item%type := 1.tplan_id%type . P_EQP_SIZE mv_tplans.ref1_type%type := B.Select Username.event_datetm%type := SYSDATE. P_EVENT_TYPE mv_eventtableitems. P_BOOKING _ITEM mv_tplans. What things should we watch for in a user's SQL areas? First. P_RETURN_MESG This output of this summary report shows here the sql area used by each user.eqs_eqp_size_fk%type := 20. if a particular hold a large amount of memory then that means the sql’s used by that user are bad every time it generate different execution plan for similar kind of queries. watch for the non-use of bind variables. Sum(RUNTIME_MEM) From temp_sql_report Group by username.--------------. sharable_mem.---------------SYS 3004291 237048 1097504 TEST 281085 18040 83328 The out put of the report look like this – USERS -----------------------------SQL_TEXT ---------------------------------------------------------------------------------------------------------------------------------EXECUTIONS LOADS USERS_EXECUTING SHARABLE_MEM PERSISTENT_MEM ---------.ref1_no%type := upper('HAI2000229/1'). p_ack_reqd_ind number := 0. Spool off / USERNAME SUM(SHARABLE_MEM) SUM(PERSISTENT_MEM) SUM(RUNTIME_MEM) ---------------------------------------------------------------.-----------. P_ACK_ERROR_CODE VARCHAR2(8). The problem with non-reusable SQL is that it must still be looked at by . what amount of memory that sql statement took to execute the statement.---------.1. Notice that for most of the rest of the statements in the report no bind variables are used even though many of the SQL statements are nearly identical. Sum(PERSISTENT_MEM).eqm_eqp_no_fk%type := upper('GLDU0371682').version_no%type.tleg_id%type. Now we can generate an another where we will shown the actual sql statement executed by a user and how many time a sql statement execute by a user .-------------0 2 0 16439 1376 SYS DECLARE P_EQP_NO mv_tplans. P_PLAN_ID mv_tplans. P_RETURN_CODE NUMBER. the coding produce a large number of nonreusable sql area. Sum(SHARABLE_MEM).username like upper('%&user_name%') order by 3 desc. spool off pause Press enter to continue One warning about the script.fac_facility_fk%type := upper('SCTSOUGB'). sql_text. loads. P_EVENT_DATETM mv_edimessages. P_REF_TYPE mv_edimessages. P_LEG_ID mv_tplanlegs. bind variable usage is shown by the inclusion of variables such as ":4" in the SQL text.booking_ref_no%type.eqt_eqp_type_code_fk%type := upper('GP '). P_BOOKING_REF_NO mv _tplans. column sql_text format a60 heading Text word_wrapped column sharable_mem heading Shared| Bytes column persistent_mem heading Persistent|Bytes column loads heading Loads column users format a15 heading "User" column executions heading "Executions" column users_executing heading "Used By" start title132 "Users SQL Area Memory Use" spool Sql_info set long 2000 pages 59 lines 132 break on users compute sum of sharable_mem on users compute sum of persistent_mem on users compute sum of runtime_mem on users select username users. As the stement using the bind variable: 4 so is reusable. P_EQP_TYPE mv_tplans. P_FCL_LCL mv_tplans. persistent_mem from temp_sql_report where b. P_VERSION_NO mv_tplans. Executions. This is one of the leading causes of shared pool misuse and results in useful SQL being drown in tons of non-reusable garbage SQL. P_REF_NO mv_edimessages.event_type%type := 4. Non-bind usage means hard coded values such as upper ('GLDU0371682') are used. the report it generates can run to several hundred pages for a user with a large number of SQL areas.fcl_lcl%type := NULL.

If this same statement was used for checking the 'version' throughout the application then the literal value '2.g 1 – SELECT * FROM temp_x WHERE col_1='x'. FRO app_vers ion W ERE M H User USER_Y has his own table called TEMP_X and also issues: SELECT column_y from TEMP_X. is used by the application instead of SELECT * FROM temp_x WHERE ename=:x. Eg 3: SELECT vers ion vers ion>2. Eg 2: SELECT sysdate FROM dual.any new SQL inserted into the pool (actually it's hash value is scanned). Sharable SQL If two sessions issue identical SQL statements it does NOT mean that the statement is sharable. Although both of these statements are really the same they are not identical as an upper case 'T' is not the same as a lower case 't'. As far as the application is concerned it has asked to parse the statement. E. where the value of the literal is likely to differ between various execution of the statement. Soft Parse If session issues a SQL statement. While a hash value scan may seem a small cost item. which is already in the shared pool AND it. There are many things that determine if two identical SQL strings are truly the same statement (and hence can be shared) including: All object names must resolve to the same actual objects The optimiser goal of the sessions issuing the statement should be the same . As the SQL statement issued by the user is directly related to the shared pool and using a good mechanism of coding improve the system performance and also avoid redundant parsing of PL/SQL and SQL statement for Library Cache (memory + CPU). Hard Parse If a new SQL statement is issued which does not exist in the shared pool then this has to be parsed fully. and in the number of latch gets performed. Consider the following: User USER_X has a table called TEMP_X and issues: SELECT column_x from TEMP_X.0' is always the same so this statement can be considered sharable.. Identical Statements? If two SQL statements mean the same thing but are not identical character for character then from an Oracle viewpoint they are different statements. if your shared pool contains tens of thousands of SQL areas this can be a performance bottleneck.0. check the statement syntactically and semantically etc. very expensive in both terms of CPU used. As Library Cache is a part of Shared pool so Indirectly we can say we tuned the Shared Pool.. Hence these are different versions of the same basic statement. is Although the text of the statements are identical the TEMP_X tables are different objects. does not use bind variables but would not be considered as a literal SQL statement for this article as it can be shared. Let have a Close look of various parsing type of SQL – Literal SQL – A literal SQL statement is considered as one which use literals in the predicates rather then bind variable. Consider the following issued by SCOTT in a single session: SELECT ENAME from TEMP_X. Eg: Oracle has to allocate memory for the statement from the shared pool. This is referred to as a hard parse. SELECT ename from temp_x. can use an existing version of that statement then this is known as a 'soft parse'.

Also the amount of CPU spent on parsing is typically only a small percentage of that used to execute each statement so it is probably more important to give the optimiser as much information as possible than to minimise parse times. Sharable SQL If an application makes use of literal (unshared) SQL then this can severely limit scalability and throughput. Versus SELECT distinct cust_ref FROM orders WHERE total_cost < :bindA.0 or 99999999999999999.1) protect operations within the library cache itself. The library cache latches (and the library cache pin latch in Oracle 7. In the second statement CBO has no idea what percentage of rows fall below ":bindA" as it has no value for this bind variable to determine an execution plan . Consider the following: SELECT distinct cust_ref FROM orders WHERE total_cost < 10000.0. Literal SQL The Cost Based Optimiser (CBO) works best when it has full statistics and when statements use literals in their predicates. Eg: ":bindA" could be 0. Eg: SELECT xx FROM MYTABLE. This is typical of Decision Support Systems where there may not be any 'standard' statements.9 There could be orders of magnitude difference in the response time between the two execution paths so using the literal statement is preferable if you want CBO to work out the best execution plan for you. All of these latches are potential points of contention. The cost of parsing a new SQL statement is expensive both in terms of CPU requirements and the number of times the library cache . The number of latch gets occurring is influenced directly by the amount activity in the shared pool. where each user has their own MYTABLE Setting _SQLEXEC_PROGRESSION_COST to '0' in Oracle 8.1 Library Cache and Shared Pool latches The shared pool latch is used to protect critical operations when allocating and freeing memory in the shared pool.The types and lengths of any bind variables should be "similar". For the first statement the CBO could use histogram statistics that have been gathered to decide if it would be fastest to do a full table scan of ORDERS or to use an index scan on TOTAL_COST (assuming there is one). especially parse operations. which are issued repeatedly so the chance of sharing a statement is small. Literal SQL versus Shared SQL To give a balanced picture this short section describes the benefits of both literal SQL and sharable SQL. Anything that can minimise the number of latch gets and indeed the amount of activity in the shared pool is helpful to both performance and scalability. Hence high version counts are best avoided by: Standardising the maximum bind lengths specified by the client Avoid using identical SQL from lots of different schemas. If Oracle matches to a statement with many versions it has to check each version in turn to see if it is truly identical to the statement currently being parsed. (We don’t discuss the details of this here but different types or lengths of bind variables can cause statements to be classed as different versions) The NLS (National Language Support) environment which applies to the statement must be the same Versions of a statement As described in 'Sharable SQL' if two statements are textually identical but cannot be shared then these are called 'versions' of the same statement. which use private objects.

The following query that shows SQL in the SGA where there are a large number of similar statements: SELECT substr (sq l _ text . Note: There is often some degree of resistance to converting literal SQL to use bind variables. Note that a session only has <Parameter: OPEN_CURSORS> cursors available and holding cursors open is likely to increase the total number of concurrently open cursors.40) "SQL" ..5 and 30 are example values so this query is looking for different statements whose first 40 characters are the same which have only been executed a few times each and there are at least 30 different occurrences in the shared pool. Increasing the shared pool size delays the problem but it reoccurs more severely." with the leading portion of each statement being the same. col2. In precompilers the HOLD_CURSOR parameter controls whether cursors are held open or not while in OCI developers have direct control over cursors.. The values 40. Obviously there will be some statements which are rarely executed and so maintaining an open cursor for them is a wasteful overhead. sum(executions) "TotExecs" FROM v$sqlarea W ERE execut ions < 5 H GROUP BY substr(sql_text. Latch contention on shared pool and library cache latches. This query uses the idea it is common for literal statements to begin "SELECT col1. executing it as required. col3 FROM table WHERE. This results in only the initial parse for each statement (either soft or hard). count(*) .40) HAVING count(*) > 30 ORDER BY 2 .1 . Be assured that it has been proven time and time again that performing this conversion for the most frequently occurring statements can eliminate problems with the shared pool and improve scalability greatly.and shared pool latches may need to be acquired and released. System appears to periodically “hang” after some period of normal operation. Some of the symptoms that may be noticed are: • • System is CPU bound and exhibits an insatiable appetite for CPU. There are several investigations the DBA can use to help confirm that this is indeed happening in the instance. By looking at the V$SQLAREA view it is possible to see which literal statements are good candidates for converting to use bind variables. Eg: Even parsing a simple SQL statement may need to acquire a library cache latch 20 or 30 times. • • Identifying the Problem An Oracle instance suffering from too much literal SQL will likely exhibit some of the symptoms above. Eliminating Literal SQL If you have an existing application it is unlikely that you could eliminate all literal SQL but you should be prepared to eliminate some if it is causing problems. Reducing the load on the Shared Pool Parse Once / Execute Many By far the best approach to use in OLTP type applications is to parse a statement only once and hold the cursor open. Performance Effects Oracle performance can be severely compromised by large volumes of literal SQL. Note: If there is latch contention for the library cache latches the above Statement may cause yet further contention problems. . The best approach to take is that all SQL should be sharable unless it is adhoc or infrequently used SQL where it is important to give CBO as much information as possible in order for it to produce a good execution plan.1.

so a low percentage may indicate a literal SQL or other SQL sharing problem. Use the following query to determine the hit ratios by namespace in the library cache. MEMORY FRAGMENTATION – The primary problem that occurs is that free memory in the shared pool becomes fragmented into small pieces over time.1.sql_text.p2 AND l. name latch FROM v$session_wait w .executions) noparse_ratio FROM (select value hard_parses from v$sysstat where name = 'parse count (hard)' ) A .(select substr(sql_text. When this query selects more than 510% of total sessions there is likely very serious performance degradation taking place and literal SQL may be the culprit. Latch Free Waiters A telltale sign that the instance is suffering library cache and shared pool problems is active latch contention with sessions waiting on the “latch free” wait event. SELECT sid.1.sqltext.hard_parses/B. SELECT S.name IN (‘shared pool’. The “SQL AREA” namespace will be the one affected by literal SQL.’library cache’). Any attempt to allocate a large piece of memory in the shared pool will cause large amount of objects in the library cache to be flushed out and may result in an ORA-4031 out of shared memory error.(select value executions from v$sysstat where name = 'execute count' ) B.g. Finding Literal SQL We can attempt to locate literal SQL in the V$SQL fixed view by grouping and counting statements that are identical up to a certain point based on the observation that most literal SQL becomes textually distinct toward the end of the statement (e.v$latch l WHERE w.latch# = w. DIAGNOSIS i) ORA-4031 ERROR One way to diagnose that this is happening is to look for ORA-4031 errors being returned from applications. SELECT 100 * (1 A. The following query returns SQL statements having more than 10 statements that textually match on leading substring. as can the value 10 used to filter by level of duplication. Literal SQL will always be fully parsed. in the WHERE clause). When an attempt is made to allocate a large contiguous piece of shared memory.Execute Ratio The following query displays the percentage of SQL executed that did not incur an expensive hard parse. SELECT namespace . The SQL*Plus substitution variable &&size can be adjusted to vary the text length used to match statements.&&size) hav ing count(* ) > 10 ) D WHERE substr(S.(100*gethitratio ) hit_ratio FROM v$librarycache. when this ratio is high Oracle is sparing CPU cycles by avoiding expensive parsing and when low there may be a literal SQL problem. . The following query will select all current sessions waiting for either the shared pool or library cache latches. Note that this query is expensive and should not be executed frequently on production systems.event = 'latch free' AND l.Library Cache Hit Ratio The library cache hit ratio should be very high (98%) when SQL is being shared and will remain low regardless of shared pool sizing adjustments when SQL is chronically nonsharable.&&size) = D.sql_text FROM v$sql S . and not Again. event. SQL Parse-to.&&size) sqltext .count(*) from v$sql group by substr(sql_text.1.

The advantage of X$KSMLRU is that it allows you to identify problems with fragmentation that are effecting performance. however. with releases 7. This is only a problem when several hundred users are logged on using distinct user ids. Anything less then 5K should not be a problem. or if users do not report the errors to the DBAs. This error only occurs when there is still not a large enough contiguous piece of free memory after this happens. If this comment is something like 'MPCODE' or 'PLSQL%' then there is a large PL/SQL object being loaded into the shared pool. This fixed table can be used to identify what is causing the large allocation. The object being loaded is the object printed after the 'name='. KSMLRNUM .2/2.enough contiguous memory can be created in the shared pool. function. This is useful when applications do not always report errors signalled by oracle. There may be very large amounts of total free memory in the shared pool.amount of contiguous memory being allocated.ora parameter 'open_cursors' is set too high. If you are running MTS and the comment is something like 'Fixed UGA' then the problem is that the init. and values over 20K are very serious problems. and procedure) into the shared pool does NOT require one contiguous piece of memory in the shared pool. the 64K restriction was lifted.1. the DBA can determine that these errors are occurring. This PL/SQL object will need to be 'kept' in the shared pool.ora parameter can be set so that whenever an ORA-4031 error is signalled a dump will occur into a trace file. Before this error is signalled.number of objects that were flushed from the shared pool in order allocate the memory.The name of the object being loaded into the shared pool if the object is a PL/SQL object or a cursor. loading a library unit (package. By looking for these trace files.hash value of object being loaded KSMLRSES . By looking in the dump for 'Load=X' and then looking up a few lines for 'name=' you can often tell whether an object was being loaded into the shared pool when this error occurred. Values over around 5K start to be a problem.SADDR of the session that loaded the object. If this comment is 'kgltbtab' then the allocation is for a dependency table in the library cache. the database will signal this error. but just not enough contiguous memory. The solution in this case is to use fully qualified names for all table references.3 of Oracle7/PLSQL. each piece being only about 12K in size.allocation comment that describes the type of allocation. Note: The compiled code for a package was split into more than one-piece. If a lot of objects are being periodically flushed from the shared pool then this will cause response time problems and will likely cause library cache latch contention . ii) INIT. KSMLRSIZ . and their memory will be freed and merged. The columns of this fixed table are the following: KSMLRCOM . values over 10K are a serious problem. This problem will not occur in 7. This means that chances of getting ORA4031 is dramatically reduced. Furthermore. but that are not bad enough to be causing ORA-4031 errors to be signalled. If an object was being loaded then it is likely that this load is the cause of the problem and the Object should be 'kept' in the shared pool.ORA PARAMETER An init. packages larger 100K still may have problems compiling. The parameter is the following: Event = "4031 trace name errorstack" This will cause a dump of the oracle state objects to occur when this error is signalled.3 or later. all objects in the shared pool that are not currently pinned or in use will be flushed from the shared pool. KSMLRHON . KSMLROHV . iii) X$KSMLRU There is a fixed table called X$KSMLRU that tracks allocations in the shared pool that cause other objects in the shared pool to be aged out. So.

The means of correcting these errors is to 'keep” large PL/SQL objects in the shared pool at startup time. This is automatically taken care of for precompiler programs and forms programs. 1996 Shared Pool Internals To monitor this fixed table just runs the following: select * from X$KSMLRU where KSMLRSIZ > 5000. and therefore may cause a problem. ACTION i) KEEPING OBJECTS The primary source of problems is large PL/SQL objects. All large packages that are shipped should be 'kept' if the customer uses PL/SQL. Also you should take care that there are not multiple people on one database that select from this table because only one of them will select the real data. This is done since the fixed table stores only the largest allocations that have occurred. but could be a problem for programs that directly use OCI.keep('SYS. This will load the objects into the shared pool and will make sure that the objects are never aged out of the shared pool. For example: select * from emp where empno=1. 30) having count(*) > 3. The statements should be replaced with one statement that uses a bind variable instead of a constant. 30) sql. are not marked ‘kept’. 1. All large customer packages should also be marked 'kept'. execute the following: select name. You can determine what large stored objects are in the shared pool by selecting from the V$DB_OBJECT_CACHE fixed view.sql file. the output of selecting from this table should be carefully noted Since it cannot be reselected if it is forgotten. count(*) copies from v$sqlarea group by substr(sql_text. Volume I.STANDARD'). Should all be replaced with: select * from emp where empno=:1. 'DBMS_STANDARD'. This can be done with the following query: select * from V$DB_OBJECT_CACHE where sharable_mem > 10000. then these will need to be put into packages and marked kept. The bind call in OCI . You can identify statements that potentially fall into this class with a query like the following: select substr(sql_text. This will also tell you which objects have been marked kept. One unusual thing about the X$KSMLRU fixed table is that the contents of the fixed table are erased whenever someone selects from the fixed table. select * from emp where empno=3. One restriction on the 'keep' procedure is that it only works on packages. If the customer has large procedures or large anonymous iii) MAX BIND SIZE It is possible for a sql statement to not be shared because the max bind variable lengths of the bind variables in the statement do not match. Note that this query will not catch PL/SQL objects that are only rarely used and therefore the PL/SQL object is not currently loaded in the shared pool. The values are reset after being selected so that subsequent large allocations can be noted even if they were not quite as large as others that occurred previously. For example: exec dbms_shared_pool. and 'DIUTIL'.Problems when the objects are reloaded into the shared pool. This includes 'STANDARD'. Objects are 'kept' in the shared pool using the dbms_shared_pool package that is defined in the dbmspool. blocks. sharable_mem from V$DB_OBJECT_CACHE where sharable_mem > 10000 and (type = 'PACKAGE' or type = 'PACKAGE BODY' or type = 'FUNCTION' or type = 'PROCEDURE') and kept = 'NO'. Because of this resetting. If the objects are never aged out then there will not be a problem with trying to load them and not having enough memory. select * from emp where empno=2. Technical Reports Compendium. To determine what large PL/SQL objects are currently loaded in the shared pool. 1. ii) USE BIND VARIABLES Another thing that can be done to reduce the amount of fragmentation is to reduce or eliminate the number of SQL statements in the shared pool that are duplicates of each other except for a constant that is embedded in the statement.

command type for anonymous block and length(sql_text) > 500. The packages should be 'kept' in memory. hash number. If the current length is always passed in as the max length instead of the max possible length for the variable.' || to_char(hash). declare /* DONT_KEEP_ME */ addr varchar2(10). instead of using declare x number. and the other is a pointer to the actual length. Large anonymous blocks can be identified with the following query: select sql_text from v$sqlarea where command_type=47 -.keep(addr || '. 'C'). loop fetch anon into addr. hash_value from v$sqlarea where command_type = 47 -. hash. end loop. end. You can then use the following procedure to select these statements out of the shared pool and mark them 'kept' using the dbms_shared_pool. References 1.keep package. one is the max length of the value. begin SUMMARY – Here I try to provide some general information regarding shared pool and some internal information regarding memory structure. cursor anon is select address. end.com . I also try to provide some information related to application user relation to application point of views. "Oracle Internals" Stev Adams 2. Metalink. dbms_shared_pool. iv) ELIMINATING LARGE ANONYMOUS PL/SQL Large anonymous PL/SQL blocks should be turned into small anonymous PL/SQL blocks that call packaged functions. exit when anon%notfound. open anon. end. one can use: declare /* KEEP_ME */ x number. To identify statements that might potentially have this problem execute the following statement: select sql_text. Initialization Parameters The following Oracle initialization parameters have an important impact on library cache and shared pool performance. This includes anonymous PL/SQL blocks that are used for trigger definitions. I hope this information will useful for DBA’s. Another option that can be used when an anonymous block cannot be turned into a package is to mark the anonymous block with some string so that it can be identified in v$sqlarea and marked 'kept'.command type for anonymous block and sql_text like '% KEEP_ME %' and sql_text not like '%DONT_KEEP_ME%'.takes two arguments.oracle. begin x := 5.  _KGL_BUCKET_COUNT                    _KGL_LATCH_COUNT cursor_sharing shared_pool_size shared_pool_reserved_size shared_pool_reserved_min_all oc large_pool_size large_pool_min_alloc parallel_min_message_pool backup_io_slaves temporary_table_locks dml_locks sequence_cache_entries row_cache_cursors max_enabled_roles mts_dispatchers mts_max_dispatchers mts_servers mts_max_servers cursor_space_for_time Note that this query will not catch PL/SQL blocks that are only rarely used and therefore the PL/SQL block is not currently loaded in the shared pool. begin x := 5. version_count from v$sqlarea where version_count > 5. For example. then this could cause the sql statement not to be shared.

. Quest pipeline.3.

Sign up to vote on this title
UsefulNot useful