Mittwoch, 2. September 2015

Oracle Datenbanken mit RMAN verschieben

Es soll vorkommen, dass Datenbanken von einer Platte auf die andere verschoben werden sollen. Die folgende Beschreibung trifft ebenfalls zu, wenn die Datenbank vom Filesystem ins ASM oder andersherum verschoben wird.

Mit RMAN kann dies sehr gut vorbereitet werden um eine handliche Downtime von 10-20 Minuten zu erreichen. Mit etwas Einsatz kann auch eine 1-Minuten-Downtime erreicht werden.

Das folgende Beispiel entstand bei einem Umzug von ASM auf einem alten Storage ins Filesystem eines neuen Storage.

Schritt 1
Zunächst wird eine Image-Copy angelegt:
RMAN> backup incremental level 0 as copy database to destination '/opt/oracle/oradata' tag 'NEWSTORE';


Schritt 2
Die folgenden Pfade müssen im SPFILE angepasst werden. Dies kann online geschehen.
- db_create_file_dest
- FRA
- Archivelog-Dest
- Redologs

Schritt 3
Schritt 3 wird nun je nach Notwendigkeit zwischen der Vorbereitung und der Downtime 1-n Mal wiederholt. Dieser Vorgang aktualisiert die Image-Copy.
RMAN> backup incremental level 1 for recover of copy with tag 'NEWSTORE' database;
RMAN> recover copy of database with tag 'NEWSTORE';

Schritt 4 (switch)
Datenbank herunter fahren, Controlfiles verschieben und im SPFILE anpassen. Anschließend die Datenbank switchen:

Variante A (Alle Archivelogs seit dem letzten "Schritt 3" sind verfügbar):
RMAN> switch database to copy;
RMAN> recover database;

Variante B (Es sind nicht mehr alle Archivelogs verfügbar):
Zuerst "Schritt 3" ausführen, anschließend:
RMAN> switch database to copy;
RMAN> recover database;

Schritt 5
Datenbank wieder starten.

That's IT.

Montag, 6. Juli 2015

APEX 505 Fehler, I/O-Fehler: "Network Adapter could not establish the connection"

Problembeschreibung und Umgebung

Heute stieß ich auf den folgenden sonderbaren Fehler, den ich gerne teilen möchte. Eine APEX-Installation in einem Oracle Real Application Cluster (RAC) läuft auf einem Knoten plötzlich auf einen Fehler. Die Browser-Seite zeigte einen 505-Fehler.
Weitere Details zur Umgebung:
  • Oracle Version: 10g (2-Knoten RAC)
  • Oracle REST (APEX-Listener) 2.0.2
  • Applikations-Server: Tomcat

Symptome

Im catalina.out des Tomcat-Servers stand die folgende Fehlermeldung:
oracle.dbtools.common.jdbc.ConnectionPoolException: The pool named: apex is not correctly configured, error: I/O-Fehler: The Network Adapter could not establish the connection
         at oracle.dbtools.common.jdbc.ConnectionPoolException.badConfiguration(ConnectionPoolException.java:65)
         at oracle.dbtools.common.config.db.DatabaseConfig.badConfiguration(DatabaseConfig.java:166)
         at oracle.dbtools.common.config.db.DatabaseConfig.createPool(DatabaseConfig.java:187)
         at oracle.dbtools.common.config.db.DatabaseConfig.getConnection(DatabaseConfig.java:71)
         at oracle.dbtools.common.jdbc.ora.OraPrincipal.connection(OraPrincipal.java:69)
         at oracle.dbtools.apex.ModApexContext.getConnection(ModApexContext.java:372)
         at oracle.dbtools.apex.Procedure.getProcedure(Procedure.java:167)
         at oracle.dbtools.apex.OWA.validateProcedure(OWA.java:390)
         at oracle.dbtools.apex.security.Security.isValidRequest(Security.java:225)
 [...]
Wie gesagt, auf einem RAC-Knoten lief die Konfiguration, es gab keine Änderungen, die Konfigurationen waren auf beiden Knoten identisch.

Lösung

Die Apex-Dateien aus dem WEB-INF wurden gelöscht. Beim Neustart des Tomcats werden diese aus der .war-Datei automatisch neu deployed. Dieser erste Neustart wurde als tomcat-User manuell ausgeführt. Dabei durften die Umgebungsvariablen $LANG und $NLS_LANG nicht gesetzt sein!
$ su - tomcat
$ unset LANG
$ unset NLS_LANG
$ $CATALINA_HOME/bin/startup.sh
Anschließend war die APEX-Anwendung wieder über beide Knoten erreichbar.
Was genau das Problem war und wie es dazu kommen konnte, ließ sich anschließend natürlich kaum noch feststellen.
That's IT

Donnerstag, 8. Januar 2015

Oracle Upgrade: utlu112i.sql vergessen?

Wer kennt das nicht: Bei einem Upgrade möchte man das catupgrd.sql script laufen lassen, doch dieses läuft sofort auf den Fehler, dass irgend etwas mit der Tabelle registry$database nicht stimmt.
Das bedeutet man hat vor dem Upgrade das utlu112i.sql nicht ausgeführt. Entweder hat man es schlicht vergessen oder die Datenbank kommt aus einem Backup und man hatte überhaupt nicht die Möglichkeit das Script auszuführen.
In diesen Fällen muss man nicht unbedingt das utlu*i.sql Script vorher laufen lassen, es gibt auch eine einfache Korrektur.
Zunächst überprüft man die Tabelle registry$database:

SELECT TO_NUMBER('MUST_BE_SAME_TIMEZONE_FILE_VERSION')
FROM registry$database
WHERE tz_version != (SELECT version from v$timezone_file);

Wenn die Tabelle registry$database nicht existiert (für 11gR2):

CREATE TABLE registry$database (
 PLATFORM_ID    NUMBER,
 PLATFORM_NAME  VARCHAR2(101),
 EDITION        VARCHAR2(30),
 TZ_VERSION     NUMBER
);

Wenn die Tabelle registry$database existiert (für11gR2):

alter table registry$database add (tz_version number);
delete from registry$database;


Für beide Varianten muss noch folgendes ausgeführt werden:

INSERT into registry$database
       (platform_id, platform_name, edition, tz_version)
VALUES ((select platform_id from v$database),
        (select platform_name from v$database),
        NULL,
        (select version from v$timezone_file));
commit;


That's IT

Mittwoch, 7. August 2013

Authentifizierung bei APEX-Zugriff deaktivieren

Installiert man APEX mit PL/SQL Listener in einer Datenbank (außer XE), so muss man bei jedem Zugriff auf die APEX-Weboberfläche ein Username und Passwort eingeben. Es handelt sich hierbei um die Authentifizierung an der XML-Datenbank. Um dies abzustellen muss der folgende Code ausgeführt werden:

SET SERVEROUTPUT ON

DECLARE
  l_cfgxml XMLTYPE;
  l_value VARCHAR2(5) := 'true'; -- (true/false)
BEGIN
  l_cfgxml := DBMS_XDB.cfg_get();

  IF l_cfgxml.existsNode('/xdbconfig/sysconfig/protocolconfig/httpconfig/allow-repository-anonymous-access') = 0 THEN
    SELECT insertChildXML (
      l_cfgxml, '/xdbconfig/sysconfig/protocolconfig/httpconfig',
      'allow-repository-anonymous-access',
      XMLType('<allow-repository-anonymous-access xmlns="http://xmlns.oracle.com/xdb/xdbconfig.xsd">' ||
      l_value || '</allow-repository-anonymous-access>'),
      'xmlns="http://xmlns.oracle.com/xdb/xdbconfig.xsd"'
    ) INTO l_cfgxml FROM dual;

    DBMS_OUTPUT.put_line('Element inserted.');
  ELSE
    SELECT updateXML (
      DBMS_XDB.cfg_get(),
      '/xdbconfig/sysconfig/protocolconfig/httpconfig/allow-repository-anonymous-access/text()',
      l_value, 'xmlns="http://xmlns.oracle.com/xdb/xdbconfig.xsd"'
    )
    INTO l_cfgxml FROM dual;

    DBMS_OUTPUT.put_line('Element updated.');
  END IF;

  DBMS_XDB.cfg_update(l_cfgxml);
  DBMS_XDB.cfg_refresh;
END;
/


(Quelle: My Oracle Support)
That's IT

Mittwoch, 31. Juli 2013

APEX mit PL/SQL Embedded Gateway

Diese Konstellation ist nur für Umgebungen mit einer geringen Anzahl von Usern geeignet. Es empfielt sich immer einen Web-Server vor APEX zu hängen; Ich habe gute Erfahrungen mit Tomcat gemacht.
Zurück zum PL/SQL Embedded Gateway. Um eine akzeptable performance zu erreichen, sollte der Shared Server konfiguriert werden. Hier ein Beispiel für eine solche Konfiguration:

alter system set shared_servers=5;
alter system set max_shared_servers=20;
alter system set dispatchers='(PROTOCOL=TCP) (SERVICE=XE) (DISPATCHERS=3)';


Der SERVICE muss natürlich auf die entsprechende Umgebung angepasst werden.
That's IT.

Donnerstag, 18. Juli 2013

log_file_sync

Thank you Riyaj Shamsudeen for your good post on resolving log_file_sync wait events.
Here is the article: http://orainternals.wordpress.com/2008/07/07/tuning-log-file-sync-wait-events/

Donnerstag, 27. Juni 2013

"Execute to Parse"-Wert ist negativ

Bei einer Datenbank-Analyse fiel mir kürzlich auf, dass bei der Instanz-Effektivität des Statspack-Berichts (gilt auch für AWR) ein negativer Wert für Execute to Parse angegeben wurde. Zunächst bin ich einfach darüber hinweggegangen mit der Annahme, dass dies ein Erfassungsfehler oder sonst ein Bug im Bericht sei.
Instance Efficiency Indicators
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            Buffer Nowait %: 100.00       Redo NoWait %:  99.99
               Buffer Hit %:  99.99  Optimal W/A Exec %: 100.00
              Library Hit %:  93.59        Soft Parse %:  93.83
         Execute to Parse %: -43.82         Latch Hit %:  99.54
Parse CPU to Parse Elapsd %:  98.17     % Non-Parse CPU:  96.70
Was steckt jedoch wirklich hinter dieser negativen Zahl?
Die Anwendung, die diese Datenbank benutzt, hält nicht viel von Bind-Variablen. Deshalb war zu erwarten, dass dieser Wert gegen "0" geht. Ein negativer Wert bedeutet jedoch das Folgende:
Der Wert setzt sich zusammen aus [geparste SQLs]/[ausgeführte SQLs]*100. Normaler Weise sind die ausgeführten SQLs deutlich höher als die geparsten. Deshalb geht der Wert auch eher gegen 100% statt gegen 0%. In diesem Fall war aber die Anzahl der geparsten SQLs deutlich höher als die Anzahl der ausgeführten SQLs. Mit anderen Worten, die Anwendung lässt SQLs von der Datenbank parsen, die aber nie ausgeführt werden. Es werden hier also Datenbankressourcen verschwendet mit Operationen die niemand benötigt.
Was hier zu tun ist, liegt auf der Hand. Die Anwendung muss untersucht und bereinigt werden.

Update 2015-08-27:
Dieses Phänomen habe ich mittlerweile bei mehreren Datenbanken beobachtet. Wann immer die Entwickler der Anwendungen damit konfrontiert wurden, wurde dieses Verhalten der Anwendung vehement abgestritten. Meistens wird behauptet, dass SQLs nicht "prepared" werden und deshalb keine negative Zahl erscheinen kann. Es muss also mehr dahinter stecken als nur diese einfache Rechnung. Fakt ist, dass in der Datenbank etwas nicht ordnungsgemäß läuft.
Updates folgen...

Thrat's IT