| Lesson 3 ||Pinning Packages in the Shared Pool Library Cache |
| Objective || Pin packages into the shared pool. |
Pinning Packages in the Shared Pool Librry Cache in Oracle
Pinning Memory Objects
The concept of memory fencing and pinning objects into memory has been around since the 1960's. Any time a piece of data or program is used frequently, the database should have the ability to make that object ineligible for a page-out. IBM first introduced this concept with the introduction of the MVS operating system, but now has extended it to work with databases such as Oracle. The idea is that any PL/SQL, SQL, or data blocks that are frequently referenced by the application should be given special status, so that it will always remain in memory when needed. The trick, of course, is to identify what SQL or data should be kept in memory at the expense of other items in the shared pool or data buffer. That is the real challenge of Oracle tuning.
In all of the guidelines stated so far it has been mentioned that the memory is usually allocated above and beyond that needed for
- fixed size areas and
- pinned objects.
How do you determine what to pin? Generally speaking any package, procedure, function or cursor that is frequently used by your application should be pinned into the shared pool when the database is started. I suggest adding a null startup function
to every in house generated package. It looks like the following piece of code.
FUNCTION start_up RETURN number IS
null startup function
The purpose of the null startup function is to provide a touch point to pull the entire package into the shared pool.
This allows you to create a startup SQL procedure that pulls all of the application packages into the pool and pins them using the DBMS_SHARED_POOL package.
The DBMS_SHARED_POOL package may have to be built in earlier releases of Oracle.
The DBMS_SHARED_POOL package is built using the DBMSPOOL.SQL and PRVTPOOL.PLB scripts located in (UNIX) $ORACLE_HOME/rdbms/admin or (NT)
(where x: is the home drive for your install).
Pinning or Memory Fencing
Pinning (or memory fencing) is a procedure that tells a database that after the package is initially loaded into the shared pool,
the package must always remain in memory. In order to pin a package, it must be marked as "unswappable."
Oracle provides a procedure called dbms_shared_pool.keep to pin a package, and packages can be unpinned with dbms_shared_pool.unkeep. Only packages can be pinned. Stored procedures cannot be pinned unless they are placed into a package.
Pin Package in Memory
The choice of whether to pin a package in memory is a function of the size of the object and the frequency of its use.
Very large packages that are called frequently might benefit from pinning, but any difference might go unnoticed because the frequent calls to the procedure have kept it loaded into memory anyway. Therefore, because the object never pages out in the first place, pinning has no effect.
Also, the way procedures are grouped into packages can have some influence.
Some Oracle DBAs identify High-impact Procedures
and group them into a single package, and then pin this package in the shared pool library cache.
I highly recommend that you store all SQL in packages if you have enough shared_pool memory. Storing SQL in packages has several benefits. It ensures that all SQL is uniform and reusable, and it makes it possible to pin the SQL packages.
UNIX users might want to add code to their database startup script to ensure that the packages are re-pinned after each database startup,
guaranteeing that all packages are re-pinned with each bounce of the box. A script might look like this:
su oracle -c "/usr/oracle/bin/svrmgrl /<<!
Running pin.sql when restarting
As a database administrator, you also need to remember to run pin.sql whenever restarting a database. This is done by reissuing the PIN command from inside SQL*DBA immediately after the database has been restarted.
Locating and pinning large stored objects
If you have large procedures or large anonymous PL/SQL blocks in your application, you may also want to put these into packages and pin them in the shared pool. You can determine what large stored objects are in the shared pool by selecting from the V$DB_OBJECT_CACHE fixed view. This will also tell you which objects have been marked kept. This can be done with the following query:
select * from V$db_object_cache
where sharable_mem > 10000;
If you have plenty of free memory in the shared pool and you wish to mark all packages in the system "kept," you can execute the following PL/SQL snippet:
cursor pkgs is
object_type = 'PACKAGE';
begin open pkgs;
loop fetch pkgs into own, nam;
exit when pkgs%notfound;
dbms_shared_pool.keep(own || '.' || nam, 'P');
In the next lesson, we will look at tuning the shared pool reserved size.