Comment vérifier la base de données Oracle pour les requêtes de longue durée


99

Mon application, qui utilise une base de données Oracle, ralentit ou semble s'être complètement arrêtée.

Comment savoir quelles requêtes sont les plus chères, afin que je puisse approfondir mes recherches?

Réponses:


135

Celui-ci montre SQL qui est actuellement "ACTIF": -

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
/

Cela montre les verrous. Parfois, les choses vont lentement, mais c'est parce qu'il est bloqué en attente d'un verrou:

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
/

C'est un bon pour trouver des opérations longues (par exemple des analyses de table complètes). Si c'est à cause de nombreuses opérations courtes, rien n'apparaîtra.

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
Existe-t-il un moyen de supprimer en toute sécurité de telles requêtes si elles s'exécutent pendant plus de x minutes? Merci pour la réponse @UmberFerrule
TommyT

2
@TommyT Vous pouvez utiliser alter system kill sessioncomme décrit ici: docs.oracle.com/cd/B28359_01/server.111/b28310/…
WW.

37

Essayez ceci, cela vous donnera des requêtes en cours d'exécution pendant plus de 60 secondes. Notez qu'il imprime plusieurs lignes par requête en cours si le SQL a plusieurs lignes. Regardez le sid, numéro de série pour voir ce qui va ensemble.

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

Je lance cette requête et il me dit que ce n'est pas une déclaration invalide

C'est valide. Je l'ai testé. Quel outil utilisez-vous pour interroger? Il peut être confondu avec le signe #. Essayez de changer le début et la fin comme ceci: "sélectionnez * à partir de ... ordre par sid, q.piece"
Carlos A. Ibarra

2
De plus, vous devrez l'exécuter avec un compte privé ayant accès à v $ session, v $ sqltext_with_newlines
WW.

Cela fonctionne mais renvoie le texte SQL de la requête au format très étrange.
Bernhard Döbler

7

v $ session_longops

Si vous recherchez sofar! = Totalwork, vous verrez ceux qui ne sont pas terminés, mais les entrées ne sont pas supprimées lorsque l'opération est terminée, vous pouvez donc y voir beaucoup d'historique.


Bon indice. Également discuté en détail ici .
dma_k du

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

Vous pouvez générer un rapport AWR (référentiel de charge de travail automatique) à partir de la base de données.

Exécutez à partir de la ligne de commande SQL * Plus:

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

Lisez le document relatif à la façon de générer et de comprendre un rapport AWR. Il donnera une vue complète des performances de la base de données et des problèmes de ressources. Une fois que nous serons familiarisés avec le rapport AWR, il sera utile de trouver Top SQL qui consomme des ressources.

De plus, dans l'interface utilisateur 12C EM Express, nous pouvons générer un AWR.


0

Vous pouvez vérifier les détails des requêtes de longue durée comme le% terminé et le temps restant à l'aide de la requête ci-dessous:

 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;

Pour obtenir la liste complète des étapes de dépannage, vous pouvez vérifier ici: Dépannage des sessions longues


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;

0

Vous pouvez utiliser la vue v $ sql_monitor pour rechercher des requêtes qui s'exécutent depuis plus de 5 secondes. Cela ne peut être disponible que dans les versions Enterprise d'Oracle. Par exemple, cette requête identifiera les requêtes à exécution lente de mon service TEST_APP:

select to_char(sql_exec_start, 'dd-Mon hh24:mi'), (elapsed_time / 1000000) run_time,
       cpu_time, sql_id, sql_text 
from   v$sql_monitor
where  service_name = 'TEST_APP'
order  by 1 desc;

Remarque elapsed_time est en microsecondes donc / 1000000 pour obtenir quelque chose de plus lisible

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.