6f429244e498457b8400e72e4af683b0 Alberto Blog: ORA-00494: ENQUEUE [CF] HELD FOR TOO LONG - Instance crash in Oracle 10G

lunedì 4 febbraio 2013

ORA-00494: ENQUEUE [CF] HELD FOR TOO LONG - Instance crash in Oracle 10G


Oggi vorrei parlare di un errore che potrebbe causare grossi problemi: ENQUEUE [CF] HELD FOR TOO LONG.
Recentemente mi è capitato durante un backup full on-line con RMAN, che l'istanza andasse in crash.
I Controlfile enqueues solitamente vengono utilizzati per serializzare le transazioni di scrittura, lettura su porzioni condivise del controlfile, queste transazioni sono:
- Checkpointing
- Redo log switch
- Archiving redologs
- Performing instance crash recovery
- Redo log manipulation
- Database begin/end hot backup
- DMLs for NOLOGGING objects

Quando un processo detiene l'enqueue CF per lungo tempo, gli altri processi che devono eseguire delle operazioni saranno in attesa. Tenendo l'enqueue per molto tempo può portare al crash del DB.
C'è un timeout impostato a  900 secondi (15 minuti)  per verificare questo controllo.
Se il processo supera questo timeout, viene eseguito il kill.
Nel mio caso c'erano dei frequenti log switch, e inoltre  il backup viene eseguito in dischi esterni montati in NFS, durante questo backup viene eseguito il backup del controlfile e lo snapshot dello stesso.
Questi dischi vengono utilizzati anche per altri scopi e quindi non sono dedicati a RMAN, quindi avevo il sospetto che il tutto fosse particolarmente lento soprattutto in certi orari.
La combinazione di queste cause hanno fatto sì che Oracle effettuasse il kill del processo CKPT, di fatto mandando in crash tutta l'istanza.
Quindi ho eseguito delle modifiche:

  1. Lo snapshot e il backup del controlfile vengono fatti in dischi locali (ovviamente più veloci) non più in dischi NFS, e questo dovrebbe essere già risolutivo.
  2. Modificato _controlfile_enqueue_timeout da 900 a 1800.
  3. Modificato _kill_enqueue_blocker=1  con questo parametro se l'enqueue holder è un processo di background, il sistema non effettuerà il kill, quindi l'istanza non andrà in crash. Se l'enqueue holder NON è un processo di background, il sistema cercherà di effettuare il kill. Per default questo _kill_enqueue_blocker è impostato a 3 il quale effettua il kill di tutti i processi relativi sia di background che non.
  4. Modificato _kill_controlfile_enqueue_blocker=FALSE, di fatto questo impedisce che per la sessione bloccante di qualsiasi genere sia, non venga eseguito il kill, quindi evitando in ogni caso il crash dell'istanza.

Il valore di default per questo valore è TRUE, rendendo così effettivo il parametro _kill_enqueue_blocker.

Con questo statement, si vedono i settings dei parametri nascosti di Oracle:
select a.ksppinm name,
b.ksppstvl value,
b.ksppstdf deflt,
decode
(A.KSPPITY, 1,
'boolean', 2,
'string', 3,
'number', 4,
'file', a.ksppity) type,
a.ksppdesc description
from
sys.x$ksppi a,
sys.x$ksppcv b
where
a.indx = b.indx
AND
a.ksppinm like '\_%' escape '\'
ORDER BY
NAME;


e con questi si modificano i parametri nascosti:
ALTER SYSTEM SET "_KILL_CONTROLFILE_ENQUEUE_BLOCKER"=FALSE SCOPE=BOTH;
ALTER SYSTEM SET "_CONTROLFILE_ENQUEUE_TIMEOUT"=1800 SCOPE=both;
ALTER SYSTEM SET "_kill_enqueue_blocker"=1 scope=spfile;

Nessun commento:

Posta un commento