X

Technologie - Trends - Tipps&Tricks
in deutscher Sprache

Datenbankausfall? Mir doch egal! Dank Application Continuity

Sinan Petrus Toma
Senior Solution Engineer

Einleitung

Kennen Sie das? Sie klicken bei einer Reisebuchung oder Hotelreservierung auf „Jetzt Buchen“ und es kommt „ein unbekannter Fehler ist aufgetreten“ oder sogar gar keine Rückmeldung zurück? Sie überlegen sich, ob Sie schon die Koffer packen, oder vielleicht doch noch einmal den Buchungsvorgang wiederholen sollten.

 

Datenbank-Hochverfügbarkeit

Oracle bietet Hochverfügbarkeits- und Disaster-Recovery-Lösungen wie Real Application Clusters (RAC) und Data Guard an. Sollte beispielsweise bei einem 2-Knoten-RAC eine Datenbankinstanz oder der gesamte Datenbankserver ausfallen, bleibt die Datenbank weiterhin über die zweite Datenbankinstanz erreichbar.

Datenbank-Hochverfügbarkeit mit 2-Knoten-RAC

Was bedeutet das jedoch aus Sicht der Anwendung? Wie muss die Anwendung reagieren, um diesen Ausfall transparent für den Endbenutzer zu gestalten? Hierzu betrachten wir unterschiedliche Szenarien.

Fällt eine Datenbankinstanz aus, so werden neue Verbindungen über eine weitere Datenbankinstanz hergestellt. Um lange TCP-Timeouts zu vermeiden, soll die Anwendung nicht die physikalischen Server-IPs, sondern den SCAN-Namen, die SCAN-VIPs oder die Server-VIPs im Connection String verwenden.

(FAILOVER=ON)
(CONNECT_TIMEOUT=3)(RETRY_COUNT=3)
(ADDRESS=(PROTOCOL=TCP)(HOST=scan-name)(PORT=1521))

Bestehende, inaktive Verbindungen können ebenso über eine weitere Datenbankinstanz wiederhergestellt werden. Dafür stellt Oracle seit Release 10.1 zwei Technologien zur Verfügung:

  • Transparent Application Failover (TAF) für Client/Server-Umgebungen
  • Fast Connection Failover (FCF) für 3-Schichten-Architekturen mit Connection Pools

Wird während eines Ausfalls gerade eine SELECT-Abfrage abgearbeitet, kann TAF mit dem FAILOVER_TYPE=SELECT Feature die Abfrage nach der Wiederherstellung der Verbindung erneut absetzen und die Cursor-Position anpassen. 

Was passiert jedoch, wenn sich die Session während des Ausfalls inmitten einer Transaktion befindet? In diesem Artikel werden wir sehen, wie man mit Oracle Mitteln auf genau solche Zustände reagieren kann. Folgende Themen werden behandelt:


Transaction Guard

Eine Session führt eine Transaktion mit DML Operationen wie INSERT, UPDATE und DELETE aus und schließt diese mit einem COMMIT ab, erhält jedoch aufgrund eines Ausfalls keine Rückmeldung von der Datenbank zurück. Die Session wird wiederhergestellt, hat jedoch keinerlei Information darüber, ob der letzte COMMIT erfolgreich war. 

Soll die Session nun die letzte Transaktion wiederholen? Wenn ja, und der COMMIT vor dem Ausfall jedoch erfolgreich war, kann es zu logischer Datenkorruption in der Datenbank führen, da eine Transaktion zweimal ausgeführt wurde. Doppelte Reisebuchung! 

War der COMMIT nicht erfolgreich, und die Anwendung wiederholt die Transaktion nicht, gibt es gar keine Reisebuchung. Das passiert immer am Freitagabend. Am Montag kostet die Reise das Doppelte.

Mit Release 12.1 stellt Oracle für diesen Zweck Transaction Guard (TG) zur Verfügung. Transaction Guard ist ein Protokoll und API, um den Status der letzten Transaktion zu überprüfen.

Die Datenbank speichert den Status der letzten Transaktion.  Nach einem Ausfall und Wiederherstellung der Verbindung auf einer weiteren Datenbankinstanz, fragt die Anwendung den Zustand der letzten Transaktion anhand einer Logical Transaction ID (LTXID) ab. War die Transaktion erfolgreich, so muss die Anwendung diese nicht wiederholen, anderenfalls führt die Anwendung die Transaktion erneut durch.

Schematische Darstellung von Transaction Guard

Transaction Guard erfordert eine zusätzliche Programmierung in der Anwendung, um die letzte Transaktions-ID und deren Status abzufragen und darauf zu reagieren. Transaction Guard ist für Enterprise Edition verfügbar und kann bei RAC, RAC One Node, Data Guard Physical Standby und Active Data Guard Physical Standby eingesetzt werden.


Application Continuity (AC)

Application Continuity stellt automatisch sicher, dass eine Transaktion genau einmal ausgeführt wird, um logische Datenkorruption in der Datenbank zu vermeiden. Wird eine Transaktion nach einem Ausfall wieder ausgeführt (Replay), erscheint es für die Anwendung wie eine kurze Verzögerung, ohne eine Fehlermeldung zu erhalten.

Geplante Wartungsarbeiten wie Rolling Patching oder der Restart einer Datenbankinstanz sowie unvorhergesehene Ausfälle sind transparent für die Anwendung. Hierfür nutzt Application Continuity im Hintergrund die Transaction Guard Funktionalität. Der große Vorteil ist jedoch, dass Application Continuity lediglich durch einfache Konfiguration und ohne Änderung im Anwendungs-Code aktiviert wird. 

Hierzu berücksichtigt Application Continuity auch Funktionen, die bei einem erneuten Aufruf einen neuen Wert zurückliefern (mutables), wie z.B. SYSDATE oder NEXTVAL bei Sequenzen. Bei einem Replay wird der Wert des ersten Aufrufs wiederverwendet.

Application Continuity verfolgt nur Änderungen innerhalb der Datenbank. Aktionen außerhalb der Datenbank, wie z.B. das Erstellen einer Datei oder das Versenden einer E-Mail (side effects) würden bei einem Replay mehrmals durchgeführt werden. Es ist jedoch möglich, dieses Verhalten zu deaktivieren.

Application Continuity reagiert auf Fehler, die z.B. durch den Ausfall von Foreground-Prozessen, Netzwerk, Speicher oder Datenbankserver verursacht werden (recoverable errors). Diese Ausfälle sind unabhängig von der Applikationslogik. 

Die Applikation ist weiterhin dafür verantwortlich, auf Benutzerfehler (unrecoverable errors) zu reagieren, z.B. ein Benutzer gibt einen unzulässigen Wert ein.

Mit Release 12.1 unterstützt Application Continuity Anwendungen, die auf JDBC thin Driver basieren. Daher findet man dieses Feature auch unter dem Namen „Application Continuity for Java“. Release 12.2.0.1 unterstützt zusätzlich OCI (Oracle Call Interface) und ODP.NET Anwendungen. Mit Release 12.2.0.2 (18c) werden viele weitere Clients unterstützt.

In allen Fällen ist der Einsatz von Oracle Connection Pools wie das Universal Connection Pool für JDBC oder das OCI Session Pool notwendig. Oracle Connection Pools können auch für Dritt-Anbieter-Anwendungen wie IBM WebShere, RedHat JBoss oder Apache Tomcat konfiguriert werden. Es ist Best-Practice, dass die Applikation die Verbindung nur für die Dauer des Requests hält, und diese im Anschluss dem Connection Pool zurückgibt.

Application Continuity kann bei RAC, RAC One Node und Active Data Guard Physical Standby Datenbanken eingesetzt werden, aber nicht bei logischen Replizierungstechnologien wie Oracle GoldenGate oder Data Guard Logical Standby. Bei einer logischen Replikation unterscheiden sich die primäre und die Standby Datenbank bzgl. der physikalischen Strukturen (z.B. Tabellen- und Zeilen-IDs), daher kann kein Replay durchgeführt werden.


Transparent Application Continuity (TAC)

Eingeführt mit Release 12.2.0.2 (18c), unterstützt Transparent Application Continuity zusätzlich Anwendungen, die keinen Connection Pool nutzen. Die Verwendung von Connection Pools ist jedoch weiterhin empfohlen. Zudem erkennt Transparent Application Continuity side effects automatisch und wiederholt diese nicht im Falle eines Replay.


AC und TAC aktivieren

Erstellen Sie einen benutzerdefinierten Datenbankservice, um die Service-Attribute für Hochverfügbarkeit setzen zu können. Application Continuity kann nicht mit dem Standard Service (DB name) verwendet werden.

Server-seitig sind folgende einfache Schritte nötig:

1. Service erstellen und starten

Die Aktivierung von AC und TAC wird über den Parameter FAILOVERTYPE gesteuert. Der Wert TRANSACTION aktiviert AC, während AUTO TAC aktiviert.


srvctl add service -db dbname -pdb pdbname -service servicename 
-preferred inst1 -available inst2 
-stopoption IMMEDIATE
-replay_init_time 600 -retention 86400 -drain_timeout 300 
-notification TRUE #aktiviert FAN
-commit_outcome TRUE #aktiviert TG
-failover_restore [LEVEL1 | AUTO] 
-failovertype [TRANSACTION | AUTO] #LEVEL1 und TRANSACTION aktivieren AC - AUTO aktiviert TAC

srvctl start servie -db dbname -service servicename

2. Für pre 19c Datenbanken: KEEP Rechte für Mutables und Sequenzen vergeben


grant KEEP DATE TIME to username;
grant KEEP SYSGUID to username;
grant KEEP SEQUENCE ON schema.seqname TO username;

3. Rechte für das Application Continuity package vergeben


grant EXECUTE ON DBMS_APP_CONT TO username;

4. Port 6200 für ONS freischalten

Client-seitig sind folgende einfache Schritte nötig:

1. Folgender TNS Connection String nutzen


TNSalias = 

(DESCRIPTION = 

   (CONNECT_TIMEOUT=120) (RETRY_COUNT=50)(RETRY_DELAY=3)(TRANSPORT_CONNECT_TIMEOUT=3)

 (ADDRESS_LIST =

   (LOAD_BALANCE=on)

   (ADDRESS = (PROTOCOL = TCP)(HOST=primary-scan)(PORT=1521)))

 (ADDRESS_LIST =

   (LOAD_BALANCE=on)

   (ADDRESS = (PROTOCOL = TCP)(HOST=standby-scan)(PORT=1521)))       

(CONNECT_DATA=(SERVICE_NAME = servicename)))

2. Client konfigurieren

Für JDBC Thin Clients: ersetze die .jar Dateien mit dem aktuellen Set von Oracle. Dieser enthält die ons.jar, ucp.jar, und die der Replay Driver ojdbc8.jar bzw. ojdbc11.jar. 

Für OCI Clients: ersetze alle Vorkommnisse von OCIStmtPrepare (deprecated in 12.2) durch OCIStmtPrepare2, füge HA EVENTES=TRUE zum empfohlenen Connection String hinzu und setze den Service-Paramter notifications=true.

Eine detaillierte Auflistung der Schritte inkl. Beispiele finden Sie in diesem White Paper.


AC und TAC in der Oracle Cloud

Bei kunden-verwalteten Datenbanken im Database Cloud Service (DBCS) kann (Transparent) Application Continuity genauso einfach und in der gleichen Art und Weise wie für klassische Oracle Datenbanken aktiviert werden. 

Bei der autonomen Datenbank auf dedizierter Exadata Infrastruktur ist Transparent Application Continuity für die Transaktionsservices (_tp und _tpurgent) standardmäßig aktiviert. Sie können AC oder TAC mit dem PL/SQL Package DBMS_APP_CONT_ADMIN aktivieren oder deaktivieren, z.B.:

execute DBMS_APP_CONT_ADMIN.ENABLE_AC('TPURGENT');
execute DBMS_APP_CONT_ADMIN.ENABLE_TAC('HIGH');
execute DBMS_APP_CONT_ADMIN.DISABLE_FAILOVER('HIGH');

Bei der autonomen Datenbank auf geteilter Exadata Infrastruktur, ist Application Continuity standardmäßig deaktiviert. Da es keinen Zugriff auf die lokalen Datenbankserver gibt, können die Service-Parameter nicht wie gewohnt mit der srvctl-Utility angepasst werden. Oracle bietet hierfür die ENABLE_APP_CONT und DISABLE_APP_CONT Prozeduren im DBMS_CLOUD_ADMIN PL/SQL Package an.


BEGIN
DBMS_CLOUD_ADMIN.ENABLE_APP_CONT(
    service_name => 'N7PMWSC8TE8FJTY_ATP19C_high.atp.oraclecloud.com'
    );
END;
/

Mit folgender Abfrage können Sie die Service-Konfiguration in der Datenbank überprüfen:

SELECT name, failover_type, commit_outcome, retention_timeout 
FROM dba_services;

Zusammenfassung

RAC und Data Guard bieten Hochverfügbarkeit für die Datenbank (High Availability). Application Continuity bietet Hochverfügbarkeit für die Anwendung (Continuous Availability). Geplante Wartungsarbeiten sowie Ausfälle sind transparent für den Endbenutzer.

  • Mit TAF oder FCF (ab Version 10.1) können  inaktive oder aktive Sessions inkl. SELECT-Abragen automatisch wiederhergestellt werden, ohne eine Fehlermeldung auf der Applikationsseite zu produzieren.
  • Mittels Transaction Guard (ab 12.1) können abgebrochene Transaktionen mit DML transparent für die Anwendung wiederhergestellt werden, erfordert jedoch eine manuelle Programmierung im Anwendungs-Code.
  • Application Continuity (ab 12.1/12.2) verwendet Transaction Guard automatisch im Hintergrund. D.h., dass Sie Ihren Anwendungs-Code nicht ändern müssen und die Aktivierung lediglich durch eine einfache Konfiguration erfolgt. Der Einsatz von Connection-Pools ist jedoch erforderlich.
  • Transparent Application Continuity (ab 18c) funktioniert auch ohne Connection-Pools, auch wenn diese weiterhin empfohlen sind.

Application Continuity wird in jeder neuen Datanbankversion weiterentwickelt - auch in der neuen Version 21c. Dazu mehr in einem weiteren Blog.

 

Weitere Informationen

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.