Quando un record è bloccato in Oracle, possiamo sapere quale record è bloccato?


10

Quando un record è bloccato, possiamo sapere quale è bloccato?

Come posso ottenere il record rowid o qualcos'altro?


Posso ottenere alcune informazioni da questo sql

SELECT c.ROW_WAIT_OBJ#,c.ROW_WAIT_FILE#,c.ROW_WAIT_BLOCK#,c.ROW_WAIT_ROW#
   FROM v$locked_object a, dba_objects b, v$session c    
WHERE a.object_id = b.object_id    
    AND a.SESSION_ID = c.sid(+) 

Ho trovato un metodo nel web per ottenere rowid usando la funzione DBMS_ROWID.ROWID_CREATE()

Ma non sembra funzionare.


2
Puoi vedere solo i blocchi che un processo sta aspettando, non quelli che sono trattenuti da una transazione.
a_horse_with_no_name

@a_horse_with_no_name - v $ lock mostra i blocchi detenuti da una transazione
Chris Saxon

@ChrisSaxon: hai ragione. Mi riferivo al fatto che non puoi vedere quali file sono state bloccate - avrei dovuto essere più chiaro.
a_horse_with_no_name

Oracle (al contrario di altri database) non ha alcuna struttura condivisa per i blocchi. Ciò rende il database scalabile, ma d'altra parte non è possibile visualizzare tutti i blocchi. I blocchi vengono archiviati direttamente nei blocchi di database. Nel momento in cui qualcuno viene bloccato, viene creata una struttura "titolare-cameriere". Quindi vedrai questa coppia dentro V$LOCK.
ibre5041,

Risposte:


13

Non puoi davvero elencare tutte le righe che sono bloccate da una sessione. Tuttavia, una volta che una sessione viene bloccata da un'altra, puoi trovare quale sessione / riga la sta bloccando.

Oracle non mantiene un elenco di singoli blocchi di righe. Piuttosto, i lucchetti sono registrati direttamente all'interno delle righe stesse - pensalo come una colonna aggiuntiva.

Puoi vedere quale sessione ha acquisito un blocco su un oggetto attraverso la V$LOCKvista, ma questo elencherà solo informazioni generali, non a livello di riga.

Con questa vista puoi anche scoprire se una sessione è bloccata da un'altra. In tal caso, se una sessione viene bloccata da un'altra sessione, le informazioni sulla riga vengono visualizzate nelle V$SESSIONinformazioni.

Puoi recuperare il rowid, costruiamo un esempio con 2 sessioni:

SESSION1> create table test as select * from all_objects;

Table created

SESSION1> select rowid from test where object_name = 'TEST' for update;

ROWID
------------------
AAMnFEAAaAAALTDAAz

/* setting identifiers to help with identifying this session later */
SESSION2> exec dbms_application_info.set_client_info('012345');

PL/SQL procedure successfully completed

SESSION2> select 1 from test where object_name = 'TEST' for update;
/*  this will block */

La Sessione 2 è ora in attesa sulla Sessione 1. Possiamo scoprire la riga di blocco con:

SESSION1> SELECT o.object_name,
       2         dbms_rowid.ROWID_CREATE (1,
       3                                  s.ROW_WAIT_OBJ#,
       4                                  s.ROW_WAIT_FILE#,
       5                                  s.ROW_WAIT_BLOCK#,
       6                                  s.ROW_WAIT_ROW#) rid
       7     FROM dba_objects o, v$session s
       8    WHERE o.object_id = s.row_wait_obj#
       9      AND s.client_info = '012345';

OBJECT_NAME     RID
--------------- ------------------
TEST            AAMnFEAAaAAALTDAAz

Per ulteriori letture: una descrizione del processo di Tom Kyte .


3

È possibile trovare tutti i blocchi di tabelle in un database Oracle eseguendo la query seguente

select
   c.owner,
   c.object_name,
   c.object_type,
   b.sid,
   b.serial#,
   b.status,
   b.osuser,
   b.machine
from
   v$locked_object a ,
   v$session b,
   dba_objects c
where
   b.sid = a.session_id
and
   a.object_id = c.object_id;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.