Πώς βρίσκουμε ποιά sessions είναι ενεργά και τι query εκτελούν σε μία βάση δεδομένων της Oracle

Πώς βρίσκουμε ποιά sessions είναι ενεργά και τι query εκτελούν σε μία βάση δεδομένων της Oracle
Πώς βρίσκουμε ποιά sessions είναι ενεργά και τι query εκτελούν σε μία βάση δεδομένων της Oracle

Πολλές φορές θα δημιουργηθεί η ανάγκη να πρέπει να ψάξουμε γρήγορα ένα session που εκτελεί ένα query. Μπορεί να θέλουμε να δούμε το πλάνο με το οποίο έτρεξε, τη μνήμη που καταναλώνει, το sql text, το session id, αν έχει uncommited transaction, το undo που δεσμεύει, από ποιόν έτρεξε, αν μπλοκάρετε, το command για να το κάνουμε kill κτ.λ .

Στην ανάγκη αυτή έφτιαξα το query που θα δούμε που συνδυάζει πληροφορία από διάφορα συστημικά views.

Βάζοντας ή αφαιρώντας στο where το σχόλιο “–” μπορούμε να αλλάξουμε τα κριτήρια που ψάχνουμε όπως sql id, sid, sql text κ.τ.λ.

Έχουμε επίσης την δυνατότητα να ξεκινήσουμε trace στο session αυτό και να δούμε την πληροφορία του trace μέσω έτοιμου command στο tkproof (στο command αυτό θα χρειαστεί μετά να βάλουμε το ανάλογο password).

Προσοχή όμως στο πεδίο που διαβάζουμε το trace για το tkproof η πληροφορία έρχεται από το view diag_info που υπάρχει από την έκδοση 11 και μετά, σε περίπτωση που θέλουμε να τρέξουμε σε παλαιότερη έκδοση το βάζουμε σε σχόλιο το πεδίο αυτό.

Το query για τα τρέχων sessions

Με το παρακάτω query μπορούμε να βρούμε την πληροφορία από όποιο session υπάρχει αυτή τη στιγμή.

SELECT 
   h.LOGON_TIME,
   h.SID,
   h.SERIAL#,
   p.SPID,
   h.inst_id,
   u.username,
   h.osuser,
   h.machine,
   h.program,
   h.service_name,
   h.status,
   h.module,
   h.STATE,
   s.sql_text,
   s.SQL_FULLTEXT,
   h.sql_id,
   z.PLAN_HASH_VALUE,
   h.event,
   h.blocking_session_status,
   h.blocking_instance,
   h.blocking_session,      
   round(p.PGA_ALLOc_MEM/1024/1024,1) PGA_ALLOCATED_MB,
   (case tr.status when 'ACTIVE' then 'True' else '' end) as Is_Uncommited,
   round(tr.used_ublk * (select block_size from dba_tablespaces where tablespace_name= 'UNDOTBS1') / (1024*1024),2) as UNDO_SIZE_MB
   ,t.tablespace as Temp_Tablespace
  , round (((t.blocks * 8192) / 1024 / 1024 / 1024), 2) as Temp_Size_GB
   ,'exec sys.dbms_system.set_sql_trace_in_session(' ||h.SID||','||h.SERIAL#||',true);' as start_trace
   ,'tkprof ' ||  (select pap.value from gv$diag_info pap WHERE pap.name = 'Diag Trace' and  pap.inst_id = h.inst_id  ) || '/' || LOWER(SYS_CONTEXT('userenv','instance_name')) ||   '_ora_' || p.spid || '.trc'  || ' /home/oracle/Scripts/trace.txt explain='||u.username||'/Password sort=exeela sys=no' as TKPROOF
   ,h.failover_type
   ,h.failover_method
   ,'alter system kill session '''||sid||', '||h.serial#||', @'||h.inst_id||''' immediate;' KILL_CMD 
   ,'kill -9 '||p.spid kill_spid
FROM
   gv$session h
LEFT JOIN gv$SQLAREA s ON h.sql_hash_value = s.hash_value and h.sql_ADDRESS = s.ADDRESS and h.inst_id = s.inst_id 
LEFT JOIN (select PLAN_HASH_VALUE,SQL_ID,MAX(TIMESTAMP) from gv$sql_plan GROUP BY PLAN_HASH_VALUE,SQL_ID ORDER BY PLAN_HASH_VALUE DESC,MAX(TIMESTAMP) DESC) z ON h.SQL_ID = z.SQL_ID  
LEFT JOIN DBA_USERS u ON h.USER# = u.USER_ID
LEFT JOIN gv$process  p ON p.ADDR = h.PADDR and p.inst_id = h.inst_id
LEFT JOIN gv$transaction tr ON tr.SES_ADDR = h.SADDR and tr.inst_id = h.inst_id 
LEFT JOIN gv$sort_usage t on h.saddr = t.session_addr
WHERE  1=1
and h.sid != (select sys_context('USERENV','SID') from dual)
and h.status = 'ACTIVE'
and h.service_name != 'SYS$BACKGROUND'
--and h.SID = 4533
--and s.sql_id = 'av7nawu9dw14a'
--and s.sql_text LIKE '%session%'
--and h.OSUSER LIKE '%app%'
--and h.blocking_session_status = 'VALID'
--and u.username LIKE '%SYS%'
ORDER BY h.LOGON_TIME DESC
/

Το αποτέλεσμα

Πώς βρίσκουμε ποιά sessions είναι ενεργά και τι query εκτελούν σε μία βάση δεδομένων της Oracle
Πώς βρίσκουμε ποιά sessions είναι ενεργά και τι query εκτελούν σε μία βάση δεδομένων της Oracle
Πώς βρίσκουμε ποιά sessions είναι ενεργά και τι query εκτελούν σε μία βάση δεδομένων της Oracle

Σε περίπτωση που το query είχε εκτελεστεί μερικές ώρες πριν θα πρέπει να το ψάξουμε στο ιστορικό view ACTIVE_SESSION_HISTORY (ASH).

Το query για παλιά sessions

Για να μπορούμε να βρούμε την αντίστοιχη πληροφoρία θα πρέπει να συνδυάσουμε ιστορικά views με την κεντρική πληφορόρία να υπάρχει στο active_session_history (ASH) που αναφέραμε πριν.

Εκεί καταγράφεται πληροφορία αντίστοιχη του gv$session των active sessions και αποθηκεύει μία εγγραφή για την εικόνα που είχε τότε το κάθε session στο κάθε δευτερόλεπτο (sample_time).

select 
  a.inst_id,
  a.sample_time, 
  a.session_id, 
  a.session_serial#,
  u.username, 
  a.user_id,
  a.sql_id,
  s.sql_text,
  p.PLAN_HASH_VALUE,
  a.module, 
  a.machine,
  a.blocking_session_status,
  a.blocking_session,
  a.blocking_session_serial#,
  round(a.temp_space_allocated/1024/1024/1024) temp_usage_in_gb
from GV$ACTIVE_SESSION_HISTORY a 
LEFT JOIN DBA_USERS u ON a.USER_ID = u.USER_ID
LEFT JOIN dba_hist_sqltext s ON a.sql_id = s.sql_id
LEFT JOIN (select distinct PLAN_HASH_VALUE,SQL_ID, TO_CHAR(TIMESTAMP, 'DD-MM-YY HH') as Timin from dba_hist_sql_plan)p ON a.sql_id = p.sql_id and p.Timin = TO_CHAR(a.sample_time, 'DD-MM-YY HH') 
where 1=1
--and s.sql_text like '%FROM CUSTOMER%'
--and a.session_id = 4570 --switch it
--and a.session_serial# = 24864 --switch it
--and u.username LIKE '%SYS%'
--and a.temp_space_allocated/1024/1024/1024 > 3
order by a.sample_time DESC
/
Μοιράσου το

Αφήστε μία απάντηση