Is recompiling Oracle Packages safe - oracle

Hi
We have a third party oracle based application, that ships with precompiled binary(wrapped) packages.
But when I compile them in Oracle SQL Developer (right click -> compile all), they get invalidated.
Is recompiling a safe operation with no side effects?

The major side effect is that if you compile a package which another package is dependant upon you risk invalidating the dependant package for any existing sessions - even if the compile has no errors. This is fine for applications where sessions are short-lived but for applications where sessions are long-lived this is a problem. If you're using connection pools in JDBC the cached sessions will be long lived and likely invalidated. You have to flush the cached sessions to avoid the error.
The error you're looking for is "ORA-04068: existing state of packages has been discarded".
See here for more info.
Specifically with regards to SQL Developer - it does not handle recompilation of wrapped packages well. If you are going to recompile them try another tool like TOAD or PL/SQL Developer or use the "alter package" command in the SQL Plus command line.

Personally, I'd avoid 'Recompile All' (in SQL Developer or TOAD) - especially in any environment where you have open database connections from other users or software.
In most situations you probably just want to recompile Invalid objects.
If you're on Oracle 10 or above, there are two in-built packages that will do this (although they may not be accessible to your role without speaking to your DBA).
UTL_RECOMP.RECOMP_PARALLEL(threads => 4, schema => :schema_owner)
DBMS_UTILITY.COMPILE_SCHEMA(schema => :schema_owner, compile_all => FALSE)
UTL_RECOMP is the new preferred way to do it. DBMS_UTILITY exists on earlier versions of Oracle, but would always compile everything - compile_all is a new optional flag, that lets us tell it to compile only invalid items.
If you are on an earlier version than 10, I'd suggest rolling your own compile invalid procedure - I found it useful to write this as a job that can be submitted via DBMS_JOB and then emails back progress via DBMS_SMTP (DBMS_MAIL in Ora 10).
My job recursively tries to compile INVALID objects where all dependencies are VALID, using the following SQL, until there are no changes between iterations.
SELECT uo.object_name,uo.object_type
FROM user_objects uo
WHERE uo.status = 'INVALID'
MINUS -- objects with invalid children
SELECT uo.object_name,uo.object_type
FROM user_objects uo,
user_objects uo2,
public_dependency pd
WHERE uo.status = 'INVALID'
AND uo.object_id = pd.object_id
AND pd.referenced_object_id = uo2.object_id
AND uo2.status = 'INVALID'

Most third party applications advice you against editing/compiling their objects unless of course their support tells you to do so.
Since you do not know all the dependent objects, I would suggest you contact the third-part application's support team first before modifying their objects. If it is a bundled application, simply recompiling oracle objects may leave dependent applications/services in other tiers invalid.

If your packages get invalid are they actually invalid in the sense that they won't work anymore?
Try to recompile an invalid package body using sqlplus.
SQL>alter package <package name> compile body;
If you get the message "compiled with errors"
SQL>show errors;
This will give some information about the error.
Generally speaking it is fine to recompile wrapped packages. Should not be a problem.

Related

Oracle package invalidated automatically

We have a oracle 12.1 Prod database. One of the packages in the database become invalid abruptly and all the sessions have the state of that package has been invalidated. We are sure that there was no manual actions (Deployment, DDL, Compile etc.. ) performed on the database. Is there any other way that package can become invalid automatically?
This package is directly referencing 3 remote database tables using DB link.
If any dependency undergoes a DDL operation, it will invalidate stored PL/SQL programs that depend on it. It could be a table, a synonym, a view, another PL/SQL routine, etc.. I suggest you look at dba_dependencies to see what the dependencies are for your package, then look at dba_objects for every one of those objects to see what has a recent last_ddl_time value. Don't forget the remote objects on the other side of that database link. When you find it, you are well on your way to finding the root cause. If you can't figure out what DDL is hitting that object, enable DDL auditing so you can capture the event the next time it happens.
If you find that the offending object cannot avoid undergoing DDL for some reason, then you may need to consider breaking the dependency on it by embedding your reference to it inside an EXECUTE IMMEDIATE.

What are the main causes for a package to have a much slower execution time for all users except the schema owner?

Any advice or knowledge is appreciated I'm pretty new to databases.
I have a oracle package that executes at an acceptable rate by the schema owner however when I grant a role to any other user which has access to the package it is extremely slow.
What are the best methods to trouble shoot would the package be the problem or could this be an issue with how oracle verifies security for the package execution.
The package has essentially got looped select statements and is inserting data using another package.
Many Thanks
Does the package run as the owner or as the current user? What is the full version of Oracle?
If the package runs as the current user then the code could be finding different versions of the objects.
If the code runs as the owner but the users have different session parameter settings, several of which effect the CBO plans, then different query plans could be in use.
Run sql trace on an execution by the owner and by a user and compare the results.
You have option to [PIN] package code into database memory pool and increase performance.

What is EXTPROC in Oracle?

For security reasons I asked DB team to add EXTPROC_DLLS:ONLY; but they said this:
"Please be informed that the KEY = EXTPROC1526 doesn’t refer to any
external process at all. This is just a key used by any process needs
to call Oraxxx via IPC protocol. The key can be any value and the same
key value should be passed via the tnsnames.ora"
To me, it seems wrong. Could you please help me on this? What is the exact use of EXTPROC and what happens if we don't add EXTPROC_DLLS:ONLY?
For any program to connect the oracle database you need Extproc agent.
PLS/SQL for example needs Extproc to work with oracle
You can find more information about the securit here
Ill past some of the link
Description
***********
The Oracle database server supports PL/SQL, a programming language. PL/SQ can execute external procedures via extproc. Over the past few years there has been a number of vulnerabilities in this area.
Extproc is intended only to accept requests from the Oracle database server but local users can still execute commands bypassing this restriction.
Details
*******
No authentication takes place when extproc is asked to load a library and execute a function. This allows local users to run commands as the Oracle user (Oracle on unix and system on Windows). If configured properly, under 10g, extproc runs as nobody on *nix systems so the risk posed here is minimal but still present.
and an example here
On contrary to other databases Oracle does NOT allow plugins to access it's own memory address space. In case of MySQL/PostgreSQL a .dll plugin (C stored procedure) is loaded by the main database process.
Oracle lets listener to spawn a new process by calling extproc (or extproc32). This process loads the shared library and the rest of the database talks to this process via IPC.
This approach is safer, because the external library can not crash the database nor corrupt data. On the other hand sometimes C stored procedures might be slower than Java ones.
This option can restrict path for .dlls being loaded by extproc. i.e. those created by CREATE LIBRARY statement.
PS: usage of C stored procedures is VERY rare, if you do not use them you can freely remove the whole extproc stanza from listener.ora.
PS1: there is possible scenario of exploiting the extproc feature.
User must have CREATE LIBRARY, which usually NOT granted
extproc is not configured to run with nobody's privs - but runs as oracle:dba
User creates malicious .so library, which will performs something "evil" during it's initialization.
User puts this lib into /tmp directory
User creates Oracle LIBRARY pointing into /tmp by using CREATE LIBRARY statement
User forces extproc to dlopen this library
exproc will execute evil code with OS privileges oracle:dba
When using this EXTPROC_DLLS:ONLY restriction, developers have to cooperate with DBAs, and only white-listed libraries can be used and loaded.

First call to a stored procedure, after successful compilation, fails. Oracle 10g

I have an Oracle 10G installation (Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Prod), and a java web app that calls stored procedures and functions in oracle via a JDBC connection. The SP's and functions are part of a package. The first time a SP or a function is called, after the package is successfully compiled, I get these errors:
(I replaced our schema name and package name with "#schema-name#.#package-name#")
ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package body "#schema-name#.#package-name#" has been invalidated
ORA-04065: not executed, altered or dropped package body "#schema-name#.#package-name#"
ORA-06508: PL/SQL: could not find program unit being called: "#schema-name#.#package-name#"
ORA-06512: at "#schema-name#.#package-name#", line 5393
ORA-06512: at line 1
The very next time it is called, everything runs the way that it should. Any ideas on why and how to keep this from happening?
This is normal behavior for packages that have state, i.e. they have body variables. When the package is compiled, the existing state has to be discared and all session that have used the package before receive the ORA-04068 error (except the one that compiled the package).
As you have a web application, I assume it uses a connection pool that keeps the session alive. So they will all be affected if they have used the package before.
One workaround is to call DBMS_SESSION.RESET_PACKAGE, which discards the state of all packages of the current session. Another one is to check whether you can get rid of the session state, which is somewhat problematic in combination with a connection pool.
I don't think there's any way around this without dropping and recreating your session..
Have a look at this

Invalid privilege error?

Two related applications use a function in a package in several queries to return some data as CSV. The column being selected and concatenated is a CLOB field and can contain HTML, special characters, etc. The applications have few users and so are not heavily used. One is a Flex application that consumes Oracle HTTP services, and the other is an ASP.NET application that uses ODP.NET. The applications are really one integrated application with hyperlinks to each other.
Yesterday, I received several notifications of a strange error:
ORA-01031: insufficient privileges ORA-06512
The line number in the package in the error details indicates that the error was caused by the function being used in the select clause. It would occur when called by either application about 75% of the time.
Am I correct that an ORA-06512 occurred in the function that then caused an ORA-01031 insufficient privilege error? Unfortunately, ORA-06512 is a very generic error and doesn't tell me anything. And why would it cause an invalid privilege error? The Oracle user accounts being used by both applications have the execute privilege on the package that contains the function.
Regarding the function... it has been used for about 2 years in production without any issue. Also, when I imported the data to QA yesterday and tested it, no error would occur, no matter how many times I hammered the server with requests. But in production, the error would occur about 75% of the time with exactly the same parameters.
The DBA tried to help me with a trace, but we could not find the error message in the trace files.
Today, everything is back to normal in production. Even if I hammer the server with requests the error will stubbornly refuse to occur.
What caused this very strange behaviour yesterday? Do any of the gurus here have any ideas?
EDIT: I just realized one important detail. The column in the table that is being selected and concatenated into CSV by the function is a CLOB.
If the client applications were running "SELECT clob_to_csv(clob_col) FROM ..." and it returned an invalid privilege SOMETIMES, then it is probably something the function is trying to do, rather than the select statement not having sufficient privilege to execute the function.
Not quite clear on what it might do that may require a privilege. Does it use a file (UTL_FILE) or network connection / web service ?
Could be some sort of odd data (a very large clob perhaps).

Resources