spfile im Single-Instance-System: ein Parameter, mehrere Einträge
Vor einiger Zeit erreichte mich eine Anfrage eines Kunden: er hätte in einem SPFILE für eine Single-Instance-Datenbank für einen Parameter mehrere Einträge. Was ist da passiert?
Im SPFILE stellt sich diese Szenario wie folgt dar:
DEMODB@> select sid,name,value from v$spparameter where name='optimizer_index_cost_adj' 2 ; SID NAME VALUE ---------- ------------------------------ ------------------------------ * optimizer_index_cost_adj 100 DEMODB optimizer_index_cost_adj 110 2 rows selected.
Die Einträge mit der SID werden normalerweise nur im RAC gebraucht und es gilt der Grundsatz:
Wenn es einen instanzspezfischen Parameter gibt, dann hat der Vorrag vor einem allgemeingültigen Eintrag (mit “*”)
Man kann dann also in einem größeren RAC z.B. eine Standard-SGA-Größe festlegen und für einzelne Instanzen eine größere SGA.
Einige Parameter müssen im RAC auch instanzspezfisch sein (z.B. INSTANCE_NUMBER, THREAD), andere müssen für alle Instanzen im RAC identisch sein (z.B. DB_BLOCK_SIZE, DB_NAME).
Die bekannten Befehle um die Parameter zu setzen, sind:
REM Allgemeingültig: ALTER SYSTEM SET. .... SID='*'*; REM Instanzspezfisch ALTER SYSTEM SET. .... SID='<SID>';
Wie kann es also auf einem Single-Instanz-System passieren, dass es für einen Parameter zwei Einträge im SPFILE gibt?
Der normale ALTER SYSTEM-Befehl (ohne SID=) setzt immer “*” als Geltungsbereich.
Beispiel:
DEMODB@> alter system set optimizer_index_cost_adj=100 scope=both; System altered. DEMODB@> select sid,name,value from v$spparameter where name='optimizer_index_cost_adj'; SID NAME VALUE ---------- ------------------------------ ------------------------------ * optimizer_index_cost_adj 100 1 row selected.
Aber auch im Single-Instance-System kann man mit “SID=..” arbeiten:
DEMODB@> alter system set optimizer_index_cost_adj=110 scope=both sid='DEMODB'; System altered. DEMODB@> select sid,name,value from v$spparameter where name='optimizer_index_cost_adj' 2 ; SID NAME VALUE ---------- ------------------------------ ------------------------------ * optimizer_index_cost_adj 100 DEMODB optimizer_index_cost_adj 110 2 rows selected.
Wir haben also zwei Einträge zum gleichen Parameter.
Und beim nächsten Startup wird der instanzspezifische Wert genommen:
DEMODB@> startup force; ORACLE instance started. Total System Global Area 2147481656 bytes Fixed Size 8898616 bytes Variable Size 704643072 bytes Database Buffers 1426063360 bytes Redo Buffers 7876608 bytes Database mounted. Database opened. DEMODB@> show parameter optimizer_index_cost_adj NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ optimizer_index_cost_adj integer 110
Im Single-Instanz-System wird eine solche Konfiguration oftmals nicht entdeckt und man wundert sich, warum ein Parameter einen Wert hat der nicht dem mit “ALTER SYSTEM” eingestellten Wert entspricht
Daher ist mein Tipp, das spfile zu bereinigen, d.h.:
- Den “*”-Wert auf den “richtigen” Wert setzen.
- Die instanzspezifische Zeile löschen.
In obigem Beispiel also:
ALTER SYSTEM SET optimizer_index_cost_adj=110 scope=both; alter system reset optimizer_index_cost_adj scope=spfile sid='DEMODB'; DEMODB@> select sid,name,value from v$spparameter where name='optimizer_index_cost_adj' ; SID NAME VALUE ---------- ------------------------------ ------------------------------ * optimizer_index_cost_adj 110 1 row selected.
Wie kann man sein spfile prüfen und so eine Konfiguration erkennen?
Über
select name,min(value),max(value) from v$spparameter group by name having count(*) >1;
kann man rausfinden, ob es Parameter gibt, die mehrfach im spfile eingetragen sind (und dann ggf. aufräumen).
Achtung: der Parameter “control_files” hat pro Controlfile eine Zeile und taucht daher auch in der o.a. Abfrage auf.
Um bei der Kontrolle eines Parameters nur die gültige Zeile abzufragen, könnte man – ab 12c – mit “fetch next 1 rows only” arbeiten:
DEMODB> select sid,name,value from v$spparameter where name='optimizer_index_cost_adj' order by sid desc fetch next 1 rows only; SID NAME VALUE ---------- ------------------------------ ------------------------------ DEMODB optimizer_index_cost_adj 110
Um eine Übersicht für alle Parameter anzuzeigen, die – falls vorhanden – nur den instanzspezfischen Wert anzeigt (und den “*”-Wert unterdrückt),
fällt mir erstmal folgendes SQL ein (es gibt sicher auch elegantere Varianten):
select p1.sid,p1.name,p1.value from v$spparameter p1 where p1.sid=(select instance_name from v$instance) union select p2.sid,p2.name,p2.value from v$spparameter p2 where p2.sid='*' and not exists (select 1 from v$spparameter p3 where p3.name=p2.name and p3.sid<>p2.sid) order by 2;
Amazon-Partner-Link: