Seiten

Posts mit dem Label Powershell werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Powershell werden angezeigt. Alle Posts anzeigen

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]

Hier müssen nur die Variablen $AssemblyFile und $ConnectionString angepasst werden. Wenn alles in Ordnung ist, sieht die Ausgabe so aus:

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/)

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.