Oracle package invalidated automatically - oracle

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.

Related

Execute Oracle script with SqlPlus; go to state before script processing if any exceptions

I have a lot of scripts that contain all kinds of transactions including complex DML and DDL.
I need to find a way to run them fully or not at all. I'd like to see following behavior: if any error occurs in the middle of script processing => go back to the state before the script processing.
I thought I would just put whole script into one big transaction, put a savepoint at the beginning and make a rollback to the savepoint in case of any exception, but AFAIK that's impossible, as Oracle does not support nested transactions.
Do you mind sharing your thoughts about that case?
I don't think there is an easy solution for this, because you have DDL in your script. DDL executes commit before processing, so rollback will not help.
As an alternative you could use flashback option of Oracle. But this impacts the entire database. You create a flashback restore point, run the script, if any errors occured then you flashback database to restore point. This will revert all the changes in all the schemas of your database. This is good when you have separate database for running/testing your scripts. It is rather fast. The database should be in archivlog mode.
Another option is to use export/import utility (expdp/impdp). This is also hardly automated in one script, so you do the recovery manually. You take the export dump, run the script, if any errors happened - you restore the dump of your db schemas running impdp.
Perhaps what you need is the "whenever sqlerror exit" clause.
Check it here out

Oracle - Export DDL and Data from Schema in correct order

I need to create a copy of DDL and Data from an Oracle 12cR1 schema.
I can't use the SYS or other High Privileges user.
I can only use SQL DEVELOPER using the schema credentials.
The rights I have are:
Create and alter object privileges within the schema (such as CREATE
TABLE).
Insert, read, update and delete data privileges on the tables
within the schema.
Execute privileges on the stored procedures,
functions and packages within the schema.
I can use Oracle SQL Developer or other third party tool.
I have used the "Database Export" functions, but I ahve found no way to get both the DDL and the INSERT queries in the correct order. Some table have dependencies, so I need to respect a logic order for both DDL and Queries.
In my opinion, you should use a tool which is designed to do such a task, and that's Data Pump (Export & Import). It requires you to acquire privileges on a directory which resides on the database server, and that's something that a privileged (SYS) user creates and grants. If there's a DBA there, ask them to provide it for you.
If there's none, you can still use the Original EXP utility which creates a DMP file on your own computer.
The advantage of the export is that Oracle handles everything that seems to bother you.
If I were you, I wouldn't do it manually, there's really no need to do it that way. Apart from the fact that it is time-consuming, you'll have to take care about foreign key constraints, create slow INSERT INTO statements ... shortly, don't do it. Use (Data Pump) export and import.
You can disable all the constraints and triggers first, then insert the data. After data loaded, enable them all.
You can also try to use PL/SQL Developer to export the objects first. This tool exports objects in dependency order. Then export the data, but not sure it exports the data in dependency, you can try if there are disable constraints/triggers option when export.

temporarily disabling access to a schema in Oracle : lock account vs revoke grant

I have a usecase where I need to block access to all objects in a schema temporarily while I perform some massive changes. I plan to perform the changes as the schema owner. Once I am done I want to enable access back. I am currently exploring two options and would like to know your thoughts as to which one works better :
Lock all accounts that go against the database objects in target schema.
Revoke grants on the database objects and hence preventing external users from using it.
Is there are better way? I want the process to be as smooth as possible and insure that no one is able to get to the target schema while the change is going on
Trigger. This trigger works for everybody except the user with dba role.
CREATE OR REPLACE TRIGGER logon_audit_trigger
AFTER LOGON
ON DATABASE
DECLARE
BEGIN
raise_application_error (-20001, 'You cannot login.');
END;
If you want to know who and where is trying to login. You can get thses information from SYS_CONTEXT.
SELECT SYS_CONTEXT ('USERENV', 'SESSION_USER')
FROM DUAL;
You could consider to quiesce the database. The downsides to locking out users or revoking permissions is that users will receive errors (you don't have access or you can't login, etc...). Quiesceing the database means that active sessions will finish their work, but then will hang until the database is un-quiesced. Then, you perform your modifications and will be guaranteed that nothing can block your exclusive access to the objects you are updating. After your update (or even during your update after you have the lock on the object in question), unquiesce the database.
Of course, the downside to this approach is that this is across the entire database instead of to just one schema. The advantage to this is that your users won't experience any error messages, and if you turn your DML into DDL (as described below) to greatly speed up the downtime window, the majority of your users shouldn't experience much more than a few seconds of inactivity.
There is a good write up on quiesceing the database at Oracle FAQ. You would have to get your DBA's involved to both quiesce the database and to put your changes live as only system or sys can perform this operation.
For DML, you could consider creating a new table with the data that you want before the downtime window starts. Then when the downtime window starts, rename the old table, rename the new table as the old table, recreate the permissions, for a much faster downtime window (since this effectively turns a DML update into DDL). Tom Kyte has a discussion of this approach here.
Also, it goes without saying that proper testing in a testing environment of the above procedures should be done, which will iron out any gotchas in this process and give you a pretty good idea of how long the system will need to be quiesced for.

Liquibase: Custom SQL statement

I have my liquibase schema defined initially for PostreSQL. Now, I have to modify the schema file to support Oracle. I have a change-set that has a <sql> tag. It has a query that accesses the pg_catalog table to set a value to the sequence. However, this will not work for Oracle. If I remove it, the Liquibase complains with check-sum validation fail. It complains even if I have an empty <sql> tag or some other query specified within. Within this change-set, I have many other create-table statement, so I cannot just remove oracle from dbms attribute. Is there any way I can suppress this sql from running for Oracle?
The dbms attribute on the changeset is the mechanism designed to handle this problem..... Sounds like you're trying to do too much within one changesest (but I guess you've figured that out)
The checksum validation failure is liquibase's safety mechanism designed to defend the database against someone tampering with the schema files.
How to fix it is to use the clearChecksums option when running liquibase. It tells liquibase to recompute the checksums for the changesets already in the database. This will enable your postgres database instance to accept the alterations to its changesets that you've made for Oracle.

Is recompiling Oracle Packages safe

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.

Resources