Приветствую Вас Гость | RSS

DBA.UCOZ.RU

Понедельник, 20.11.2017, 18:37
Главная » Статьи » СУБД » Oracle

Практическое администрирование Oracle – Экземпляр – Уничтожение сеансов.
Сеанс – это специфическое соединение пользователя к экземпляру 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 | Добавил: dba (13.04.2009) | Автор: Жилин Сергей Валентинович
Просмотров: 7613 | Комментарии: 1 | Теги: Уничтожение, Сеанс, Экземпляр, Oracle | Рейтинг: 0.0/0
Всего комментариев: 1
1  
При написании статьи использовались Oracle Database 10g Express Edition и DBASQL for Oracle.
Сборник всех статей в pdf формате можно скачать здесь

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]