Oracle DBA Tips Corner |
|
Native Compiled PL/SQL
by Jeff Hunter, Sr. Database Administrator
Contents
Introduction
As a performance enhancement, Oracle9i provides the capability to natively compile
PL/SQL code into shared libraries. These shared libraries are then loaded and
executed whenever the corresponding PL/SQL program unit is invoked at runtime.
Native compilation of PL/SQL, once it has been properly configured, is transparent
to both the user compiling a PL/SQL program unit and to the end user invoking that
same PL/SQL program unit.
Oracle9i generates C code corresponding to the PL/SQL code and then compiles
and links the resulting C code into shared libraries using the compiler and
linker for that platform. Therefore, a C compiler must be installed on the
same host for native compilation to work.
You can compile both the packages supplied by Oracle and the procedures
or packages that you custom develop. Oracle supplied packages are statically
linked, and procedures or packages you develop are dynamically linked to
the process running the Oracle executable.
The initialization parameters that are used to configure PL/SQL native compilation
are described next.
Initialization Parameters Related to PL/SQL Native Compilation
Possible values are:
Defaults are: 'INTERPRETED','NON_DEBUG'
Examples:
Disallowed combinations:
This parameter affects ONLY those PL/SQL program units explicitly
compiled AFTER the parameter is set.
This parameter is settable only at the system level.
This parameter is mandatory if
This parameter should be set to the full pathname of the makefile
provided with Oracle9i for this purpose. The provided makefile is
called
Since
Examples:
This parameter is settable only at the system level.
This parameter is mandatory if
This parameter should be set to the full pathname of the '
Since the location of the
Examples:
Solaris
This parameter is settable only at the system level.
This parameter is mandatory if
This parameter should be set to the full pathname of the directory
where the shared libraries are to be stored. The 'oracle' user must
have write permissions on this directory or native compilation will
fail. Other users' access to the directory should be restricted; in
particular, no user other than 'oracle' or 'root' should be allowed
to delete files from this directory.
The directory is assumed to have already been created by the DBA.
Oracle will not create the directory for you.
There is no default value; this parameter must be set explicitly.
Examples:
Example (
Examples (
Rationale:
By setting this parameter to some value N, you are asking that Oracle
distribute the generated shared libraries across the N subdirectories
of
Setting this parameter is recommended if the number of PL/SQL program
units to be natively compiled exceeds 10,000.
This parameter is optional; the default value is 0 (zero) so all shared
libraries are by default stored directly in plsql_native_library_dir.
An Example PL/SQL Native Compilation Session
(In most cases, no modifications will need to be made to this
file. All directories should be correct as a result of the
install.)
From SQL*Plus, you can use the following command to ensure all values have been
properly set:
(Keep in mind
that the
Why is the Execution of Native Code Much Faster?
Source: OCP Oracle9i Database: New Features for Administrators Exam Guide (Exam 1Z0-030), Daniel Benjamin
Verifying that a Procedure is being Executed Natively in Solaris
Use pmap to see all of the memory segments (including shared libraries)
that are currently attached to this process. You will see FILL_EMP__SCOTT__0.so
listed among the libraries displayed by the pmap utility.
Dependencies, Invalidation and Revalidation
The stored settings are ONLY used when recompiling as part of
revalidation. Any time a PL/SQL module is explicitly compiled via
'
Although natively compiled PL/SQL program units are obviously
dependent on their implementation shared libraries, the database
is unable to track such dependencies (since the libraries, which
reside on the file system, can be manipulated directly via OS
commands). For example, attempting to execute a PL/SQL program
unit whose shared library has been deleted results in error.
Since the removal of the library is undetectable to Oracle until the
module is executed, the program unit is not marked INVALID; therefore,
there is no implicit revalidation (and recompilation). To recreate
the missing library, you must explicitly recompile it or recreate
it from source.
On a related note, shared libararies corresponding to a PL/SQL program
unit are not automatically deleted when the program unit is dropped;
these files must be manually removed when they are no longer needed.
All articles, scripts and material located at the Internet address of http://www.idevelopment.info is the copyright of Jeffrey M. Hunter
and is protected under copyright laws of the United States. This document may not be hosted on any other site without my express,
prior, written permission. Application to host any of the material elsewhere can be made by contacting me at jhunter@idevelopment.info.
I have made every effort and taken great care in making sure that the material included on my web site is technically accurate,
but I disclaim any and all responsibility for any loss, damage or destruction of data or any other property which may arise from
relying on it. I will in no case be liable for any monetary damages arising from such loss, damage or destruction.
In versions prior to Oracle9i, all PL/SQL stored program units are compiled to P-code.
The resulting P-code is stored in the database and interpreted at runtime.
While this results in a very portable solution, it does have some performance
consequences; interpreted languages are usually slower than natively compiled languages.
plsql_compiler_flags
Determines whether PL/SQL code is compiled native or interpreted
and determines whether debug information is included.
This parameter is settable at both the system and session levels.
plsql_native_make_file_name
Determines the full path to the makefile used to create the shared
libraries that contain the natively compiled PL/SQL code.
plsql_compiler_flags = 'NATIVE'.
spnc_makefile.mk and resides in
$ORACLE_HOME/plsql.
$ORACLE_HOME can vary from one installation
to another, this parameter does not have any default; it must be
set explicitly.
ALTER SYSTEM SET plsql_native_make_file_name = '/u01/app/oracle/product/9.2.0/plsql/spnc_makefile.mk';
plsql_native_make_utility
Determines the full path to the make utility used to process the
makefile specified via
plsql_native_make_file_name.
plsql_compiler_flags = 'NATIVE'.
make'
utility on your machine. If the PATH environment variable is set
appropriately, you may find that providing just the name of the
make utility will work; however, it is highly recommended that
the full pathname be provided to avoid potential problems.
make utility can vary from one
machine to another, this parameter does not have any default; it must
be set explicitly.
ALTER SYSTEM SET plsql_native_make_utility='/usr/ccs/bin/make';
Linux
ALTER SYSTEM SET plsql_native_make_utility='/usr/bin/make';
plsql_native_library_dir
Determines the directory name used to store the shared libraries
that contain the natively compiled PL/SQL code.
plsql_compiler_flags = 'NATIVE'.
ALTER SYSTEM SET plsql_native_library_dir = '/u01/app/oracle/product/9.2.0/plsql_libs';
plsql_native_c_compiler
This parameter should NOT be set with an alter system command,
in
init.ora or the stored parameter file (SPFILE).
The provided makefile should be modified to include
the appropriate default location for the C compiler.
spnc_makefile.mk):
# Specify C Compiler
#
CC=/opt/SUNWspro/bin/cc
plsql_native_linker
This parameter should NOT be set with an alter system command,
in
init.ora or in the stored parameter file (SPFILE).
The provided makefile should be modified to include the appropriate default
location for the linker.
spnc_makefile.mk):
# Specify Linker
#
LD=/usr/ccs/bin/ld
plsql_native_library_subdir_count
Determines the number of subdirectories to be created in the directory
specified by
the plsql_native_library_dir parameter.
Performance of certain file operations can be adversely affected if
the number of files in a directory grows very large. In cases where
many PL/SQL program units are natively compiled, each corresponding
to a shared library in plsql_native_library_dir, the number of files
in this directory can become unacceptably large.
This parameter is settable only at the system level.
plsql_native_library_dir. The names of these subdirectories are of
the form 'dn' where n is the zero-based directory number.
To compile procedures and packages, you must perform the following steps:
$ORACLE_HOME/plsql to reflect the appropriate paths:
INTERPRETED value for the
PLSQL_COMPILER_FLAGS initialization parameter
with the NATIVE value. You can perform this
by modifying the entry in the initialization parameter file,
or you can use ALTER SESSION or ALTER SYSTEM
to dynamically alter the PLSQL_COMPILER_FLAGS
parameter, as shown below:
SQL> SELECT name, value FROM v$parameter where name = 'plsql_compiler_flags';
NAME VALUE
--------------------- ---------------
plsql_compiler_flags INTERPRETED
SQL> ALTER SYSTEM SET PLSQL_COMPILER_FLAGS = NATIVE;
SQL> SELECT name, value FROM v$parameter where name = 'plsql_compiler_flags';
NAME VALUE
--------------------- ---------------
plsql_compiler_flags NATIVE
plsql_% instance parameters. The the section above,
Initialization Parameters Related to PL/SQL Native Compilation
In general, here is a list of the parameters you will need to change:
plsql_compiler_flags
plsql_native_make_file_name
plsql_native_make_utility
plsql_native_library_dir
SQL> show parameters plsql
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
plsql_compiler_flags string NATIVE
plsql_native_c_compiler string
plsql_native_library_dir string /u01/app/oracle/product/9.2.0/plsql_libs
plsql_native_library_subdir_count integer 0
plsql_native_linker string
plsql_native_make_file_name string /u01/app/oracle/product/9.2.0/plsql/spnc_makefile.mk
plsql_native_make_utility string /usr/bin/make
plsql_v2_compatibility boolean FALSE
CREATE OR REPLACE PROCEDURE to compile the procedure.
ALTER PROCEDURE command to compile the procedure.
ALTER PACKAGE command to compile the entire package.
DROP PROCEDURE to drop the procedure and then create
it again with the CREATE procedure to compile the procedure.
PLSQL_COMPILER_FLAGS initialization
parameter set to NATIVE to compile ALL the Oracle-supplied
packages. Oracle does this by starting the UTLIRP script in:
$ORACLE_HOME/rdbms/admin/utlirp.sql.
utlirp.sql script can be used to invalidate
and then recompile all PL/SQL modules (procedures, functions, packages,
types, triggers, views) in a database.)
NATIVE compiled
by querying the USER_STORED_SETTINGS data dictionary view:
SELECT object_name, param_value
FROM user_stored_settings
WHERE object_name = 'FILL_EMP'
AND param_name = 'plsql_compiler_flags';
OBJECT_NAME PARAM_VALUE
--------------- ------------------------
FILL_EMP NATIVE,NON_DEBUG
NOTE:
If the procedure FILL_EMP is not
compiled for native execution, it will
contain INTERPRETED within the param_value
column.
Besides the standard degradation in performance to parse interpreted code,
the execution of native code is much faster because of the following:
On Solaris, one can verify that the procedure is being
executed natively by using 'pmap' to view the libraries
loaded by the oracle executable. Use the following methods:
SQL> !ls -l /u01/app/oracle/product/9.2.0/plsql_libs
total 28
-rwxr-xr-x 1 oracle dba 12081 Mar 19 16:53 FILL_EMP__SCOTT__0.so
-rwxr-xr-x 1 oracle dba 2115 Mar 19 16:53 RANDOM__SCOTT__2.so
-rwxr-xr-x 1 oracle dba 9463 Mar 19 16:53 RANDOM__SCOTT__3.so
Note that the shared library name (in this case, on Solaris) is
constructed from the procedure, function or package name and the
schema name.
SQL> !ps
PID TTY TIME CMD
21595 pts/4 00:00:00 ksh
21625 pts/4 00:00:00 sqlplus
22982 pts/4 00:00:00 ksh
22983 pts/4 00:00:00 ps
Find the process id of the oracle process:
(Note: this assumes you connected via bequeath;
otherwise the oracle process won't be a child of
sqlplus)
SQL> !ps -ef | grep 21625
oracle 21627 21625 0 17:38 pts/4 00:00:00 oracleCUSTDB (DESCRIPTION=(LOCAL
oracle 23178 21625 0 18:14 pts/4 00:00:00 /bin/ksh -c ps -ef | grep LOCAL
oracle 23180 23178 0 18:14 pts/4 00:00:00 grep 21625
SQL> !/usr/proc/bin/pmap 21627 | more
/* partial listing of output */
EF44C000 8K read/write/exec [ anon ]
EF460000 56K read/exec /usr/lib/libresolv.so.2
EF47C000 8K read/write/exec /usr/lib/libresolv.so.2
EF47E000 16K read/write/exec [ anon ]
EF490000 40K read/exec /usr/ucblib/libucb.so.1
EF4A8000 8K read/write/exec /usr/ucblib/libucb.so.1
EF4B0000 8K read/exec /lang/product/9.0.1/plsqllib/FILL_EMP__SCOTT__0.so
EF4C0000 8K read/write/exec /lang/product/9.0.1/plsqllib/FILL_EMP__SCOTT__0.so
NOTE: It may be possible to perform a similar
test on other platforms besides Solaris, but the tools required will likely
differ. For example, Linux uses a utility called strace that is
very similar to pmap.
See your platform documentation for how to do this on your operating system platform.
Dependencies between database objects are handled in the same manner
as in previous Oracle versions. If an object upon which some natively
compiled PL/SQL program unit depends changes, the PL/SQL module is
invalidated. The next time the same PL/SQL program unit is executed,
an attempt is made to revalidate (recompile) the module. Any time a
module is recompiled as part of revalidation, it is compiled using
its stored setting (i.e. the setting in force the last time the
module was explicitly compiled and appearing in the
USER/ALL/DBA_STORED_SETTINGS data dictionary views).
create or replace' or 'alter ... compile',
the current setting for the session is used.
$ rm /u01/app/oracle/product/9.2.0/plsql_libs/FILL_EMP__SCOTT__0.so
$ sqlplus scott/tiger
SQL> execute fill_emp(100);
*
ERROR at line 1:
ORA-06549: PL/SQL: failed to dynamically open shared object (DLL):
/u01/app/oracle/product/9.2.0/plsql_libs/FILL_EMP__SCOTT__0.so: cannot open
shared object file: No such file or directory
SQL> ALTER SESSION SET plsql_compiler_flags='NATIVE';
Session altered.
SQL> ALTER PROCEDURE fill_emp COMPILE;
Procedure altered.
SQL> exit
$ ls -l /u01/app/oracle/product/9.2.0/plsql_libs
-rwxr-xr-x 1 oracle dba 12081 Mar 19 18:39 FILL_EMP__SCOTT__0.so*
Friday, 20-Jan-2006 16:47:48 EST
Page Count: 22537