Donnerstag, 10. November 2016

Export Datapump: No locks available (NFS Share)

It's time for a new post, istn't it?

I recently had the problem that an expdp command failed with the following message:

ORA-39001: invalid argument value
ORA-39000: bad dump file specification
ORA-31641: unable to create dump file "/backup/exp.dmp"
ORA-27086: unable to lock file - already in use
Linux-x86_64 Error: 37: No locks available
Additional information: 9
Additional information: 37

The problem is related with that the NFS server which provides the NFS share. It has no locking service installed and/or configured. There are two options, you either install a locking service on the NFS server or change the mount options.

The option "noac" needs to be replaced with "nolock".

In my case I did the following change to /etc/fstab:

# Before
10.10.10.10:/Oracle  /backup  nfs  rw,rsize=32768,wsize=32768,tcp,vers=3,hard,intr,noac  0 0
# After 
10.10.10.10:/Oracle  /backup  nfs  rw,rsize=32768,wsize=32768,tcp,vers=3,hard,intr,nolock  0 0

That's IT.

Montag, 29. Februar 2016

SQLPlus Ausgabe in Variable Speichern

In Linux ist es sehr einfach, eine Variable mit der Ausgabe von einem SQLPlus-Befehl zu füllen. Unter Windows ist das eine halbe Doktorarbeit.

Vielen Dank an Damir Vadas für seinen sehr hilfreichen Post in seinem Blog (Thank you Damir Vadas for your helpful post on this subject):
"How to redirect sqlplus result in Windows batch script"

echo set timi off head off^&echo. select  MIN(sequence#) from v$log where thread#=1; | sqlplus -s "/ as sysdba" | findstr . > result.tmp
FOR /F %i IN (result.tmp) DO @set MIN1=%i
@echo %MIN1%
del result.tmp


Quelle: http://damir-vadas.blogspot.de/2010/11/how-to-redirect-sqlplus-result-in.html

That's IT

Dienstag, 9. Februar 2016

Katastrophe: Windows 64Bit, Oracle DB 64Bit und Oracle Client 32Bit

Von Zeit zu Zeit ist man als Oracle-DBA dazu gezwungen, Datenbanken unter Windows zu betreiben. Als wenn das nicht genug Ärger bedeutet, soll auch noch neben der 64Bit Datenbank ein 32Bit Client installiert werden.

Es gibt eine ganze Sammlung (Oracle Note 1157463.1) von Problemen die unter Windows auftreten wenn man versucht, ein zweites oder drittes Oracle-Produkt zu installieren. Mit Oracle-Produkt meine ich nicht Java oder ähnliches, sondern alles was mit dem Oracle Universal Installer installiert wird.

Neben verschiedenen Java-Problemen, Chaos im Inventory oder andere Kleinigkeiten gibt es noch dieses Problem:

Der OUI wurde mit "Als Administrator ausführen" ausgeführt und startet ganz normal. Am Ende des Assistenten klickt man auf "Install". Der Installationsdialog erscheint für 1-3 Sekunden und verschwindet wieder. Wer in den Installationslogs nach weiteren Informationen sucht, wird nicht fündig denn diese sind leer. Das Verhalten wurde in der Oracle-Community bereits diskutiert, leider ohne Erfolg: https://community.oracle.com/thread/2192825?tstart=0
Dieses Problem scheint auch nicht immer aufzutreten, denn sonst gäbe es im Internet sicher schon mehrere Komplettlösungen dazu.

Das Problem liegt an den Registry-Einträgen im Zusammenhang mit dem Oracle Inventory Pfad.

Nach der Installation von Oracle DB 64Bit gibt es den Registry-Key "inst_loc" unter [HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE]. Dieser verweist auf das Oracle-Inventory unter "C:\Program Files\Oracle\Inventory".

Der 32Bit-Installer sucht zusätzlich nach dem Registry-Key "inst_loc" in [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Oracle]. Diesen gibt es noch nicht und da dies ein 32Bit-Installer ist, müsste dementsprechend der Pfad "C:\Program Files (x86)\Oracle\Inventory" heißen. Den Konflikt zwischen den beiden Keys/Pfaden kann der Installer dann scheinbar nicht lösen und stürzt ab.

Wenn dieser Pfad vor der Installation des Oracle Client 32Bit manuell angelegt wird, funktioniert die Installation. Es kommt also darauf an, dass die beiden Registry-Keys [HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\inst_loc] und [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Oracle\inst_loc] auf den selben Pfad zeigen.

That's IT

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