È ansible uccidere una singola query in Oracle senza uccidere la sessione?

Mi piacerebbe essere in grado di uccidere la query di un utente in Oracle 10.2.0.4 senza uccidere l’intera sessione. Ciò consentirebbe alla query di terminare, ma non di registrare quell’utente fuori dalla loro sessione, in modo che possano continuare a fare altre domande. Ciò è effettivamente ansible? O il martelletto smussato di uccidere la sessione è l’unico modo per terminare l’esecuzione di una query?

Ho trovato un trucco. Non ho idea di quanto sia sicuro giocare con questo, ma funziona. C’è un evento Oracle, 10237, che è descritto come “simula ^ C (a scopo di test)”.

Devi avere il SID e il SERIAL # della sessione che vuoi interrompere.

Chiama SYS.DBMS_SYSTEM.SET_EV ( sid , serial # , 10237, 1, ”) per triggersre l’evento nella sessione di destinazione. Qualsiasi istruzione attualmente in esecuzione deve essere interrotta (ricezione di “ORA-01013: l’utente ha richiesto l’annullamento dell’operazione corrente”). Finché l’evento è impostato, qualsiasi ulteriore istruzione che la sessione tenta di eseguire terminerà immediatamente con lo stesso errore.

Per distriggersre l’evento, effettuare la stessa chiamata con il quarto parametro impostato su “0”. La sessione sarà quindi in grado di eseguire nuovamente le dichiarazioni.

Si noti che la sessione di destinazione deve rilevare che l’evento è impostato, il che potrebbe richiedere del tempo, o potrebbe non avvenire mai, a seconda di cosa sta facendo. Quindi non puoi semplicemente triggersre e distriggersre rapidamente l’evento. Dovresti accenderlo, verificare che l’istruzione in questione sia stata arrestata e quindi distriggersrla.

Ecco alcuni esempi di codice. Questo deve essere eseguito come blocco anonimo in SQLPlus, con le variabili di sostituzione “sid” e “serial” definite in modo appropriato. È ansible trasformarlo in una stored procedure con quelli come suoi parametri.

DECLARE l_status v$session.status%TYPE; BEGIN dbms_system.set_ev( &sid, &serial, 10237, 1, ''); LOOP SELECT status INTO l_status FROM v$session WHERE sid = &sid and serial# = &serial; EXIT WHEN l_status='INACTIVE'; END LOOP; dbms_system.set_ev( &sid, &serial, 10237, 0, ''); END; 

Sospetto che potrebbe essere ansible dal momento che puoi farlo in TOAD. Mentre è in esecuzione una query, viene visualizzata una finestra di dialogo Annulla che puoi premere per interrompere la query.

Come è implementato non lo so, ma sarei molto interessato anche a scoprirlo.

Se stai usando java, c’è il metodo java.sql.Statement cancel () che dovrebbe farlo. Vedi qui per alcune note e limitazioni …

http://download.oracle.com/docs/cd/B14117_01/java.101/b10979/tips.htm#BACDAICJ

Puoi guardare i limiti delle risorse:

“Se un utente supera un limite di risorse a livello di chiamata, Oracle interrompe l’elaborazione dell’istruzione, ripristina l’istruzione e restituisce un errore, tuttavia tutte le precedenti dichiarazioni della transazione corrente rimangono intatte e la sessione dell’utente rimane connessa. ”

Ciò presuppone che il motivo dell’annullamento di SQL sia un limite di risorse, piuttosto che l’aggiornamento dell’insieme di righe errate (ad esempio). Ho il sospetto che non sarebbe in grado di influenzare correntemente l’esecuzione di SQL attraverso l’aggiunta di un limite di risorse.

 http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/security.htm#i13767 http://download.oracle.com/docs/cd/B19306_01/server.102/b14231/dbrm.htm#i1010776 

Idealmente l’applicazione dell’utente dovrebbe avere la possibilità di cancellare una query (tramite OCICancel o equivalente).

In caso contrario, il migliore sarebbe utilizzare Resource Manager (se su Oracle EE), è ansible utilizzare DBMS_RESOURCE_MANAGER.SWITCH_CONSUMER_GROUP_FOR_SESS per impostare la sessione di destinazione sul gruppo di utenti CANCEL_SQL.

Un altro hack per cancellare la query di altre sessioni, che però non funziona con le sessioni client SQL di sqlplus, sarebbe inviare un segnale urgente al processo Oracle usando kill -URG (è un hack, non per l’uso quotidiano)

Ho scritto sul motivo per cui funziona qui:

http://blog.tanelpoder.com/2010/02/17/how-to-cancel-a-query-running-in-another-session/