Vor 1,5 Jahren habe ich mich das erste mal mit dem Phänomen HANA beschäftigt. Seitdem ist eine Menge passiert und Oracle hat reagiert.
Am vergangenen Dienstag war ich auf der DOAG 2014 Datenbank in Düsseldorf und kam wieder einmal mit dem Thema in Berührung. Günter Stürner (Oracle) hielt dort die Keynote.
Der Focus seiner Rede lag auf der kommenden In-Memory-Option („Turbo Boost für die Datenbank“) der Datenbank und der Abgrenzung zur HANA.
Ein paar Sachen haben mich an meinen Text erinnert. Zeit sich den alten Kram wieder anzusehen… ich kann behaupten, dass ich gar nicht einmal falsch lag. :)
Vieles, was zwischen SAP und Oracle zum Thema In-Memory ausgetauscht wurde und wird, ist natürlich reines Marketing. SAP will seine eigene DB verkaufen und Oracle seine Marktführerschaft ausbauen bzw. nicht verlieren.
Die Existenz von HANA ist dabei meiner Meinung nach an sich keine Gefahr für Oracle. HANA steht vielmehr für die Gefahr, dass Oracle aus Kundensicht die Fähigkeit verlieren könnte, die wichtigen technischen Trends zu setzen und als Saurier dasteht.
Oracle versucht den In-Memory-Hype einerseits etwas abzuschwächen, indem sie darauf aufmerksam machen, dass dieses Thema nichts Neues ist. Andererseits wollen sie auf der Welle mitreiten. (Man ist SAP für die Marketingvorarbeit zu Thema In-Memory dankbar.)
Dabei wird dann noch klar gestellt, dass es weniger um In-Memory geht, sondern vielmehr und die Frage „Arbeitet die Datenbank der Zukunft zeilen- oder spaltenorientiert?“. (columnar)
Diese Frage hat Oracle für sich etwa so beantwortet:
Je nach Anwendungsfall ist die eine oder die andere Technologie sinnvoller. Oracle bietet beides in einem Produkt an. Auf dem Storage liegen die Daten zeilenorientiert und im Hauptspeicher werden sie auf Wunsch spaltenorientiert verarbeitet.
(So würde ich das zusammenfassen und ich kann nicht sagen, dass ich diesen Ansatz schlecht fände.)
Ganz nebenbei wuchert Oracle mit dem Pfund, eine ausgereifte, skalierbare Enterpriselösung (Backup, RAC, DataGuard, Vault…) anbieten zu können: SAP müsse schließlich erst noch aus HANA eine Enterpriselösung machen.
In der Keynote hat Günter Stürner dargestellt, wie einfach die Lösung implementiert ist. Ein einfaches „ALTER TABLE <tablename> INMEMORY;“ lädt die Tabelle „columnar“ in den Hauptspeicher. Der Zugriff soll sich bis um den Faktor 100 beschleunigen. Das soll auch mit Tablespaces, Partitionen und sogar der ganzen Datenbank funktionieren – falls die DB dort hineinpasst.
Ich denke, dass man sich um Oracle keine Sorgen machen muss. Am 11.06.2014 soll die In-Memory-Option für die 12c vorgestellt werden. (Am 17.06.2014 kann man sich das live in Frankfurt ansehen.) Wenn es tatsächlich so ist, dass die Option für die Applikation transparent nutzbar ist, kann Oracle sich zurücklehnen und sagen:
"Hey, SAP hat nur HANA, wir haben HANA on board - und wir lassen uns das ebenfalls sehr gut bezahlen." ;)
Ich freu mich schon darauf „ALTER DATABASE INMEMORY;“ testen zu können. Eine DB, die in den Hauptspeicher passt und mit einem suboptimalen Datenmodell glänzt, habe ich für den Performancetest. :)
Freitag, 6. Juni 2014
Donnerstag, 6. März 2014
Powershell und Oracle-connect
Ein Testconnectskript
Die PowerShell ist ein tolles Werkzeug. Man kann Sie für ausgeklügelte Backupskripte benutzen, das Housekeeping damit automatisieren und auch auf die Oracle-DB zugreifen.Der Zugriff ist manchmal nicht so einfach einzurichten. Gerade, wenn es mehrere ORACLE_HOMEs auf dem Rechner gibt, kann man eine Menge Zeit mit der Suche nach dem richtigen Connectionstring und dem genutzten ORACLE_HOME verschwenden - ich habe jedenfalls schon viel Zeit damit verschwendet.
Deshalb nutze ich seit einiger Zeit dieses Test-Skript, welches ich auf dem entsprechenden Rechner nur noch anpasse:
$AssemblyFile = "D:\oracle\product\11.2.0.4\dbhome_1\ODP.NET\bin\2.x\Oracle.DataAccess.dll"
$ConnectionString
= "Data Source=(DESCRIPTION=(ADDRESS=
(PROTOCOL=TCP)
(HOST=server01)
(PORT=1521))
(CONNECT_DATA=(SERVICE_NAME=orcl)));
User Id=oradba;
Password=orapwd"
$CommandText
= "SELECT count(*) FROM all_users"
[Reflection.Assembly]::LoadFile($AssemblyFile)
$OracleConnection
= ""
$OracleConnection
= New-Object -TypeName Oracle.DataAccess.Client.OracleConnection
$OracleConnection.ConnectionString =
$ConnectionString
$OracleConnection.Open()
$OracleCommand
= New-Object -TypeName Oracle.DataAccess.Client.OracleCommand
$OracleCommand.CommandText = $CommandText
$OracleCommand.Connection = $OracleConnection
$OracleDataAdapter
= New-Object -TypeName Oracle.DataAccess.Client.OracleDataAdapter
$OracleDataAdapter.SelectCommand =
$OracleCommand
$DataSet
= New-Object -TypeName System.Data.DataSet
$OracleDataAdapter.Fill($DataSet)
$OracleDataAdapter.Dispose()
$OracleCommand.Dispose()
$OracleConnection.Dispose()
$OracleConnection.Close()
$DataSet.Tables[0]
Powershell ISE ohne tnsnames.ora
Ich verwende sehr gern die PowerShell ISE. Beim Testen zickt sie aber gern.Wenn man auf eine DB zugreifen möchte (korrekter Code, alles i.O....) und die DB ist in der tnsnames.ora nicht korrekt eingetragen, bekomme man einen Fehler.
Soweit korrekt.
Jetzt korrigiert man natürlich die tnsnames.ora und versucht den connect erneut.
Die überraschende Folge: Gleiche Fehlermeldung.
Wenn man jetzt aber die PS ISE schließt, erneut startet und den selben Code wieder ausführt: keine Fehlermeldung, alles läuft durch!?!
Meiner Meinung nach prüft die ISE die Systemumgebung nicht erneut oder hat einen Cache, der nicht geleert wird - was auch immer - und liest die aktualisierte tnsnames.ora nicht.
Das ist der Grund, warum ich oben genanntes Skript verwende. Es greift nicht auf die tnsnames.ora zu sondern nutzt direkt den Connectionstring. (http://www.connectionstrings.com/oracle/)
Mittwoch, 26. Februar 2014
Oracle, Windowsdienste und ORA-12631
Damit die DB auch ins Netzwerk schreiben kann, muss der entsprechende Dienst unter einem Domainuser laufen.
Beim RMAN ist das zum Beispiel sehr nützlich, aber auch beim RAC kann man das gut gebrauchen, sofern die Instanzen der verschiedenen Nodes auf das Filesystem ihrer Kollegen zugreifen müssen.
Das lässt sich bequem über die Oberfläche einrichten (services.msc):
Sofern man den Account bequem per Button "Browse" und anschließendem "Check Names" auswählt, wird das ganze nicht mehr wie gewohnt funktionieren.
In diesem Fall wird Windows den Account im Format "oradba@my.domain" eintragen.
Die Folge ist ein ORA-12631 beim Versuch eines Connects per NTS:

Die Lösung: Der Username muss händisch im Format "domain\username"eingetragen werden:
Dann funktioniert alles wie gewohnt.
Beim RMAN ist das zum Beispiel sehr nützlich, aber auch beim RAC kann man das gut gebrauchen, sofern die Instanzen der verschiedenen Nodes auf das Filesystem ihrer Kollegen zugreifen müssen.
Das lässt sich bequem über die Oberfläche einrichten (services.msc):
- rechte Maustaste auf dem Dienst und Properties auswählen
- auf den Reiter "Log On" wechseln
- This Account und
- Account und Passwort angeben.
- OK
- Dienst neu starten und fertig.
Sofern man den Account bequem per Button "Browse" und anschließendem "Check Names" auswählt, wird das ganze nicht mehr wie gewohnt funktionieren.
In diesem Fall wird Windows den Account im Format "oradba@my.domain" eintragen.
Die Folge ist ein ORA-12631 beim Versuch eines Connects per NTS:
Die Lösung: Der Username muss händisch im Format "domain\username"eingetragen werden:
Dann funktioniert alles wie gewohnt.
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.
Die Ausgabe ist allerdings im Normalfall allumfassend.
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:
Die Rückgabe wird in eine Email gepackt und versendet.
D:\>crsctl status resource –toder 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, OFFLINEDieses 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:
Anschließend jagt man DBMS_REPAIR über die kaputte Tabelle:
Jetzt kann man in der Repairtabelle nachsehen, was im Argen liegt:
Hier die ausführliche CORRUPT_DESCRIPTION:
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:
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().
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 0xf25ec07ckdbchk: 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:
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.
- das embedded PL/SQL Gateway,
- den APEX-Listener und
- Oracle HTTP Server (OHS) mit mod_plsql - einem Apache-Webserver.
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.
Abonnieren
Posts (Atom)
