For example, let's say we have the following script to execute in prod.
drop index idx_test1;
drop index idx_test2;
But, after execute first instruction we get the error: ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired. From here I'd like to stop all subsequent instructions. Is there any way to do it in sqlplus and sqldeveloper/PL/SQL Developer?
I would recommend running scripts using Sql*Plus. You would use
WHENEVER SQLERROR EXIT SQL.SQLCODE ROLLBACK
This can be part of your glogin.sql or just as a header of your production script.
This will also send the error code to the calling process for your own logging so if you have some orchestrator, it can know what's happened.
We are trying to schedule hanganalyze automatically if number of sessions are greater than 300 as it is too difficult to monitor database continuously and this issue happens only for a couple of minutes. Could you help us in creating procedure. Also could you confirm that if running this procedure has any impact on performance.
A hang analyze is done via oradebug, so you'd be looking at using SQL Plus to check session counts and then run it if needed, eg store this in a script
spool /tmp/checker.sql
select
case when count(*) > 300 then
'oradebug setorapname reco' ||chr(10)||'oradebug -g all hanganalyze 3'
else
'REM do nothing'
end
from v$session
spool off
#/tmp/checker.sql
and then have a SQL plus session that does:
conn / as sysdba
#script.sql
host sleep 60
#script.sql
host sleep 60
...
...
In a unix machine (solaris), after i entered user oracle like so:
su - oracle
I initiated a program via command line that does the following:
for i in $(seq 1 900); do while true ; do printf "select * from dual;\n" | sqlplus <user>/<password>; done &>/dev/null & done
I closed the terminal and the program keeps running in the background, as expected.
How do i terminate the program if i don't have the program pid?
You can get the PID of that job with $!, write it out into some file and access it there later.
To kill all processes with a command of sqlplus, try:
pkill sqlplus
I am trying the below script to kill all active and inactive oracle sessions for user at once but it doesn't work. The script executes successfully but does not kill sessions for user.
BEGIN
FOR r IN (select sid,serial# from v$session where username = 'USER')
LOOP
EXECUTE IMMEDIATE 'alter system kill session ''' || r.sid
|| ',' || r.serial# || '''';
END LOOP;
END;
The KILL SESSION command doesn't actually kill the session. It merely asks the session to kill itself. In some situations, like waiting for a reply from a remote database or rolling back transactions, the session will not kill itself immediately and will wait for the current operation to complete. In these cases the session will have a status of "marked for kill". It will then be killed as soon as possible.
Check the status to confirm:
SELECT sid, serial#, status, username FROM v$session;
You could also use IMMEDIATE clause:
ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
The IMMEDIATE clause does not affect the work performed by the command, but it returns control back to the current session immediately, rather than waiting for confirmation of the kill. Have a look at Killing Oracle Sessions.
Update If you want to kill all the sessions, you could just prepare a small script.
SELECT 'ALTER SYSTEM KILL SESSION '''||sid||','||serial#||''' IMMEDIATE;' FROM v$session;
Spool the above to a .sql file and execute it, or, copy paste the output and run it.
BEGIN
FOR r IN (select sid,serial# from v$session where username='user')
LOOP
EXECUTE IMMEDIATE 'alter system kill session ''' || r.sid || ','
|| r.serial# || ''' immediate';
END LOOP;
END;
This should work - I just changed your script to add the immediate keyword. As the previous answers pointed out, the kill session only marks the sessions for killing; it does not do so immediately but later when convenient.
From your question, it seemed you are expecting to see the result immediately. So immediate keyword is used to force this.
Execute this script:
SELECT 'ALTER SYSTEM KILL SESSION '''||sid||','||serial#||''' IMMEDIATE;'
FROM v$session
where username='YOUR_USER';
It will printout sqls, which should be executed.
BEGIN
FOR r IN (select sid,serial# from v$session where username='user')
LOOP
EXECUTE IMMEDIATE 'alter system kill session ''' || r.sid || ',' || r.serial# || '''';
END LOOP;
END;
/
It works for me.
For Oracle 11g this may not work as you may receive an error like below
Error report:
SQL Error: ORA-00026: missing or invalid session ID
00026. 00000 - "missing or invalid session ID"
*Cause: Missing or invalid session ID string for ALTER SYSTEM KILL SESSION.
*Action: Retry with a valid session ID.
To rectify this, use below code to identify the sessions
SQL> select inst_id,sid,serial# from gv$session or v$session
NOTE : v$session do not have inst_id field
and Kill them using
alter system kill session 'sid,serial,#inst_id' IMMEDIATE;
inactive session the day before kill
begin
for i in (select * from v$session where status='INACTIVE' and (sysdate-PREV_EXEC_START)>1)
LOOP
EXECUTE IMMEDIATE(q'{ALTER SYSTEM KILL SESSION '}'||i.sid||q'[,]' ||i.serial#||q'[']'||' IMMEDIATE');
END LOOP;
end;
I am getting Oracle maximum processes exceeded error. To increase the the maximum allowed processes I log in as sysdba:
$ sqlplus / as sysdba
I try to see processes parameter:
sql> show parameter processes
ERROR:
ORA-01012: not logged on
I presume that sqlplus is not able to login due to processes being exceeded.
I try to shutdown the instance so that processes will be closed:
SQL> shutdown immediate
ORA-24324: service handle not initialized
ORA-24323: value not allowed
ORA-00020: maximum number of processes (%s) exceeded
I try to kill the Oracle service, that should kill the processes:
$ sudo service oracle-xe restart
[sudo] password for kshitiz:
Shutting down Oracle Database 10g Express Edition Instance.
Stopping Oracle Net Listener.
Starting Oracle Database 10g Express Edition Instance.
I login as sysdba again but it gives the same error.
How do I kill the processes so that the database is manageable again? And how should I diagnose why this error is occuring (which application is responsible for hogging the database)?
I am on Oracle 10g express and Ubuntu 13.10.
The solution is to increase the max number of processes allowed. But the problem is that in this state there is no way to do that since DB wouldn't take any commands. Even the commands to increment the process parameter would give the maximum processes exceeded error.
Kill all processes belonging to oracle user:
$ sudo su
$ su oracle
$ kill -9 -1
Check that all process are killed:
$ ps -ef | grep oracle
If not kill them using kill -9 PID. Now connect to database as sysdba:
$ su oracle
$ sqlplus / as sysdba
Shutdown the database (1. Shutdown immediate would probably not work and give same ORA-01012 error. 2. Since the processes are killed isn't the database already shutdown? That's what I thought but it seems that it keeps a record of the last state or something which isn't clear out until you run the following command):
SQL> shutdown abort
Now bring it up again:
SQL> startup
Modify the processes parameter to prevent this problem from recurring:
SQL> select count(*) from v$process;
SQL> alter system set processes=300 scope=spfile;
Restart database:
SQL> shutdown immediate
SQL> startup
Check that max processes have increased:
SQL> show parameter processes
Edit:
After all of this for some strange reason my application wasn't connecting to DB, though SQL plus was working just fine. So as a last step I restarted the oracle service:
$ sudo service oracle-xe restart
This got everything working for me.