Ошибка ora 00028

Сеанс – это специфическое соединение пользователя к экземпляру Oracle через пользовательский процесс. При работе с выделенным сервером для каждого такого сеанса создается отдельный серверный процесс. Обмен пользователя с экземпляром базы данных происходит через пользовательский процесс на клиентской машине, который в свою очередь через драйвер клиента Oracle Net работает с выделенным серверным процессом, взаимодействующим непосредственно с самим экземпляром Oracle. Иногда возникают ситуации, когда требуется уничтожить какие либо сеансы. Такое обычно такое происходит, когда требуется прервать долго выполняющийся сеанс или возникает необходимость в проведении административных работ с отключением всех сеансов. Так же может понадобиться и просто откатить незафиксированную транзакцию, если за данным сеансом выстроилась большая очередь. Бывают и так называемые “потерянные сеансы”, нуждающиеся в уничтожении. В этой главе мы научимся идентифицировать такие сеансы, уничтожать их, а так же рассмотрим сложности, возникающие при этом процессе.

Идентифицируем сеанс

Процесс уничтожения сеанса заключается в откате всех незафиксированных транзакций сеанса, освобождении используемых им ресурсов и уничтожении серверного процесса. Выполняется эта операция с помощью SQL команды ALTER SYSTEM KILL SESSION ‘sid,serial#’. Чтобы выполнить эту команду, нам необходимо знать идентификатор sid и порядковый номер serial# сеанса. Для этого нам необходимо обратится к системным представлениям v$session и v$process с целью поиска записи параметров конкретного сеанса. Но прежде мы вкратце ознакомимся с данными системными представлениями. Первое из них v$session показывает все установленные сеансы экземпляра Oracle. Второе v$process отображает соответствующие им выделенные серверные процессы. Оба этих представления основаны на так называемых x$ таблицах: x$ksuse и x$ksupr. Если мы сделаем запрос к этим таблицам, то обнаружим, что количество строк в этих таблицах соответствует параметрам инициализации sessions и processes, и не совпадает с количеством строк отображаемых представлениями v$session и v$process.

Подключение: SYS@XE AS SYSDBA
Oracle Database 10g Express Edition Release 10.2.0.1.0 – Production

SQL> SELECT 'x$ksuse' "X$TABLES", count(*) FROM x$ksuse union SELECT 
'x$ksupr',count(*) FROM x$ksup;
 
X$TABLES COUNT(*)
-------- --------
x$ksupr  40      
x$ksuse  49  

SQL> SELECT name, value FROM v$parameter WHERE name IN 
('processes','sessions');
 
NAME      VALUE
--------- -----
processes 40   
sessions  49   

SQL> SELECT 'v$session' "VIEW", count(*) FROM v$session union SELECT 
'v$process',count(*) FROM v$process;
 
VIEW      COUNT(*)
--------- --------
v$process 22      
v$session 16      

Так как x$ таблицы, по сути, являются наборами определённых структур в памяти SGA, то можно предположить, что память под структуры хранящие информацию о сеансах и серверных процессах выделяется заранее и их количество всегда равно значениям параметров инициализации session и process. Рассмотрим более подробно некоторые поля этих двух x$ таблиц. Одна из таблиц x$ksuse, хранит информацию о сеансах экземпляра Oracle и первое, интересующее нас в ней поле indx, обозначает идентификатор сеанса. Оно имеет сквозную нумерацию от 1 до значения параметра sessions и в представлении v$session соответствует полю sid. Значение в этом столбце практически указывает на номер записи в таблице x$ksuse и следовательно может быть повторно использовано после того как данный сеанс закончит работу. Второе поле ksuseser – это порядковый номер сеанса. В представлении v$session данное поле соответствует полю serial# и имеет уникальное неповторяющееся значение для каждого сеанса. Третье поле, которое мы рассмотрим это поле ksusepro – адрес структуры памяти серверного процесса, которому принадлежит данный сеанс. В представлении v$session оно отражается как поле paddr. В дополнении к таблице x$ksuse мы так же рассмотрим структуру таблицы x$ksupr, которая определяет выделенные серверные процессы Oracle. Здесь нас будут интересовать два поля. Это поле addr — адрес структуры памяти выделенного серверного процесса. В представлении v$process он имеет такое же название. И второе поле это ksuprpid – идентификатор процесса операционной системы. В представлении v$process поле spid. И так мы ознакомились с представлениями и параметрами идентифицирующими сеанс. Теперь в качестве примера попробуем получить sid и serial# сеанса предварительно созданного нами пользователя AH. Для этого выполним следующий запрос, соединив два представления v$session и v$process по полям addr и paddr:

SQL> SELECT sid, s.serial#, s.status, p.spid FROM v$session s, v$process p 
WHERE s.username = 'AH' AND paddr = addr(+)
 
SID SERIAL# STATUS   SPID
--- ------- -------- ----
22  11      INACTIVE 1568 

Параметры получены. Теперь можно приступить к уничтожению сеанса.

Уничтожаем неактивный сеанс

Выполним команду ALTER SYSTEM KILL SESSION для указанного выше сеанса:

SQL> ALTER SYSTEM KILL SESSION '22,11' 

System altered 

Посмотрим состояние сеанса:

SQL> SELECT sid,s.serial#,s.status,p.spid FROM v$session s, v$process p WHERE 
s.username = 'AH' AND paddr = addr(+)
 
SID SERIAL# STATUS SPID
--- ------- ------ ----
22  11      KILLED

Если сеанс неактивный и не содержит незавершенных транзакций, то он помечается со статусом KILLED . Поле PADDR уже не указывает на адрес структуры выделенного серверного процесса. Но серверный процесс не освобождается:

SQL> SELECT addr, pid, spid FROM v$process WHERE spid = 1568
 
ADDR     PID SPID
-------- --- ----
2A136324 21  1568

Такое состояние будет продолжаться до тех пор, пока пользователь снова попытается использовать сеанс или отключиться от сервера. В первом случае пользователю выдается сообщение об ошибке ORA-00028:

SQL> SELECT sysdate FROM dual
 
SELECT sysdate FROM dual
*
Ошибка в строке 1:
ORA-00028: your session has been killed 

Информация при этом о сеансе из представления v$session исчезает:

SQL> SELECT sid, s.serial#, s.status, p.spid FROM v$session s, v$process p 
WHERE s.username = 'AH' AND paddr = addr(+)
 
SID SERIAL# STATUS SPID
--- ------- ------ ----

Выбрано: 0 строк

Но остаётся в таблице x$ksuse:

SQL> SELECT count(*) FROM x$ksuse WHERE ksuudsna = 'AH'
 
COUNT(*)
--------
1       

Выбрано: 1 строка

Серверный процесс при этом всё ещё существует:

SQL>  SELECT addr, pid, spid FROM v$process WHERE spid = 1568
 
ADDR     PID SPID
-------- --- ----
2A136324 21  1568

Если пользователь продолжит пытаться выполнять команды, то экземпляр на все дальнейшие попытки будет отвечать ошибкой ORA-01012: not logged on:

SQL> SELECT sysdate FROM dual
 
SELECT sysdate FROM dual
*
Ошибка в строке 1:
ORA-01012: not logged on

В дальнейшем серверный процесс будет уничтожен только в том случае, если пользователь предпримет попытку сам разорвать соединение. Только в этом случае процесс уничтожения сеанса можно считать законченным.

Уничтожаем сеанс с незафиксированными транзакциями

Если в сеансе имеются незафиксированные транзакции, то при выдаче команды ALTER SYSTEM KILL SESSION происходит откат этих транзакций. Занимается откатом мертвых транзакции фоновый процесс Oracle SMON . Убедимся в этом, выполнив следующий пример:

SQL> CREATE TABLE table1 (id NUMBER(11),name VARCHAR2(20));

Таблица создана

SQL> DECLARE
  2>   i INTEGER;
  3> BEGIN
  4>   FOR i IN 1..500000 LOOP
  5>     INSERT INTO table1 (id,name) VALUES (i,'ITEM'||i);
  6>   END LOOP;
  7> END;  
 
PL/SQL procedure successfully completed

Теперь попытаемся уничтожить этот сеанс:

SQL> ALTER SYSTEM KILL SESSION '14,151'; 

System altered  

Сеанс уничтожается, не дожидаясь окончания отката транзакции. Через некоторое время в каталоге, определяемом параметром background_dump_dest, появится трассировочный файл процесса SMON, который будет содержать строку примерно следующего вида:

Dead transaction 0x0006.00a.00000091 recovered by SMON

Это означает, что мёртвая транзакция 0x0006.00a.00000091 была восстановлена процессом SMON. Если же в экземпляре используется параллельное восстановление, то функции отката берёт на себя вновь образующийся от SMON дочерний процесс. Его можно увидеть, если выполнить следующий запрос сразу после уничтожения сеанса:

SQL> SELECT sid, username, status, program FROM v$session WHERE program LIKE 
'% P00%'; 

SID USERNAME STATUS PROGRAM  
--- -------- ------ -----------------  
16           ACTIVE ORACLE.EXE (P000) 

Выбрано: 1 строка

В данном случае трассировочного файла не образуется, но в журнальном файле Oracle появляется запись вида о попытке параллельного восстановления:

SMON: Parallel transaction recovery tried

Так как фоновый процесс SMON обладает низким приоритетом обработки, то при большой загрузке он может длительное время откатывать транзакции. Поэтому надо с осторожностью уничтожать такие сеансы.

Уничтожаем серверный процесс

Иногда бывает, что пользовательское приложение завершается аварийно, вместе с ним аварийно завершается и пользовательский процесс. К примеру, отключите сеть, выгрузите приложение, затем снова включите сеть. Для того чтобы уничтожить такие сеансы, Oracle с периодичностью в минутах задаваемой параметром sqlnet.expire_time, который находится в файле sqlnet.ora посылает по всем соединениям пустые пакеты, которые игнорируются работающими пользовательскими процессами. Если физического соединения нет, то Oracle помечает сеанс как убитый и приступает к его уничтожению. В некоторых случаях данный механизм не срабатывает, и возникают так называемые “потерянные сеансы”, то есть сеансы не связанные с пользовательскими процессами. Такие сеансы могут находиться в неопределённом состоянии долгое время. Обычно они легко уничтожаются с помощью команды ALTER SYSTEM KILL SESSION. Но если выполнение команды не приносит результатов, и сеанс продолжает долгое время, находится в статусе KILLED, то придется вмешаться в уничтожение такого сеанса на уровне операционной системы, то есть уничтожить серверный процесс средствами ОС. Операция эта опасная и делать её надо очень аккуратно, чтобы случайно не уничтожить фоновые процессы экземпляра. Для этого желательно всегда запоминать значение идентификатора SPID серверного процесса относящегося к сеансу. Если же значение поля PADDR в представлении v$session уже не соотноситься с адресом в поле ADDR представления v$process , то серверный процесс придется искать приблизительно. В Unix это можно сделать с помощью команды ps , примерно сравнивая время соединения сеанса в поле logon_time представления v$session со временем образования процесса в колонке STARTED результата выполнения команды ps.

alfa> ps aux 
USER   PID   %CPU %MEM VSZ   RSS  TTY S  STARTED  TIME    COMMAND 
oracle 16051 0.0  0.0  2.16M 1.9M ??  I  16:55:14 0:01.88 oraclealfa 
(DESCRIPTION=( 

В системе Windows сеансы существуют в виде потоков. Поэтому определить такой сеанс будет сложнее. Чтобы облегчить задачу можно выполнить запрос к представлению v$process, который покажет все процессы, у которых значения поля ADDR не соответствует ни одному значению в поле PADDR представления v$session:

SQL> SELECT addr, pid, spid, program FROM v$process WHERE addr NOT IN (SELECT 
paddr FROM v$session) 
 
ADDR     PID SPID PROGRAM          
-------- --- ---- -----------------
2A12EC64 1        PSEUDO           
2A1333A4 13  1220 ORACLE.EXE (D000)
2A133994 14  1148 ORACLE.EXE (S000)
2A133F84 15  1200 ORACLE.EXE (S001)
2A134574 16  1204 ORACLE.EXE (S002)
2A134B64 17  1240 ORACLE.EXE (S003)
2A135154 18  652  ORACLE.EXE (SHAD)

Выбрано: 7 строк

Здесь мы видим такой процесс со значением идентификатора процесса в операционной системы SPID равным 652. Попробуем уничтожить данный серверный процесс. В системе Windows это делается с помощью утилиты командной строки orakill:

C:\>orakill XE 652

Kill of thread id 652 in instance XE successfully signalled.

В Unix с помощью команды kill -9 spid .

alfa> kill -9 16472 

Уничтожаем активный сеанс

Выше мы рассмотрели варианты уничтожения неактивных сеансов. Более сложная ситуация возникает в случае активности сеанса. Здесь всё зависит от того, что делает сеанс в момент времени уничтожения. Если выполняется оператор SQL , то сеанс уничтожается, и пользователь немедленно получает сообщение ошибки ORA-00028: your session has been killed. Если же сеанс выполняет, к примеру, откат транзакции или сетевой ввод-вывод, то его уничтожение произойдет только после завершения текущей операции. В этом случае сеанс, в котором выполняется команда ALTER SYSTEM KILL SESSION, будет ожидать. Если время ожидания превысит 60 секунд, то данному сеансу выдается сообщение ошибки ORA-00031. Уничтожаемый сеанс при этом обретает статус KILLED, но продолжает выполнять текущую операцию.

SQL> SELECT s.sid, s.serial#, s.status, p.spid FROM v$session s, v$process p 
WHERE s.username = 'AH' AND p.addr = s.paddr; 

SID SERIAL# STATUS SPID  
--- ------- ------ ----  
14       26 ACTIVE 1176 

Выбрано: 1 строка  

SQL> ALTER SYSTEM KILL SESSION '14,26'; 

ALTER SYSTEM KILL SESSION '14,26'  
*  
Ошибка в строке 1: 
ORA-00031: session marked for kill 

SQL> SELECT sid,s.serial#,s.status FROM v$session s WHERE s.username = 'TEST'; 

SID SERIAL# STATUS 
--- ------- ------  
14       26 KILLED  

Выбрано: 1 строка  

Выводы

  • Если сеанс не содержит незавершенных транзакций, то такой сеанс можно уничтожать без проблем.
  • Уничтожение серверного процесса сеанса на уровне OC необходимо выполнять только в случае крайней необходимости.
  • Если сеанс содержит незавершенные транзакции, то прежде чем уничтожать такой сеанс посмотрите, сколько изменений было сделано в транзакции и какова загрузка Oracle в текущий момент. Если эти значения высоки, то уничтожение сеанса лучше перенести на более спокойный отрезок времени.
  • Если сеанс активный и выполняет, к примеру, откат транзакции или сетевой вывод то лучше подождать завершения текущей операции сеанса. Если выполнение этой операции затягивается, то необходимо уничтожить серверный процесс на уровне OC . Но делать это лучше в случае крайней необходимости. Практическое администрирование Oracle – Экземпляр

ORA-00028: your session has been killed

calendar_today

Updated On:

Products

CA Release Automation — Release Operations Center (Nolio)

CA Release Automation — DataManagement Server (Nolio)

Issue/Introduction

NAC reports a «session has been killed» error.  The NAC’s nolio_dm_all.log files then capture the following errors:

WARN  (org.hibernate.engine.jdbc.spi.SqlExceptionHelper:143) — SQL Error: 28, SQLState: 08006

ERROR (org.hibernate.engine.jdbc.spi.SqlExceptionHelper:144) — ORA-00028: your session has been killed

ERROR (com.nolio.platform.server.dataservices.services.hibernate.NolioHibernateTemplate:203) — Caught hibernate exception.org.hibernate.exception.JDBCConnectionException: ORA-00028: your session has been killed

Environment

Any Release Automation environment running with Oracle database.

Cause

The group of errors above occur when Oracle database generates an ORA-00028 error.  There are several possible causes for Oracle to return this error to Release Automation.  ORA-00028 usually indicates a privileged user (such as a DBA) has manually killed the session.  This can happen if database maintenance tasks are being performed at the time of the error or if the database user has decided to identify and kill that session for some reason.

There are other possible causes for this error, including:

  • Manually killed session by privileged database user. 
  • Database timeout.
  • Database deadlock.
  • Oracle specific bug in the database.
  • Firewall or other network problem.

Resolution

After identifying which of the possible causes above is at play, solutions follow, respectively:

  • In the most likely case of a privileged user manually killing the session, you should consult your Oracle DBA for further details.
  • A timeout or deadlock may require a database restart to resolve.
  • Check with Oracle for any known defects that may result in ORA-00028, as patches may be available. 
  • Check for any firewall or network issues.  An example: If the host name of the NAC is changed, and the firewall is not adjusted accordingly, an ORA-00028 error may be reported as a result. 

Additional Information

For more information regarding ORA-00028, there are many online resources outside of CA worth consulting.  Oracle provides their own Oracle Technology Network community that provides a number of resources for finding more detailed information on this and other ORA errors. 

Feedback

thumb_up
Yes

thumb_down
No

The problem is that handling an error ORA-00028 is kinda tricky. Please, look at the code below.

If you run proc1 in session 1 and while it’s still running you kill session 1 with ALTER SYSTEM KILL SESSION then you get ORA-00028 error message and no row in llog table.
If you run proc1 and let it finish (1 min) then error handling works as expected and you get no error message and 1 row in llog table. But the funny thing is if after that you run proc1 again and kill that session you get no error-message (ORA-00028 handled) and one more row in llog table.

So for ORA-00028 to be handled in exception clause you need to catch some other error first. It seems to be a bug. Has anyone faced this problem?

/* creating simple table with logs */

create table llog(time timestamp, error varchar2(4000));
/

/* creating package */

create or replace package my_pack
is
       procedure proc1;
end;
/
/* creating package body*/

create or replace package body my_pack
is

e_session_killed EXCEPTION;
PRAGMA EXCEPTION_INIT(e_session_killed, -00028);


procedure error_log (time llog.time%type, error llog.error%type) is
  pragma autonomous_transaction;
begin
  insert into llog values (time, error); 
  commit;
end;


procedure proc1 is
begin

  dbms_lock.sleep(60);

  raise too_many_rows;

  exception
    when e_session_killed then
      error_log(systimestamp, sqlerrm);

    when others then
      error_log(systimestamp, sqlerrm);

end;

end;

asked Nov 10, 2019 at 13:50

Lumberjack's user avatar

2

You can’t catch a kill session. It interrupts the current operation (as mush as it can — there might be some low level operations that cause issues), rolling back the open transaction(s). Once the rollback is complete the client is told that it is disconnected (assuming the client is still there) and the process goes away.

There’s a couple of variants of kill session that affect the order of those but you’re not going to be able to insert anything into any table from a killed session.

The only exception might be through a database link or similar, where you actually have two separate sessions/processes going on at the same time.

answered Nov 11, 2019 at 2:04

Gary Myers's user avatar

Gary MyersGary Myers

35k3 gold badges49 silver badges74 bronze badges

3

Сеанс – это специфическое соединение пользователя к экземпляру Oracle через пользовательский процесс. При работе с выделенным сервером для каждого такого сеанса создается отдельный серверный процесс. Обмен пользователя с экземпляром базы данных происходит через пользовательский процесс на клиентской машине, который в свою очередь через драйвер клиента Oracle Net работает с выделенным серверным процессом, взаимодействующим непосредственно с самим экземпляром Oracle. Иногда возникают ситуации, когда требуется уничтожить какие либо сеансы. Такое обычно такое происходит, когда требуется прервать долго выполняющийся сеанс или возникает необходимость в проведении административных работ с отключением всех сеансов. Так же может понадобиться и просто откатить незафиксированную транзакцию, если за данным сеансом выстроилась большая очередь. Бывают и так называемые “потерянные сеансы”, нуждающиеся в уничтожении. В этой главе мы научимся идентифицировать такие сеансы, уничтожать их, а так же рассмотрим сложности, возникающие при этом процессе.

Идентифицируем сеанс

Процесс уничтожения сеанса заключается в откате всех незафиксированных транзакций сеанса, освобождении используемых им ресурсов и уничтожении серверного процесса. Выполняется эта операция с помощью SQL команды ALTER SYSTEM KILL SESSION ‘sid,serial#’. Чтобы выполнить эту команду, нам необходимо знать идентификатор sid и порядковый номер serial# сеанса. Для этого нам необходимо обратится к системным представлениям v$session и v$process с целью поиска записи параметров конкретного сеанса. Но прежде мы вкратце ознакомимся с данными системными представлениями. Первое из них v$session показывает все установленные сеансы экземпляра Oracle. Второе v$process отображает соответствующие им выделенные серверные процессы. Оба этих представления основаны на так называемых x$ таблицах: x$ksuse и x$ksupr. Если мы сделаем запрос к этим таблицам, то обнаружим, что количество строк в этих таблицах соответствует параметрам инициализации sessions и processes, и не совпадает с количеством строк отображаемых представлениями v$session и v$process.

Подключение: SYS@XE AS SYSDBA
Oracle Database 10g Express Edition Release 10.2.0.1.0 – Production

SQL> SELECT 'x$ksuse' "X$TABLES", count(*) FROM x$ksuse union SELECT 
'x$ksupr',count(*) FROM x$ksup;
 
X$TABLES COUNT(*)
-------- --------
x$ksupr  40      
x$ksuse  49  

SQL> SELECT name, value FROM v$parameter WHERE name IN 
('processes','sessions');
 
NAME      VALUE
--------- -----
processes 40   
sessions  49   

SQL> SELECT 'v$session' "VIEW", count(*) FROM v$session union SELECT 
'v$process',count(*) FROM v$process;
 
VIEW      COUNT(*)
--------- --------
v$process 22      
v$session 16      

Так как x$ таблицы, по сути, являются наборами определённых структур в памяти SGA, то можно предположить, что память под структуры хранящие информацию о сеансах и серверных процессах выделяется заранее и их количество всегда равно значениям параметров инициализации session и process. Рассмотрим более подробно некоторые поля этих двух x$ таблиц. Одна из таблиц x$ksuse, хранит информацию о сеансах экземпляра Oracle и первое, интересующее нас в ней поле indx, обозначает идентификатор сеанса. Оно имеет сквозную нумерацию от 1 до значения параметра sessions и в представлении v$session соответствует полю sid. Значение в этом столбце практически указывает на номер записи в таблице x$ksuse и следовательно может быть повторно использовано после того как данный сеанс закончит работу. Второе поле ksuseser – это порядковый номер сеанса. В представлении v$session данное поле соответствует полю serial# и имеет уникальное неповторяющееся значение для каждого сеанса. Третье поле, которое мы рассмотрим это поле ksusepro – адрес структуры памяти серверного процесса, которому принадлежит данный сеанс. В представлении v$session оно отражается как поле paddr. В дополнении к таблице x$ksuse мы так же рассмотрим структуру таблицы x$ksupr, которая определяет выделенные серверные процессы Oracle. Здесь нас будут интересовать два поля. Это поле addr — адрес структуры памяти выделенного серверного процесса. В представлении v$process он имеет такое же название. И второе поле это ksuprpid – идентификатор процесса операционной системы. В представлении v$process поле spid. И так мы ознакомились с представлениями и параметрами идентифицирующими сеанс. Теперь в качестве примера попробуем получить sid и serial# сеанса предварительно созданного нами пользователя AH. Для этого выполним следующий запрос, соединив два представления v$session и v$process по полям addr и paddr:

SQL> SELECT sid, s.serial#, s.status, p.spid FROM v$session s, v$process p 
WHERE s.username = 'AH' AND paddr = addr(+)
 
SID SERIAL# STATUS   SPID
--- ------- -------- ----
22  11      INACTIVE 1568 

Параметры получены. Теперь можно приступить к уничтожению сеанса.

Уничтожаем неактивный сеанс

Выполним команду ALTER SYSTEM KILL SESSION для указанного выше сеанса:

SQL> ALTER SYSTEM KILL SESSION '22,11' 

System altered 

Посмотрим состояние сеанса:

SQL> SELECT sid,s.serial#,s.status,p.spid FROM v$session s, v$process p WHERE 
s.username = 'AH' AND paddr = addr(+)
 
SID SERIAL# STATUS SPID
--- ------- ------ ----
22  11      KILLED

Если сеанс неактивный и не содержит незавершенных транзакций, то он помечается со статусом KILLED . Поле PADDR уже не указывает на адрес структуры выделенного серверного процесса. Но серверный процесс не освобождается:

SQL> SELECT addr, pid, spid FROM v$process WHERE spid = 1568
 
ADDR     PID SPID
-------- --- ----
2A136324 21  1568

Такое состояние будет продолжаться до тех пор, пока пользователь снова попытается использовать сеанс или отключиться от сервера. В первом случае пользователю выдается сообщение об ошибке ORA-00028:

SQL> SELECT sysdate FROM dual
 
SELECT sysdate FROM dual
*
Ошибка в строке 1:
ORA-00028: your session has been killed 

Информация при этом о сеансе из представления v$session исчезает:

SQL> SELECT sid, s.serial#, s.status, p.spid FROM v$session s, v$process p 
WHERE s.username = 'AH' AND paddr = addr(+)
 
SID SERIAL# STATUS SPID
--- ------- ------ ----

Выбрано: 0 строк

Но остаётся в таблице x$ksuse:

SQL> SELECT count(*) FROM x$ksuse WHERE ksuudsna = 'AH'
 
COUNT(*)
--------
1       

Выбрано: 1 строка

Серверный процесс при этом всё ещё существует:

SQL>  SELECT addr, pid, spid FROM v$process WHERE spid = 1568
 
ADDR     PID SPID
-------- --- ----
2A136324 21  1568

Если пользователь продолжит пытаться выполнять команды, то экземпляр на все дальнейшие попытки будет отвечать ошибкой ORA-01012: not logged on:

SQL> SELECT sysdate FROM dual
 
SELECT sysdate FROM dual
*
Ошибка в строке 1:
ORA-01012: not logged on

В дальнейшем серверный процесс будет уничтожен только в том случае, если пользователь предпримет попытку сам разорвать соединение. Только в этом случае процесс уничтожения сеанса можно считать законченным.

Уничтожаем сеанс с незафиксированными транзакциями

Если в сеансе имеются незафиксированные транзакции, то при выдаче команды ALTER SYSTEM KILL SESSION происходит откат этих транзакций. Занимается откатом мертвых транзакции фоновый процесс Oracle SMON . Убедимся в этом, выполнив следующий пример:

SQL> CREATE TABLE table1 (id NUMBER(11),name VARCHAR2(20));

Таблица создана

SQL> DECLARE
  2>   i INTEGER;
  3> BEGIN
  4>   FOR i IN 1..500000 LOOP
  5>     INSERT INTO table1 (id,name) VALUES (i,'ITEM'||i);
  6>   END LOOP;
  7> END;  
 
PL/SQL procedure successfully completed

Теперь попытаемся уничтожить этот сеанс:

SQL> ALTER SYSTEM KILL SESSION '14,151'; 

System altered  

Сеанс уничтожается, не дожидаясь окончания отката транзакции. Через некоторое время в каталоге, определяемом параметром background_dump_dest, появится трассировочный файл процесса SMON, который будет содержать строку примерно следующего вида:

Dead transaction 0x0006.00a.00000091 recovered by SMON

Это означает, что мёртвая транзакция 0x0006.00a.00000091 была восстановлена процессом SMON. Если же в экземпляре используется параллельное восстановление, то функции отката берёт на себя вновь образующийся от SMON дочерний процесс. Его можно увидеть, если выполнить следующий запрос сразу после уничтожения сеанса:

SQL> SELECT sid, username, status, program FROM v$session WHERE program LIKE 
'% P00%'; 

SID USERNAME STATUS PROGRAM  
--- -------- ------ -----------------  
16           ACTIVE ORACLE.EXE (P000) 

Выбрано: 1 строка

В данном случае трассировочного файла не образуется, но в журнальном файле Oracle появляется запись вида о попытке параллельного восстановления:

SMON: Parallel transaction recovery tried

Так как фоновый процесс SMON обладает низким приоритетом обработки, то при большой загрузке он может длительное время откатывать транзакции. Поэтому надо с осторожностью уничтожать такие сеансы.

Уничтожаем серверный процесс

Иногда бывает, что пользовательское приложение завершается аварийно, вместе с ним аварийно завершается и пользовательский процесс. К примеру, отключите сеть, выгрузите приложение, затем снова включите сеть. Для того чтобы уничтожить такие сеансы, Oracle с периодичностью в минутах задаваемой параметром sqlnet.expire_time, который находится в файле sqlnet.ora посылает по всем соединениям пустые пакеты, которые игнорируются работающими пользовательскими процессами. Если физического соединения нет, то Oracle помечает сеанс как убитый и приступает к его уничтожению. В некоторых случаях данный механизм не срабатывает, и возникают так называемые “потерянные сеансы”, то есть сеансы не связанные с пользовательскими процессами. Такие сеансы могут находиться в неопределённом состоянии долгое время. Обычно они легко уничтожаются с помощью команды ALTER SYSTEM KILL SESSION. Но если выполнение команды не приносит результатов, и сеанс продолжает долгое время, находится в статусе KILLED, то придется вмешаться в уничтожение такого сеанса на уровне операционной системы, то есть уничтожить серверный процесс средствами ОС. Операция эта опасная и делать её надо очень аккуратно, чтобы случайно не уничтожить фоновые процессы экземпляра. Для этого желательно всегда запоминать значение идентификатора SPID серверного процесса относящегося к сеансу. Если же значение поля PADDR в представлении v$session уже не соотноситься с адресом в поле ADDR представления v$process , то серверный процесс придется искать приблизительно. В Unix это можно сделать с помощью команды ps , примерно сравнивая время соединения сеанса в поле logon_time представления v$session со временем образования процесса в колонке STARTED результата выполнения команды ps.

alfa> ps aux 
USER   PID   %CPU %MEM VSZ   RSS  TTY S  STARTED  TIME    COMMAND 
oracle 16051 0.0  0.0  2.16M 1.9M ??  I  16:55:14 0:01.88 oraclealfa 
(DESCRIPTION=( 

В системе Windows сеансы существуют в виде потоков. Поэтому определить такой сеанс будет сложнее. Чтобы облегчить задачу можно выполнить запрос к представлению v$process, который покажет все процессы, у которых значения поля ADDR не соответствует ни одному значению в поле PADDR представления v$session:

SQL> SELECT addr, pid, spid, program FROM v$process WHERE addr NOT IN (SELECT 
paddr FROM v$session) 
 
ADDR     PID SPID PROGRAM          
-------- --- ---- -----------------
2A12EC64 1        PSEUDO           
2A1333A4 13  1220 ORACLE.EXE (D000)
2A133994 14  1148 ORACLE.EXE (S000)
2A133F84 15  1200 ORACLE.EXE (S001)
2A134574 16  1204 ORACLE.EXE (S002)
2A134B64 17  1240 ORACLE.EXE (S003)
2A135154 18  652  ORACLE.EXE (SHAD)

Выбрано: 7 строк

Здесь мы видим такой процесс со значением идентификатора процесса в операционной системы SPID равным 652. Попробуем уничтожить данный серверный процесс. В системе Windows это делается с помощью утилиты командной строки orakill:

C:>orakill XE 652

Kill of thread id 652 in instance XE successfully signalled.

В Unix с помощью команды kill -9 spid .

alfa> kill -9 16472 

Уничтожаем активный сеанс

Выше мы рассмотрели варианты уничтожения неактивных сеансов. Более сложная ситуация возникает в случае активности сеанса. Здесь всё зависит от того, что делает сеанс в момент времени уничтожения. Если выполняется оператор SQL , то сеанс уничтожается, и пользователь немедленно получает сообщение ошибки ORA-00028: your session has been killed. Если же сеанс выполняет, к примеру, откат транзакции или сетевой ввод-вывод, то его уничтожение произойдет только после завершения текущей операции. В этом случае сеанс, в котором выполняется команда ALTER SYSTEM KILL SESSION, будет ожидать. Если время ожидания превысит 60 секунд, то данному сеансу выдается сообщение ошибки ORA-00031. Уничтожаемый сеанс при этом обретает статус KILLED, но продолжает выполнять текущую операцию.

SQL> SELECT s.sid, s.serial#, s.status, p.spid FROM v$session s, v$process p 
WHERE s.username = 'AH' AND p.addr = s.paddr; 

SID SERIAL# STATUS SPID  
--- ------- ------ ----  
14       26 ACTIVE 1176 

Выбрано: 1 строка  

SQL> ALTER SYSTEM KILL SESSION '14,26'; 

ALTER SYSTEM KILL SESSION '14,26'  
*  
Ошибка в строке 1: 
ORA-00031: session marked for kill 

SQL> SELECT sid,s.serial#,s.status FROM v$session s WHERE s.username = 'TEST'; 

SID SERIAL# STATUS 
--- ------- ------  
14       26 KILLED  

Выбрано: 1 строка  

Выводы

  • Если сеанс не содержит незавершенных транзакций, то такой сеанс можно уничтожать без проблем.
  • Уничтожение серверного процесса сеанса на уровне OC необходимо выполнять только в случае крайней необходимости.
  • Если сеанс содержит незавершенные транзакции, то прежде чем уничтожать такой сеанс посмотрите, сколько изменений было сделано в транзакции и какова загрузка Oracle в текущий момент. Если эти значения высоки, то уничтожение сеанса лучше перенести на более спокойный отрезок времени.
  • Если сеанс активный и выполняет, к примеру, откат транзакции или сетевой вывод то лучше подождать завершения текущей операции сеанса. Если выполнение этой операции затягивается, то необходимо уничтожить серверный процесс на уровне OC . Но делать это лучше в случае крайней необходимости. Практическое администрирование Oracle – Экземпляр

The v$session view

If you do not know already, to check who is connected and since when, what their connection status is etc., you would use dynamic view v$session.

The view has the following columns:

SADDR, SID, SERIAL#, AUDSID, PADDR, USER#, USERNAME, COMMAND,
OWNERID, TADDR, LOCKWAIT, STATUS, SERVER, SCHEMA#, SCHEMANAME,
OSUSER, PROCESS, MACHINE, TERMINAL, PROGRAM, TYPE, SQL_ADDRESS,
SQL_HASH_VALUE, PREV_SQL_ADDR, PREV_HASH_VALUE, MODULE, MODULE_HASH,
ACTION, ACTION_HASH, CLIENT_INFO, FIXED_TABLE_SEQUENCE, ROW_WAIT_OBJ#,
ROW_WAIT_FILE#, ROW_WAIT_BLOCK#, ROW_WAIT_ROW#, LOGON_TIME, LAST_CALL_ET,
PDML_ENABLED, FAILOVER_TYPE, FAILOVER_METHOD, FAILED_OVER,
RESOURCE_CONSUMER_GROUP, PDML_STATUS, PDDL_STATUS, PQ_STATUS,
CURRENT_QUEUE_DURATION, CLIENT_IDENTIFIER

You would kill the required session by issuing

ALTER SYSTEM KILL SESSION 'sid,serial#';

Note: The IMMEDIATE option of the above command just returns control to you immediately. There is no difference in the underlying KILL operation and its after-effects!

2 Reasons why a session stays in KILLED status

The view has a lot of useful information. In this post, we are not so much concerned with the view itself but the status displayed by the view for an underlying session.

In particular, when a session is killed by a DBA, the session’s STATUS changes to KILLED. When you query v$session for your SID & SERIAL# (which uniquely constitute a session), the status may remain in “KILLED” status. There are a couple of reasons why this is happens

  1. The client (e.g., SQL*Plus) was not closed or did not issue anything to reconnect with the database, at which point Oracle would have said “ORA-00028: your session has been killed”
  2. The session is KILLED but PMON (Oracle background process – Process Monitor), has to cleanup and the work might involve rolling back changes

If you are trying to perform operations that involve getting an exclusive lock on the object(s) involved, you may get this error:
ORA-00054: resource busy and acquire with NOWAIT specified

More about why a session stays in KILLED status

So, how do you get around the error or make the entry in v$session with the “KILLED” status disappear? It depends on which of the two situations is causing the entry to stay on.

  • If the reason for session “hanging around” in “KILLED” status is because of #1 above:
  • Close the client software that you requested your DBA to kill. Alternatively, try issuing another command that tries to make a connection to the database. This should result in the error – ORA-00028: your session has been killed.
  • If the client S/W is not on your PC but on a server for example, close or kill the OS process associated with the session.
  • After doing the above, if the session is still showing up in v$session with “KILLED” status, it is because of #2 above
  • You have to wait until Oracle finishes the rollback and cleanup necessary

If the reason is #2, the following query, which shows UNDO usage by session should show the usage by the session in KILLED status.

SELECT s.username,
       s.SID,
       s.serial#,
       s.logon_time,
       t.xidusn,
       t.ubafil,
       t.ubablk,
       t.used_ublk,
       t.start_time AS txn_start_time,
       t.status,
       ROUND (t.used_ublk * TO_NUMBER (x.VALUE) / 1024 / 1024, 2) || ' Mb'
          "Undo"
  FROM v$session s, v$transaction t, v$parameter x
WHERE s.saddr = t.ses_addr AND x.name = 'db_block_size'

What if I restart the instance?

I can tell you right away that you are making the problem worse by restarting. It still has to ROLLBACK and bring the objects involved to a consistent state before letting them go. By restarting, you will be interfering and interrupting that and adding more time delays!

Can you do anything about it? No, just sit tight and monitor!

As PMON cleanup/rollback continues, the size of UNDO used by the session should keep going down. When it gets to zero, yes, you guessed it – your session in KILLED status will disappear from v$session. Use this in coordination with the other tip from before that showed how to query the overall UNDO usage at the system level.

The serial# is also a key part of the query here when you monitor. Oracle reuses SID values. For example, session with SID 17 that a few minutes ago, was running a query and then disconnected, can have the SID value be used by another session but with a different Serial#. Until the next database restart, SID+Serial# combination will remain unique.

Can I do something to be proactive? Absolutely

Yes, the DBA can tell you what statement is being executed or where the connection is made from etc, but he may not know what application the session belongs to. You could help your DBA by using DBMS_APPLICATION_INFO.SET_CLIENT_INFO in your entry-point procedure of your application to set the CLIENT_INFO so that it shows up as part of the v$Session.client_info column and the DBA can then tell you that such and such an application is the one whose ROLLBACK is in progress. There are also additional instrumentation options available in the package that should be fully taken advantage of.

PROCEDURE DBMS_APPLICATION_INFO.SET_CLIENT_INFO
    (client_info IN VARCHAR2);

Assuming you here have instrumented your code, v$session.client_info column has the name of the application. To find all the sessions for an application(s), simple issue this query:

SELECT * FROM v$session
WHERE client_info IS NOT NULL;

In my organization, I instituted the instrumentation part so that everyone knows exactly what is running.

When you request us to kill a session, you can be more knowledgeable about your request by first looking the session status and then giving the DBA’s the SID/Serial#. Once killed, you can monitor when the session has been completely flushed out of the system or if it is not, you now know why!

Further Reading: https://oracle-base.com/articles/misc/killing-oracle-sessions

May 2, 2021

I got ” ORA-00028: Your session has been killed ”  error in Oracle database.

ORA-00028: Your session has been killed

Details of error are as follows.

ORA-00028: Your session has been killed

Cause: A privileged user has killed your session and you are no longer logged on to the database.

Action: Login again if you wish to continue working.

Your session has been killed

This ORA-00028 errors are related with the privileged user has killed your session and you are no longer logged on to the database.

Login again if you wish to continue working.

This is an informational message only, so there is no solution for this error. You should run your job or SQL Statement again.

Contact the DBA.   The administrator may be attempting to perform an operation that requires users to be logged out.  When the database administrator announces that the database is available, log in and resume work.

1. Need to contact to database administrator. The administrator may be attempting to perform an operation that requires users to be logged out.

2. Need to  check database setting. Database can drop the idle connections.

3. A network issue can also cause the connection to drop, contact the network administrator

4. Firewall can drop  the  idle connections.

Do you want to learn Oracle Database for Beginners, then read the following articles.

Oracle Tutorial | Oracle Database Tutorials for Beginners ( Junior Oracle DBA )

About Mehmet Salih Deveci

I am Founder of SysDBASoft IT and IT Tutorial and Certified Expert about Oracle & SQL Server database, Goldengate, Exadata Machine, Oracle Database Appliance administrator with 10+years experience.I have OCA, OCP, OCE RAC Expert Certificates I have worked 100+ Banking, Insurance, Finance, Telco and etc. clients as a Consultant, Insource or Outsource.I have done 200+ Operations in this clients such as Exadata Installation & PoC & Migration & Upgrade, Oracle & SQL Server Database Upgrade, Oracle RAC Installation, SQL Server AlwaysOn Installation, Database Migration, Disaster Recovery, Backup Restore, Performance Tuning, Periodic Healthchecks.I have done 2000+ Table replication with Goldengate or SQL Server Replication tool for DWH Databases in many clients.If you need Oracle DBA, SQL Server DBA, APPS DBA,  Exadata, Goldengate, EBS Consultancy and Training you can send my email adress [email protected].-                                                                                                                                                                                                                                                 -Oracle DBA, SQL Server DBA, APPS DBA,  Exadata, Goldengate, EBS ve linux Danışmanlık ve Eğitim için  [email protected] a mail atabilirsiniz.

Понравилась статья? Поделить с друзьями:
  • Ошибка json parse error
  • Ошибка opvl ippon smart winner 2000
  • Ошибка json parse anonymous
  • Ошибка opf altivar 31
  • Ошибка jenkins при запуске 1с