Як перевірити базу даних Oracle на наявність тривалих запитів


99

Моя програма, яка використовує базу даних Oracle, йде повільно або, схоже, повністю припинилася.

Як дізнатись, які запити є найдорожчими, щоб я міг вивчити далі?

Відповіді:


134

Цей показує SQL, який наразі є "АКТИВНИМ": -

select S.USERNAME, s.sid, s.osuser, t.sql_id, sql_text
from v$sqltext_with_newlines t,V$SESSION s
where t.address =s.sql_address
and t.hash_value = s.sql_hash_value
and s.status = 'ACTIVE'
and s.username <> 'SYSTEM'
order by s.sid,t.piece
/

Це показує замки. Іноді все йде повільно, але це тому, що він заблокований в очікуванні блокування:

select
  object_name, 
  object_type, 
  session_id, 
  type,         -- Type or system/user lock
  lmode,        -- lock mode in which session holds lock
  request, 
  block, 
  ctime         -- Time since current mode was granted
from
  v$locked_object, all_objects, v$lock
where
  v$locked_object.object_id = all_objects.object_id AND
  v$lock.id1 = all_objects.object_id AND
  v$lock.sid = v$locked_object.session_id
order by
  session_id, ctime desc, object_name
/

Це добре для пошуку тривалих операцій (наприклад, сканування повних таблиць). Якщо це через багато коротких операцій, нічого не з’явиться.

COLUMN percent FORMAT 999.99 

SELECT sid, to_char(start_time,'hh24:mi:ss') stime, 
message,( sofar/totalwork)* 100 percent 
FROM v$session_longops
WHERE sofar/totalwork < 1
/

1
Чи є спосіб безпечно вбити такі запити, якщо вони працюють більше х хвилин. Дякую за відповідь, хоча @UmberFerrule
TommyT

2
@TommyT Ви можете використовувати, alter system kill sessionяк описано тут: docs.oracle.com/cd/B28359_01/server.111/b28310/…
WW.

37

Спробуйте це, воно дасть вам запити, які зараз працюють більше 60 секунд. Зверніть увагу, що він друкує кілька рядків на один запущений запит, якщо SQL має кілька рядків. Подивіться на sid, serial #, щоб побачити, що належить разом.

select s.username,s.sid,s.serial#,s.last_call_et/60 mins_running,q.sql_text from v$session s 
join v$sqltext_with_newlines q
on s.sql_address = q.address
 where status='ACTIVE'
and type <>'BACKGROUND'
and last_call_et> 60
order by sid,serial#,q.piece

я запускаю цей запит, і він повідомляє мені, що невірне твердження

Це дійсно. Я тестував це. Який інструмент ви використовуєте для запиту? Це може заплутатися зі знаком #. Спробуйте змінити початок і кінець таким чином: "вибрати * з ... упорядкувати за sid, q.piece"
Карлос А. Ібарра,

2
Крім того, вам потрібно буде запустити це з привілейованим обліковим записом, який має доступ до v $ session, v $ sqltext_with_newlines
WW.

Це працює, але повертає текст SQL запиту в дуже дивному форматі.
Bernhard Döbler

7

v $ session_longops

Якщо ви шукаєте sofar! = Totalwork, ви побачите ті, які не завершені, але записи не видаляються після завершення операції, тому ви також можете побачити там багато історії.


Хороший підказка. Також детально обговорюється тут .
dma_k

4
Step 1:Execute the query

column username format 'a10'
column osuser format 'a10'
column module format 'a16'
column program_name format 'a20'
column program format 'a20'
column machine format 'a20'
column action format 'a20'
column sid format '9999'
column serial# format '99999'
column spid format '99999'
set linesize 200
set pagesize 30
select
a.sid,a.serial#,a.username,a.osuser,c.start_time,
b.spid,a.status,a.machine,
a.action,a.module,a.program
from
v$session a, v$process b, v$transaction c,
v$sqlarea s
Where
a.paddr = b.addr
and a.saddr = c.ses_addr
and a.sql_address = s.address (+)
and to_date(c.start_time,'mm/dd/yy hh24:mi:ss') <= sysdate - (15/1440) -- running for 15 minutes
order by c.start_time
/   

Step 2: desc v$session

Step 3:select sid, serial#,SQL_ADDRESS, status,PREV_SQL_ADDR from v$session where sid='xxxx' //(enter the sid value)

Step 4: select sql_text from v$sqltext where address='XXXXXXXX';

Step 5: select piece, sql_text from v$sqltext where address='XXXXXX' order by piece;

1

Ви можете створити звіт AWR (автоматичне сховище робочого навантаження) з бази даних.

Запустити з командного рядка SQL * Plus:

SQL> @$ORACLE_HOME/rdbms/admin/awrrpt.sql

Прочитайте документ, що стосується створення та розуміння звіту AWR. Це дасть повне уявлення про продуктивність бази даних та проблеми з ресурсами. Ознайомившись із звітом AWR, буде корисно знайти Top SQL, який споживає ресурси.

Крім того, в інтерфейсі 12C EM Express ми можемо генерувати AWR.


0

Ви можете перевірити відомості про тривалі запити, такі як% виконаного та залишився часу, використовуючи наступний запит:

 SELECT SID, SERIAL#, OPNAME, CONTEXT, SOFAR, 
 TOTALWORK,ROUND(SOFAR/TOTALWORK*100,2) "%_COMPLETE" 
 FROM V$SESSION_LONGOPS 
 WHERE OPNAME NOT LIKE '%aggregate%' 
       AND TOTALWORK != 0 
       AND SOFAR <> TOTALWORK;

Повний перелік кроків з усунення несправностей ви можете переглянути тут: Виправлення неполадок під час тривалих сеансів


0
select sq.PARSING_SCHEMA_NAME, sq.LAST_LOAD_TIME, sq.ELAPSED_TIME, sq.ROWS_PROCESSED, ltrim(sq.sql_text), sq.SQL_FULLTEXT
  from v$sql sq, v$session se
 order by sq.ELAPSED_TIME desc, sq.LAST_LOAD_TIME desc;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.