Montag, 16. November 2015

"SET NEWNAME" per SQL generieren

Wer eine Datenbank clont und nicht die db_create_file_dest für alle DB-Files verwenden kann, muss unter umständen viele Datenbankfile manuell per "SET NEWNAME" anpassen.

Im Internet kursieren komischer Weise einige SQLs, die diesen Zweck nicht richtig erledigen. Vielleicht liegt es auch an inkompatiblen Befehlen. Dafür kenne ich mich mit den Änderungen im SQL-Bereich nicht gut genug aus.

In Oracle 11g muss das SQL jedenfalls so aussehen:

select 'set newname for datafile '||file_id||' to ''/PATH/TO/FILES/'||substr(file_name,instr(file_name,'/',-1)+1)||''';' 
  from dba_data_files
;
Oder mit v$-View:
select 'set newname for datafile '||file#||' to ''/PATH/TO/FILES/'||substr(name,instr(name,'/',-1)+1)||''';' 
  from v$datafile
;

That's IT

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/