Seiten

Dienstag, 5. November 2013

APEX - Passwort speichern in der Login-Form erlauben

Standardmäßig verhindert APEX das Abspeichern von Passwörtern im Browser. Die Suche nach der Einstellung, die geändert werden muss, war etwas mühselig. Damit der nächste nicht so lang wie ich suchen muss, hier die Lösung: Das Speichern des Passwortes wird durch den Parameter autocomplete der Login-Form von APEX verhindert, der immer auf "off" gesetzt ist. Den Parameter ändert man weder im Template, noch in der Region und auch nicht über irgend welche CSS/HTML-Spielereien am Item. Nein, man geht im Applicationbuilder auf die Loginseite der Application und über Edit Page -> Security -> Form Auto Complete ändert man den Wert "off" auf "on". Apply Changes. Fertig.
Die Lösung findet man auch im Application Builder User's Guide - wenn man weiß, wonach man suchen muss.

Montag, 28. Oktober 2013

CRSCTL – RAC-Statusausgabe und -verwertung

Eine einfache Möglichkeit, den Status eines RAC auszugeben, bietet CRSCTL.
D:\>crsctl status resource –t 
oder kürzer:
D:\>crsctl stat res –t
--------------------------------------------------------------------------------
NAME           TARGET  STATE        SERVER                   STATE_DETAILS
--------------------------------------------------------------------------------
Local Resources
--------------------------------------------------------------------------------
ora.LISTENER.lsnr
               ONLINE  OFFLINE      rac2
--------------------------------------------------------------------------------
Cluster Resources
--------------------------------------------------------------------------------
ora.LISTENER_SCAN3.lsnr
      1        ONLINE  OFFLINE
ora.orcl.db
      1        OFFLINE OFFLINE                               Instance Shutdown
      2        OFFLINE OFFLINE
Dieser Befehl liefert - gesteuert durch den Parameter "-t" eine eingeschränkte tabellarische Ansicht aller Ressourcen. "-h" liefert möglicher weitere Parameter.
     resName [...]     Ein oder mehrere durch Leerzeichen getrennte Ressourcennamen
     -w                Ressourcenfilter (Beispiel: "TYPE = ora.database.type")
     -p                Gibt statische Konfiguration aus
     -v                Gibt Laufzeitkonfiguration aus\r
     -e                Wertet Sonderwerte einer Ressourceninstanz aus\r
     -f                Gibt vollständige Konfiguration aus\r
     -l                Gibt alle Kardinalitäts- und Grad-Member aus
     -g                Prüft, ob Ressourcen registriert sind\r
     -k                Kardinalitäts-ID\r
     -d                Grad-ID\r
     -n                Servername\r
     -s                Ruft Zielserver für Umspeichern ab\r
     -t                Tabellarische Anzeige
Will man das Ergebnis verskripten, ist die tabellarische Ausgabe ungeeignet. Man lässt besser den Schalter „-t“ weg.
D:\>crsctl stat res
NAME=ora.LISTENER.lsnr
TYPE=ora.listener.type
TARGET=ONLINE
STATE=OFFLINE

NAME=ora.LISTENER_SCAN3.lsnr
TYPE=ora.scan_listener.type
TARGET=ONLINE
STATE=OFFLINE

NAME=ora.orcl.db
TYPE=ora.database.type
TARGET=OFFLINE, OFFLINE
STATE=OFFLINE, OFFLINE
Dieses Ergebnis kann man schon besser in z.B. der Powershell verarbeiten.
Die Ausgabe ist allerdings im Normalfall allumfassend.

Filter - Ich will nur Probleme sehen!

Wenn man nicht die Dinge sehen will, die in Ordnung sind, sondern nur die, die Probleme bedeuten, kann die Ausgabe mit „-w“ gefiltert werden.
D:\skripte>crsctl stat res -t -w "STATE != ONLINE"
Oder
D:\skripte>crsctl stat res -t -w "TARGET != ONLINE"
Das lässt sich hervorragend kombinieren:
D:\skripte>crsctl stat res -t -w "(TARGET != ONLINE OR STATE != ONLINE)"
--------------------------------------------------------------------------------
NAME           TARGET  STATE        SERVER                   STATE_DETAILS
--------------------------------------------------------------------------------
Local Resources
--------------------------------------------------------------------------------
ora.LISTENER.lsnr
               ONLINE  OFFLINE      rac2
ora.gsd
               OFFLINE OFFLINE      rac1
               OFFLINE OFFLINE      rac2
ora.ons
               ONLINE  OFFLINE      rac2
--------------------------------------------------------------------------------
Cluster Resources
--------------------------------------------------------------------------------
ora.LISTENER_SCAN3.lsnr
      1        ONLINE  OFFLINE
ora.orcl.db
      1        OFFLINE OFFLINE                               Instance Shutdown
      2        OFFLINE OFFLINE
GSD und ONS sind uninteressant? OK:
D:\skripte>crsctl stat res -t -w "((TARGET != ONLINE) OR (STATE != ONLINE)) AND (NAME != ora.gsd) AND (NAME != ora.ons)"
Besser als NAME ist die Verwendung von TYPE:
D:\skripte>crsctl stat res -t -w "((TARGET != ONLINE) OR (STATE != ONLINE)) AND (TYPE != ora.gsd.type) AND (TYPE != ora.ons.type)"
--------------------------------------------------------------------------------
NAME           TARGET  STATE        SERVER                   STATE_DETAILS
--------------------------------------------------------------------------------
Local Resources
--------------------------------------------------------------------------------
ora.LISTENER.lsnr
               ONLINE  OFFLINE      rac2
-------------------------------------------------------------------------------
Cluster Resources
--------------------------------------------------------------------------------
ora.LISTENER_SCAN3.lsnr
      1        ONLINE  OFFLINE
ora.orcl.db
      1        OFFLINE OFFLINE                               Instance Shutdown
      2        OFFLINE OFFLINE 
Und das Ganze noch einmal ohne "-t":
D:\skripte>crsctl stat res -w "((TARGET != ONLINE) OR (STATE != ONLINE)) AND (TYPE != ora.gsd.type) AND (TYPE != ora.ons.type)"
NAME=ora.LISTENER.lsnr
TYPE=ora.listener.type
TARGET=ONLINE
STATE=OFFLINE

NAME=ora.LISTENER_SCAN3.lsnr
TYPE=ora.scan_listener.type
TARGET=ONLINE
STATE=OFFLINE

NAME=ora.orcl.db
TYPE=ora.database.type
TARGET=OFFLINE, OFFLINE
STATE=OFFLINE, OFFLINE

Weiterverarbeitung in der Powershell

Auf Grundlage einer gefilterten crsctl-Ausgabe lassen sich verschiedene Möglichkeiten umsetzen.
So könnte man einen Listener, der OFFLINE gegangen ist, neu starten oder den Admin per Email über Probleme benachrichtigen lassen.
Hier ein sehr minimalistisches Beispiel:
$a = crsctl stat res -w "((TARGET != ONLINE) OR (STATE != ONLINE)) AND ((TYPE = ora.listener.type) OR (TYPE = ora.scan_listener.type))";
$to      = "admin@meinefirma.de"
$from    = "rac@meinefirma.de"
$smtp    = "email.meinefirma.de"
$body    = '';
$subject = '';
 
if($a){
    $subject = "Listener OFFLINE!";
    $body    = "Einer oder mehrere Listener sind offline!`r`n`r`n"
    $body   += [string]$a -replace " ", "`r`n"
}
else{}

send-mailmessage -to $to -from $from -body $body -subject $subject -smtpserver $smtp
Das Skript führt zunächst crsctl aus und filtert nach Listenern, die nicht ONLINE sind.
Die Rückgabe wird in eine Email gepackt und versendet.

Dienstag, 24. September 2013

Korrupte Blöcke bekämpfen mit DBMS_REPAIR

Eine plötzliche Blockcorruption ist keine angenehme Überraschung. Wenn sich die Malaise nicht per Recovery beheben lässt, kann dbms_repair helfen.
Also.
Der Admin stellt auf einmal fest, dass Tabelle xyz_table dank einer blockcorruption nicht komplett lesbar ist oder sich nicht mit dpexp/exp exportieren lässt. (z.B.: ORA-31693: ...ORA-02354: ...ORA-00600: internal error code, arguments: [25027], [4], [394435]...)
Ein Recovery wird verworfen, da die Koruption schon zu lange existiert und andere Daten verloren gingen.
Die Lösung ist DBMS_REPAIR:
Zunächst werden die korrupten Blöcke mit dbms_repair markiert, damit die betroffene Tabelle wieder komplett gelesen/exportiert werden kann.
DBMS_REPAIR benötigt dafür eine Repairtabelle. Diese legt man hiermit an:
SET SERVEROUTPUT ON
DECLARE num_corrupt INT;
BEGIN

num_corrupt := 0;

DBMS_REPAIR.CHECK_OBJECT (
     SCHEMA_NAME => 'BEISPIEL',
     OBJECT_NAME => 'XYZ_TABLE',
     REPAIR_TABLE_NAME => 'REPAIR_TABLE',
     CORRUPT_COUNT =>  num_corrupt);
DBMS_OUTPUT.PUT_LINE('number corrupt: ' || TO_CHAR (num_corrupt));

END;
/

Anschließend jagt man DBMS_REPAIR über die kaputte Tabelle:

SET SERVEROUTPUT ON
DECLARE num_corrupt INT;
BEGIN

num_corrupt := 0;

DBMS_REPAIR.CHECK_OBJECT (
     SCHEMA_NAME => 'BEISPIEL',
     OBJECT_NAME => 'XYZ_TABLE',
     REPAIR_TABLE_NAME => 'REPAIR_TABLE',
     CORRUPT_COUNT =>  num_corrupt);
DBMS_OUTPUT.PUT_LINE('number corrupt: ' || TO_CHAR (num_corrupt));

END;
/

Jetzt kann man in der Repairtabelle nachsehen, was im Argen liegt:
SELECT OBJECT_ID, TABLESPACE_ID tsid,
   RELATIVE_FILE_ID fileid, BLOCK_ID,
   CORRUPT_TYPE, CORRUPT_DESCRIPTION, REPAIR_DESCRIPTION
FROM REPAIR_TABLE;

Hier die ausführliche CORRUPT_DESCRIPTION:

Block Checking: DBA = 16780739, Block Type = KTB-managed data block
data header at 0xf25ec07c
kdbchk: row locked by non-existent transaction
        table=0   slot=1
        lockid=6   ktbbhitc=3

Jetzt, wo man weiß, welche Block-ID – in diesem Fall die 3523 – betroffen ist, kann man mit diesem Select sogar den Inhalt finden und anzeigen:
SELECT * FROM XYZ_TABLE
WHERE DBMS_ROWID.ROWID_BLOCK_NUMBER(rowid) = 3523

Das sieht wirklich kaputt aus... aber mit ein wenig Kenntnis des Datenmodells und der Anwendung weiß man jetzt vielleicht sogar, wie man an die korrekten Daten kommt.
Anschließend kann die Tabelle korrigiert werden - z.B. mittels DBMS_REPAIR.FIX_CORRUPT_BLOCKS().

Dienstag, 20. August 2013

Thoth - APEX mit dem IIS

Oracle bietet von Haus aus bereits 3 verschiedene Web-Listener für den DB-Zugriff über APEX:
  1. das embedded PL/SQL Gateway,
  2. den APEX-Listener und
  3. Oracle HTTP Server (OHS) mit mod_plsql - einem Apache-Webserver.
Das sollte an und für sich genügen.

Aber: Sofern die eigene Firma den Einsatz eines Microsoft IIS vorschreibt, sieht man alt aus.
Morten Braten hat hier glücklicherweise einen Ausweg parat: Thoth Gateway - PL/SQL Gateway Module for Microsoft IIS
Wenn man die Installation hinter sich gebracht hat, tut Thoth klaglos seinen Dienst.

Man umgeht durch den Einsatz von Thoth aber andere Probleme in Bezug auf Lizenzkosten und Virtualisierung:
Falls man den OHS nicht auf einem DB-Server einsetzen möchte - und das dürfte im produktiven Einsatz die Regel sein - muss z.B. Oracle Web Tier erworben werden. Das kann sehr schnell kostspielig werden, da hier wieder die üblichen Fallen lauern. (Prozessoranzahl, Virtualisierung...)

Ein Nachteil von Thoth, der nicht verschwiegen werden soll:
Das Gateway wird derzeit von nur einem Entwickler gepflegt, ist dafür aber Open Source und bereits in Version 1.3.7 verfügbar.

Dienstag, 18. Juni 2013

Wie stoppt man ein "EXPIRE(GRACE)" nach einer PROFILE-Panne?

Wenn man das Default-Profile ändert oder der falschen Usergruppe das falsche Profile zuordnet, haben ganz schnell eine Menge User ein ablaufendes Passwort.

SQL >select count(*) from dba_users
  2  where  account_status = 'EXPIRE(GRACE)';

  COUNT(*)
----------
        78

1 Zeile wurde ausgewählt.

Jetzt ist guter Rat teuer. Ein "alter user account_status 'OPEN';" gibt es nicht. Die Passwörter laufen ab. Man kann nichts dagegen tun, außer das Passwort zu ändern.
Da man die Passwörter aller User für gewöhnlich nicht kennt, hilft hier nur die Passwortänderung mit dem Passwordhash.
Diesen bekommt man in 11g aus der sys.user$. Mit diesem Skript lässt man sich in sqlplus gleich noch ein sql-Skript erstellen, welches die Passworthashes schreibt und damit den Accountstatus zurücksetzt:
rem unexpire_users.sql, MW, 18.06.2013

spool alter_user_unexpire.sql
set echo off
set heading off
set linesize 200
set feedback off

SELECT 'ALTER USER ' || DU.USERNAME || ' IDENTIFIED BY VALUES '''|| SU.PASSWORD ||''';' 
FROM SYS.USER$ SU
INNER JOIN SYS.DBA_USERS DU ON DU.USERNAME = SU.NAME
WHERE DU.ACCOUNT_STATUS = 'EXPIRED(GRACE)'
ORDER BY DU.PROFILE, DU.DEFAULT_TABLESPACE, DU.USERNAME;

spool off
exit

Und jetzt das erstellte SQL-Skript ausführen und fertig:
SQL >@alter_user_unexpire
...
...
SQL >select count(*) from dba_users
  2  where  account_status = 'EXPIRE(GRACE)';

  COUNT(*)
----------
         0

1 Zeile wurde ausgewählt.

Donnerstag, 13. Juni 2013

Clonen einer DB auf dem RAC

Das Duplizieren von Datenbanken auf einem RAC ist gar nicht so schwer.
Das erste, was man sich vergegenwärtigen muss, wenn man auf dem RAC eine DB clonen/duplizieren möchte ist: Es ist im Prinzip das gleiche wie auf einem "normalen" Server - normal meint hier: Single-Node - nur irgendwie komplizierter. Aber wen wundert das schon. ;)
Im Prinzip steht alles, was man wissen muss hier drin: Oracle® Database Backup and Recovery User's Guide
Speziell diese Kapitel sollen helfen:
Wer schon einmal eine DB auf einem "normalen" Server dupliziert hat, der weiß im Prinzip schon alles. Er musste dabei auf diverse Details seiner Systemumgebung achten - zum Beispiel:
  • Wird von ASM nach ASM, von ASM ins Filesystem oder umgekehrt dupliziert?
  • Wird OMF von target oder von auxiliary oder von beiden genutzt?
  • Duplizieren wir "backup based", "without/with target connection", "with/without recovery catalog" oder lieber nur "from active database"? 
  • ...Hä? ;)
...und das Ganze jetzt auch noch auf dem RAC...

Das Wichtigste gleich vorneweg:
Es ist unmöglich von RAC-DB zu RAC-DB zu duplizieren.
Aber: Man kann eine RAC-DB in eine Single-Instance-DB duplizieren und diese anschließend zu einer RAC-DB machen.
Na geht doch. 

Ausgangslage

Ich mache es mir einfach:
Wir haben einen 2-Knoten-RAC mit ASM und OMF - keine ausgefallenen Geschichten. Im Falle eines Standard-Edition-Systems und noch dazu auf Windows sollte dies in 99% der Fälle passen.
Auf dem RAC läuft die zu duplizierende DB (target), die auf dem selben RAC dupliziert werden soll. In der ASM ist genug Platz. Die DB läuft im Archivelog-Modus und ein RMAN-Backup ist eingerichtet.
Die Duplizierung läuft "backup based", "with target connection" und "without recovery catalog".
Das Server-OS ist (leider) ein WindowsServer 2008 R2. (englisch) 

Vorbereitung

Die neue Instanz (auxiliary) muss eingerichet werden. Hierfür sind eine Reihe von Schritten notwendig.

1. Dienst und Passwortdatei anlegen

D:\>set ORACLE_HOME=D:\oracle\product\11.2.0.3\dbhome_1

D:\>oradim -new -sid DUPLO
Instanz erstellt.

D:\>orapwd file=d:\oracle\product\11.2.0.3\dbhome_1\database\pwdDUPLO.ora
password=<SYSPWD>
Es bietet sich an, hier das gleiche Passwort zu nutzen, wie in der target-DB.

2. Parameterfile anlegen

Am besten kopiert man die init.ora der target-Instanz und kommentiert alle RAC-Parameter aus oder entfernt sie.
Für eine initiale Duplizierung sind nur wenige Parameter notwendig.
#initDUPLO.ora
### notwendige Parameter ###
db_name='DUPLO'
db_create_file_dest='+DATA'
#Falls Datafile-Konvertierungen nötig sind: DB_FILE_NAME_CONVERT
#DB_FILE_NAME_CONVERT='+DUPSOURCE','+DUPDEST'
control_files='+DATA(CONTROLFILE)/duplo/duplo_control01.ctl','+FRA(CONTROLFILE)/duplo/duplo_control02.ctl'
db_recovery_file_dest='+FRA'
db_recovery_file_dest_size=52428800000
#Falls Logfile-Konvertierungen nötig sind: LOG_FILE_NAME_CONVERT
#LOG_FILE_NAME_CONVERT='+DGDUPSOURCE','+DGDUPDEST'
log_archive_dest='+FRA'

### Hier die RAC-Parameter ###
cluster_database=false
#cluster_database_instances=2
#duplo1.instance_number=1
#duplo2.instance_number=2

### optionale Parameter ###
db_domain=''
db_block_size=8192
sga_target=3969908736
pga_aggregate_target=1323302912
log_archive_format='ARC%S_%R.%T'
db_create_online_log_dest_1='+FRA'
archive_lag_target=1800
[edit] hinzugefügt am 10.09.2013:

3. Die Datenbank und die Instanz in der Clusterware registrieren

Auf einem normalen DB-Server ohne Grid-Infrastruktur macht man die Instanzen über einen Eintrag in der listener.ora bekannt.
Auf dem RAC bemüht man eine Reihe von srvctl-Kommandos:
D:\>set ORACLE_HOME=D:\oragrid\11.2.0.3

D:\>srvctl add database -d DUPLO -o d:\oracle\product\11.2.0.3\dbhome_1\ -c SINGLE -x racnode01

rem D:\>srvctl add instance -d DUPLO -i DUPLO -n racnode01

D:\>srvctl config database -d DUPLO
Eindeutiger Datenbankname: DUPLO
Datenbankname:
Oracle-Standardverzeichnis: d:\oracle\pr
Oracle-Benutzer: nt authority\system
Spfile:
Domain:
Startoptionen: open
Stoppoptionen: immediate
Datenbankrolle: PRIMARY
Verwaltungs-Policy: AUTOMATIC
Server-Pools: DUPLO
Datenbankinstanz: DUPLO
DatentrΣgergruppen:
Mount Point-Pfade:
Services:
Typ: SINGLE
Die Datenbank ist administratorverwaltet
[/edit]

4. spfile anlegen

Zunächst startet man die Instanz der auxiliary-DB im nomount-Modus und erzeugt das spfile in der ASM.
Instanz starten:
D:\>set ORACLE_SID=DUPLO

D:\>set ORACLE_UNQNAME=DUPLO

D:\>sqlplus /nolog

SQL*Plus: Release 11.2.0.3.0 Production on Di Jun 11 20:16:35 2013

Copyright (c) 1982, 2011, Oracle.  All rights reserved.

SQL >conn / as sysdba
Bei einer nicht hochgefahrenen Instanz angemeldet.

SQL >startup nomount pfile='D:\oracle\product\11.2.0.3\dbhome_1\database\initDUPLO.ora';
ORACLE-Instanz hochgefahren.

Total System Global Area 3958439936 bytes
Fixed Size                  2261280 bytes
Variable Size             771755744 bytes
Database Buffers         3170893824 bytes
Redo Buffers               13529088 bytes
11.06.13 SYS AS SYSDBA@DUPLO>
SPFILE in der ASM erzeugen:
SQL >create spfile='+DATA' from pfile='d:\oracle\product\
11.2.0.3\dbhome_1\database\initDUPLO.ora';

Datei erstellt.

Abgelaufen: 00:00:00.32
11.06.13 SYS AS SYSDBA@DUPLO> 

Ein must have (1)

Hier halten wir kurz inne und nehmen uns Zeit für ein wenig Feinschliff.
Das spfile wird in der ASM automatisch unter '+DATA/DUPLO/PARAMETERFILE/' angelegt und bekommt wegen OMF einen nicht merkbaren Namen:
ASMCMD [+] > ls +data/duplo/parameterfile/
spfile.303.817894325
Es ist schöner, wenn man mit einem spfile arbeiten kann, das nicht diese Zahlen hat. Wenn man das trotz OMF haben will, ist MKALIAS in ASMCMD das Mittel der Wahl - also ein Link:
ASMCMD [+] > mkalias +DATA/DUPLO/PARAMETERFILE/spfile.303.817894325 +DATA/DUPLO/spfileduplo.ora
Hier sieht man dann schön das Ergebnis:
ASMCMD [+] > ls +data/duplo/
CONTROLFILE/
DATAFILE/
PARAMETERFILE/
duplo_control01.ctl
spfileduplo.ora
ASMCMD [+] >
Hier fehlt noch ein Detail: Die Instanz weiß nicht wo das spfile liegt und bedient sich weiter gemäß den Defaultvorgaben. Dazu aber später mehr.

 Die Duplizierung

1. RMAN - connect & duplicate

Jetzt kann man sich mit RMAN einloggen und die DB duplizieren:
D:\>rman target sys/<SYSPWD>@orcl auxiliary /

Recovery Manager: Release 11.2.0.3.0 - Production on Di Jun 11 20:52:29 2013

Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.

Mit Ziel-Datenbank verbunden: ORCL (DBID=4167151783)
Bei Hilfsdatenbank angemeldet: DUPLO (nicht mit MOUNT angeschlossen)

RMAN> duplicate target database to DUPLO until time "TO_DATE('11.06.2013:20:30','DD.MM.YYYY:HH24:MI')";

Starten Duplicate Db um 11.06.13
Kontrolldatei der Zieldatenbank wird anstelle des Recovery-Katalogs verwendet
Zugewiesener Kanal: ORA_AUX_DISK_1
Kanal ORA_AUX_DISK_1: SID=922 Device-Typ=DISK

...
...

Inhalt von Speicher-Skript:
{
   Alter clone database open resetlogs;
}
Speicher-Skript wird ausgeführt

Datenbank geöffnet
Beendet Duplicate Db um 11.06.13

RMAN>

An dieser Stelle wäre noch Platz für Nacharbeiten bzw. Umkonfigurieren der DB. (Onlinelogs hinzufügen, Pfadanpassungen...)

2. Aus 1 mach 2 (1)

Das pfile muss jetzt angepasst werden um aus der Singleinstancedatenbank eine RAC-DB machen zu können.
Hierzu werden dien RAC-Parameter in der init.ora editiert. Anschließend wird mit dem pfile das spfile in der ASM erzeugt.
Das reicht aber noch nicht aus. Die DB muss dann in den Cluster integriert werden
RAC-Parameter im pfile:
#initDUPLO.ora
...

### Hier die RAC-Parameter anpassen###
cluster_database=true
cluster_database_instances=2
duplo1.instance_number=1
duplo2.instance_number=2

...
jetzt das spfile erzeugen:
SQL >create spfile='+DATA/DUPLO/spfileduplo.ora' from pfile='d:\oracle\product\11.2.0.3\dbhome_1\database\initDUPLO.ora';

Datei erstellt.

Abgelaufen: 00:00:00.21
SQL >shu immediate
Datenbank geschlossen.
Datenbank dismounted.
ORACLE-Instanz heruntergefahren.
SQL >
Ohne den Alias auf das spfile hätte hier die Pfadangabe auf das bestehende spfile mit dem OMF-Namen erfolgen müssen. Zum Beispiel:
SQL >create spfile='+DATA/DUPLO/PARAMETERFILE/spfile.303.817894325' from pfile='d:\oracle\product\11.2.0.3\dbhome_1\database\initDUPLO.ora';

3. Ab in den Cluster

Jetzt wird zunächst das ORACLE_HOME aufs Grid geschwenkt und die Datenbank registriert:
D:\>set ORACLE_HOME=D:\oragrid\11.2.0.3

D:\>srvctl add database -d DUPLO -o d:\oracle\product\11.2.0.3\dbhome_1\
Die Prüfung der Konfiguration ergibt, dass die DB registriert ist, aber keine Datenbankinstanzen besitzt.
D:\>srvctl config database -d DUPLO
Eindeutiger Datenbankname: DUPLO
Datenbankname:
Oracle-Standardverzeichnis: d:\oracle\product\11.2.0.3\dbhome_1\
Oracle-Benutzer: nt authority\system
Spfile:
Domain:
Startoptionen: open
Stoppoptionen: immediate
Datenbankrolle: PRIMARY
Verwaltungs-Policy: AUTOMATIC
Server-Pools: DUPLO
Datenbankinstanzen:
Datenträgergruppen:
Mount Point-Pfade:
Services:
Typ: RAC
Die Datenbank ist administratorverwaltet

D:\>
Die Registrierung der Datenbankinstanzen ist der nächste Schritt. Die notwendige Syntax erhält man von SRVCTL, wenn man mit ihm spricht:
D:\>srvctl add instance -h

Fügt eine Datenbankinstanzkonfiguration zu Oracle Clusterware hinzu.

Verwendung: srvctl add instance -d  -i  -n  [-f]
    -d            Eindeutiger Name für die Datenbank
    -i            Instanzname
    -n            Knotenname
    -f                       Hinzufügen-Vorgang erzwingen, selbst wenn einige Ressourcen gestoppt werden
    -h                  Verwendung drucken
Kommunikation ist eben alles. ;)
Man kann sich übrigens mit fast allen Oracle-Kommadozeilenprogrammen so angeregt unterhalten und spart sich auf diese Weise den zeitraubenden Blick in Handbücher.
D:\>srvctl add instance -d DUPLO -i DUPLO1 -n racnode01

D:\>srvctl add instance -d DUPLO -i DUPLO2 -n racnode02

Das must have (2)

Jetzt sagen wir der DB noch schnell, wo das spfile - bzw. sein Alias - liegt:
D:\>srvctl modify database -d duplo -p +DATA/duplo/spfileduplo.ora
Konfiguration prüfen:
D:\>srvctl config database -d DUPLO
Eindeutiger Datenbankname: DUPLO
Datenbankname:
Oracle-Standardverzeichnis: d:\oracle\product\11.2.0.3\dbhome_1\
Oracle-Benutzer: nt authority\system
Spfile: +DATA/duplo/spfileduplo.ora
Domain:
Startoptionen: open
Stoppoptionen: immediate
Datenbankrolle: PRIMARY
Verwaltungs-Policy: AUTOMATIC
Server-Pools: DUPLO
Datenbankinstanzen: DUPLO1,DUPLO2
Datenträgergruppen:
Mount Point-Pfade:
Services:
Typ: RAC
Die Datenbank ist administratorverwaltet

D:\> 
Das spfile in der ASM ist bekannt und die Instanzen ebenfalls - perfekt.

Abschlussarbeiten und DB-Start

Jetzt sind beide Instanzen registriert, wie man sieht.
Die Instanzen kann man aber noch nicht starten. Hierfür sind noch zusätzliche Handgriffe zu erledigen.
  • Auf jedem Knoten muss ein pfile für die jeweilige Instanz existieren.
  • Jedes dieser pfiles kann auf "seine" Instanz angepasst sein. Es ist beispielsweise möglich, jeder Instanz unterschiedliche Mengen an Speicher zur Verfügung zu stellen. Best Practice ist aber: Alle Knoten sind möglichst identisch konfiguriert.
  • Die pfiles benötigen den Pfad zum gemeinsamen spfile in der ASM.

Aus 1 mach 2 (2)

Zunächst wird also auf jedem Knoten unter %ORACLE_HOME%/database ein pfile angelegt. Die pfiles sind einfache eine Kopie des bisher verwendeten pfile mit dem jeweiligen Instanznamen:
  1. Knoten 1: initDUPLO.ora -> initDUPLO1.ora
  2. Knoten 2: initDUPLO.ora -> initDUPLO2.ora
Der Pfad zum spfile wird ganz am Ende des pfiles eingetragen:
#initDUPLO.ora
### notwendige Parameter ###
db_name='DUPLO' 

...
...

SPFILE='+DATA/duplo/spfileduplo.ora'
Ein pfile, das nur den Verweis auf das spfile in der ASM enthält, reicht auch aus.

Fazit

Im Prinzip ganz einfach. Man muss es nur machen.:)
Das Clonen von RAC-DB in anderen Konstellationen - z.B. von einem RAC auf einen zweiten Cluster - funktioniert in leicht abgewandelter Form, wenn man das backup based duplicate durchführt.
Leider ist das Duplizieren "from active database" nicht so einfach, weil es da nicht ausreicht, sich per
External User Authentication mit der DB zu verbinden.

Mittwoch, 12. Juni 2013

Mobile-Apex-Tutorial

Carsten Czarski hat in der Apex Community ein erstklassiges Tutorial veröffentlicht, das zeigt, wie schnell und einfach Webseiten für mobile Engeräte mit APEX erstellt werden können.
Workshopartig, über 10 Aufgaben verteilt, wird umfassend und in anschaulicher Weise der Aufbau einer kleinen WebApp gezeigt.

Prädikat: Äußerst empfehlenswert.

(An Aufgabe 08 habe ich einen kleinen Anteil - das freut mich natürlich besonders. :))