Datenbank Services im RAC und Single Instanz mit DBMS_SERVICE
von Sebastian Solbach, ORACLE Deutschland GmbH

Seit Oracle 8i wird die Verbindung zur Datenbank nicht mehr über die SID, sondern über einen Service aufgebaut. In den meisten Fällen benutzt man hierzu den Default Service der Datenbank, der sich zusammensetzt aus dem Namen der Datenbank "db_name" und der Datenbankdomäne "db_domain". Dies geschieht meist aus Vereinfachungsgründen.

Mit Oracle 10g und Real Application Clusters (RAC) bekamen neu angelegte Services, die eben nicht wie die Datenbank heißen, eine wichtige Bedeutung:

  • Möglichkeit der Konsolidierung und trotzdem der eindeutigen Identifizierung von Applikationen und Workload
  • Lastverteilung auf bestimmte Server
  • Spezifizierung von serverseitigen Einstellungen für Transparent Application Failover (TAF). Damit entfallen die Anpassungen der tnsnames.ora auf den Clients
  • Festlegung von Lastverteilung beim Verbindungsaufbau
  • Informierung der Clients über Vorgänge am Server mit Hilfe von FAN (Failover Application Notification)
  • Ressourcenverteilung anhand der Services mit Hilfe des Ressource Managers der Datenbank

  • Datenbank Services haben aber auch bei einer Single Instanz durchaus Vorteile bei der Administration und Ressourcenverteilung.
    So helfen Services auch bei DataGuard Umgebungen: Eine Rekonfiguration des Clients nach einem Switch- oder Failover ist nicht notwendig.

    Im folgenden wird auf Services mit und ohne RAC eingegangen und deren Unterschiedlichen Attribute erklärt, hierbei wird auch das DBMS_SERVICE Pakage etwas näher beleuchtet.
    Bei einem RAC sollte übrigens niemals der Default Service zur Verbindung der Datenbank verwendet werden, da dieser einige der oben beschriebenen Funktionalitäten nicht besitzt.

    Anlegen von Datenbank Services Single Instanz

    Bei einer Single Instanz können Services über das DBMS_SERVICE Pakage angelegt und verwaltet werden. Das DBMS_SERVICE Pakage ist Bestandteil jeder Datenbank Edition.
    Es gibt hierfür keine Integration in die GUI des DBControl oder dem Enterprise Manager Grid Control, wie es bei einem RAC der Fall ist.
    Bei folgendem Create kommen nur die Parameter zum Einsatz die für eine Single Instanz Sinn machen:

    SQL> BEGIN
      DBMS_SERVICE.CREATE_SERVICE (
        SERVICE_NAME => 'servicetest',
        NETWORK_NAME => 'stest',
        AQ_HA_NOTIFICATIONS => TRUE,
        FAILOVER_METHOD => DBMS_SERVICE.FAILOVER_METHOD_BASIC,
        FAILOVER_TYPE => DBMS_SERVICE.FAILOVER_TYPE_SELECT,
        FAILOVER_RETRIES => 180,
        FAILOVER_DELAY => 1
      );
    END;
    /
    Die Funktionalität von Transparent Application Failover (TAF) und Failover Application Notification (FAN) über Advanced Queuing machen auch bei einer Single Instanz Sinn: Wenn es einen Server gibt auf den ausgewichen werden kann: z.B. eine Standby Datenbank, DataGuard Konfiguration oder Replikation.

    Für den Verbindungsaufbau vom Client ist nur der NETWORK_NAME ausschlaggebend, der SERVICE_NAME wird nur für die Verwaltung des Services innerhalb der Datenbank verwendet. Damit sich die Clients verbinden können muss der Listener vom Service Kenntnis erhalten. Dazu ist es seit Oracle 8i nicht mehr notwendig den Listener zu konfigurieren. Durch die automatische Serviceregistrierung meldet die Datenbank den Service beim Listener an. Vorraussetzung hierzu ist die richtige Einstellung des Datenbankparameters LOCAL_LISTENER. Läuft der Listener auf Port 1521 kann dieser Parameter auch leer sein.

    Gibt es mehrere Listener auf unterschiedlichen Ports, über die der Service erreichbar sein sollte, so können im Parameter LOCAL_LISTENER auch mehrere Listener angegeben werden:
    SQL> ALTER SYSTEM SET LOCAL_LISTENER='MY_LISTENER';
    In der TNSNAMES.ORA stehen dann alle Listener, bei denen sich der Service registrieren soll:
    MY_LISTENER =
      (DESCRIPTION_LIST =
        (DESCRIPTION =
          (ADDRESS = (PROTOCOL = TCP)(HOST = dbhost)(PORT = 1521)(IP = FIRST))
          (ADDRESS = (PROTOCOL = TCP)(HOST = dbhost)(PORT = 1523)(IP = FIRST))
        )
      )
    Zum Abschluss sollte der Service noch über
    SQL> EXEC DBMS_SERVICE.START_SERVICE('servicetest');
    gestartet werden.

    Ab nun können sich die Clients an den Service verbinden.
    Existierende Services kann man übrigens in DBA_SERVICES prüfen.

    Anlegen von Datenbank Services RAC

    Das Anlegen von Datenbank Services im RAC gestaltet sich über die GUI des DBControl oder des Grid Controls sehr einfach.
    In 10g hatte man noch die Möglichkeit dies auch im DBCA zu tun, dies ist in 11g aber nicht mehr vorhanden.
     
    Hierbei wird einerseits der Service innerhalb der Datenbank angelegt, als auch der Service im Oracle Cluster Repository (OCR) hinterlegt. Die Services werden danach über das externe srvctl Kommando gestoppt und gestartet und nicht mit Hilfe von DBMS_SERVICE, da sonst keine Synchronisation zum Cluster respektive OCR stattfindet. Dabei ist auch der Cluster die einzige Stelle, an der definiert ist, auf welchen Knoten der Service gestartet ist und wie die Hochverfügbarkeitseinstellungen wie "Preferred" und "Available" gehandelt werden.

    Die "Service Properties" hingegen sind die Parameter von DBMS_SERVICE (leider nicht alle):
    • "TAF Policy" entspricht dabei der FAILOVER_METHOD
    • "Enable Distributed Transaction Processes" = DTP und sorgt dafür dass der Service immer nur auf einem Knoten aktiv ist
    • "Connection Load Balancing Goal" definiert CLB_GOAL, und steuert die Lastverteilung auf Basis Sessions (Long) oder auf Basis der ausgeführten Transaktionen (Short)
    • "Load Balancy Advisory" ist das GOAL und gibt an dass bei der Lastverteilung (Short) eher der Durchsatz oder die ablaufende Zeit den Ausschlag gibt. Es verwendet hierbei Statistiken vom Automatic Workload Repository (AWR) aus V$SERVICEMETRIC und V$SERVICEMETRIC_HISTORY.
    • "FAN for OCI" ist AQ_HA_NOTIFICATIONS

    Für eine größere Ansicht auf das Bild klicken
    Die restlichen Einstellungen beziehen sich auf die Verknüpfung der Services mit dem Ressource Manager ("Consumer Group", "Job Scheduler"), bzw. dem Monitoring des Durchsatzes oder der CPU Zeit im DBControl.
    Alternativ zur GUI können RAC Services auch über das srvctl Utility angelegt werden.

    Möchte man TAF verwenden, so muss man die Parameter wie FAILOVER_TYPE, FAILOVER_RETRIES und FAILOVER_DELAY über DBMS_SERVICE.MODIFY_SERVICE nachträglich anpassen.

     SQL> BEGIN
      DBMS_SERVICE.MODIFY_SERVICE (
        SERVICE_NAME => 'racservice',
        AQ_HA_NOTIFICATIONS => TRUE,
        FAILOVER_METHOD => DBMS_SERVICE.FAILOVER_METHOD_BASIC,
        FAILOVER_TYPE => DBMS_SERVICE.FAILOVER_TYPE_SELECT,
        FAILOVER_RETRIES => 180,
        FAILOVER_DELAY => 1
      );
    END;
    /

    Funktionalitäten von Datenbank Services

    Datenbankservices können gezielt während des laufenden Betriebs hochgefahren und beendet werden und können damit den Zugriff bestimmter Benutzerkreise steuern.
    Es ist durchaus denkbar diesen Service dann auf einer anderen Datenbank zu starten und die Benutzer ohne Ihr Wissen auf die andere Datenbank zu leiten.
    Diese Technik kommt z.B. bei DataGuard zum Einsatz, dass sich die Benutzer immer auf der aktiven Instanz anmelden, ohne dass hierfür am Client etwas geändert werden müsste. Hierbei wird der Service mit Hilfe eines Startup Triggers nur gestartet, wenn die Datenbank als Primary identifiziert wird:

    SQL> CREATE OR REPLACE TRIGGER manage_stestservice after startup on database 
    DECLARE 
      role VARCHAR(30); 
    BEGIN 
      SELECT DATABASE_ROLE INTO role FROM V$DATABASE; 
      IF role = 'PRIMARY' THEN 
        DBMS_SERVICE.START_SERVICE('stest'); 
      ELSE DBMS_SERVICE.STOP_SERVICE('stest'); 
      END IF; 
    END;
    /
    Des weiteren erleichtern Services die Identifikation, da die Information über den Service z.B. in der V$SESSION zu finden ist, auch wenn derselbe Username für die Verbendung verwendet wurde:
    SQL> select SID,SERIAL#,USERNAME,SERVICE_NAME from v$session where username='SCOTT';
    
           SID    SERIAL# USERNAME             SERVICE_NAME
    ---------- ---------- -------------------- --------------------
           132       7643 SCOTT                SSOR
           134       8288 SCOTT                servicetest
    Man sollte beim beenden eines Services beachten, dass bestehende Verbindungen davon nicht betroffen sind.
    Mit der Identifikation der Sessions wäre es nun zwar ein Leichtes alle Sessions zu beenden, es geht aber noch schneller und einfacher:
    Mit DBMS_SERVICE.DISCONNECT_SESSION können alle Sessions die über einen bestimmten Service eröffnet worden sind beendet werden:
    SQL> EXEC DBMS_SERVICE.DISCONNECT_SESSION('stest',DBMS_SERVICE.POST_TRANSACTION);
    Mögliche Werte sind hierbei DBMS_SERVICE.POST_TRANSACTION (0) oder DBMS_SERVICE.IMMEDIATE (1).
    Bei Services im RAC Umfeld bietet srvctl diese Funktionalität übrigens beim "stop" oder "relocate service" mit der -f Option.

    Des weiteren gibt es die Möglichkeit Services mit Consumer Gruppen des Resource Managers der Datenbank zu verknüpfen und damit den CPU Verbrauch für bestimmte Arbeiten zu limitieren. Mehr Informationen hierüber finden Sie in der Dokumentation zum Resource Manager.

    Die Funktionalitäten im RAC Umfeld sind viel weitreichender, wie z.B. das Automatic Workload Management und Fast Connect Failover (FCF).
    Deren genaue Funktionalität werden in einem der nächsten Tipps behandelt.
    Bei RAC führt kein Weg an Services vorbei - mit den Einsatzmöglichkeiten bei einer Single Instanz eigentlich auch.

    Nützliche Links und Referenzen

  • DBMS_SERVICE Dokumentation
  • Automatic Workload Management
  • Workload Management with Oracle Real Application Clusters (FAN, FCF, Load Balancing)(PDF)
  • Client Failover in Data Guard Configurations for Highly Available Oracle Databases
  • Zurück zur Community-Seite