Oracle-Datenbankarchitektur: Einführung für Entwickler und DBAs
Einen Einstieg in Oracle zu finden, ist sehr schwer, wenn man aufgrund der vielen Fachbegriffe und Abkürzungen der Oracle-Welt den Wald vor lauter Bäumen nicht mehr sieht. Der Einstieg in diese Welt wird um ein Vielfaches vereinfacht, wenn man "The Big Picture" – das große Bild der Oracle-Struktur und -Architektur – im Vorfeld verstanden hat. Hierbei ist es nicht notwendig, bis ins letzte Detail alle Komponenten zu beleuchten, sondern die wesentlichen Bestandteile und deren Zusammenspiel in Verbindung zu bringen.
Für die normale Standardadministration einer Oracle-Datenbank benötigt der Administrator ein breit gestreutes Fachwissen, um einen fehlerfreien Betrieb der Oracle-Datenbank zu gewährleisten. Bei tiefergehenden Problemen kann der Administrator auf dieses Wissen aufsetzen und es im Eigenstudium vertiefen. Um den Einstieg in die Oracle-Administration zu vereinfachen, ist es dienlich, Hilfestellung für die Entscheidung geben zu können, "was für mich als Administrator wichtig zu wissen ist und was ich mir zu einem späteren Zeitpunkt selbst zusätzlich aneignen kann". Genau hier liegt das Hauptproblem des Oracle-Einsteigers: Unterscheiden zu können, bei welchem Punkt der Einstieg beginnen muss, um strukturiert das Wissen der Oracle-Administration aufbauen zu können.
Die Oracle-Datenbankarchitektur
Jeder Anwender hat eine gewisse Erwartung an eine Datenbank, die sich in der Regel mit folgenden Schlagworten umschreiben lässt: Eine schnelle Antwortzeit, eine optimale Schreibgeschwindigkeit und Datensicherheit. Diese grundlegenden Erwartungen sollen in diesem Kapitel in einer Zusammenfassung der Datenbankarchitektur wiedergegeben und durch die grundlegenden Komponenten der Architektur beschrieben werden, um ein Gesamtbild der Funktionsweise vom Oracle-RDBMS zu bekommen.
Die Oracle-Architektur gliedert sich grob in zwei grundlegende Bereiche:
- die Oracle-Datenbank
- die Oracle-Instanz
Die Oracle-Instanz
Die Oracle-Instanz ist der Motor der Oracle-Architektur und befindet sich im Hauptspeicher des Systems. Die Oracle-Instanz wird auch als der aktive Teil der Oracle-Architektur bezeichnet. Zu ihr gehören Speicherstrukturen für die Ablage von Daten sowie Hintergrundprozesse. Der Aufbau der Instanz wird über die Parameter- oder (ab Oracle 9i) über die Serverparameterdatei definiert. Wird eine Instanz gestartet, so wird im Vorfeld der Inhalt der Parameterdatei oder der Serverparameterdatei ausgelesen, die die Konfigurationseinstellungen der Instanz beinhaltet. So werden beispielsweise die Größen der Speicherstrukturen, aber auch bestimmte Optionsparameter der Datenbank und Instanz über sie konfiguriert.
Die Oracle-Datenbank
Die Oracle-Datenbank besteht aus den Datenbankdateien und befindet sich auf dem Plattensubsystem des Datenbankservers. Die Oracle-Datenbank wird auch als der passive Teil bezeichnet. Allgemein wird gesagt, dass eine Datenbank gestartet wird. Dies ist aber nicht richtig, weil nur der Motor, also die Instanz, gestartet werden kann, welche dann mit der Datenbank interagiert.
Die Kontrolldatei (Control File)
Die Kontrolldatei ist ein wichtiger Bestandteil der Oracle-Datenbank. In ihr befinden sich unter anderem die Speicherorte der Datenbankdateien. Nach dem Start der Instanz wird die Kontrolldatei über den in der Parameterdatei befindlichen Initialisierungsparameter CONTROL_FILES lokalisiert und die Speicherorte der Datenbankdateien werden ausgelesen. Darauffolgend werden die Datenbankdateien an die Instanz angebunden (gemountet). Ist die Kontrolldatei defekt oder nicht vorhanden, schlägt ein Öffnen der Datenbank fehl, weil die entsprechenden Datendateien nicht gefunden werden können.
Zusätzlich wird die Kontrolldatei vom Recovery Manager als Sicherungskatalog verwendet, indem alle Metadaten der mit dem Recovery Manager erzeugten Sicherungen in ihr gespeichert werden. Ist die Kontrolldatei unwiederbringlich verloren, kann die Datenbank nur schwer wiederhergestellt werden. Aus diesem Grund ist eine Spiegelung der Kontrolldateien zu empfehlen, um einem Verlust vorzubeugen.
Oracle und Transaktionen
Transaktionen sind ein wichtiger Bestandteil einer Datenbank, der abhängige Datenänderungen zusammenfasst. Dies bedeutet, dass diese Änderungen nicht voneinander getrennt werden dürfen und alle erfolgreich ausgeführt werden müssen. Sollten eine oder mehrere Änderungen in einer Transaktion nicht erfolgreich durchgeführt werden, darf auch keine andere Änderung dieser Transaktion durchgeführt werden.
Beispiel: Bei einer Überweisung wird Geld von einem Konto auf ein anderes transferiert. Das bedeutet, dass Geld von einem Konto abgebucht und einem anderen Konto gutgeschrieben wird. Grob betrachtet sind dies zwei Änderungen, denn von dem ersten Konto wird der Geldbetrag abgezogen, auf das zweite Konto wird dieser Betrag addiert. Diese beiden Änderungen sind unmittelbar miteinander verknüpft und voneinander abhängig. Sollte nun aber die Abbuchung des Geldbetrages erfolgreich sein, das Gutschreiben aber fehlschlagen, so ist Geld vernichtet worden. Im umgekehrten Fall gilt: Schlägt die Abbuchung fehl, während das Gutschreiben erfolgreich ist, so ist Geld vermehrt worden. In beiden Fällen ist die Konsistenz der Datenbank gestört, weil nicht nachvollzogen werden kann, wohin der entsprechende Geldbetrag gegangen ist bzw. wo er herkommt.
Notwendigerweise müssen diese beiden Änderungen als Einheit betrachtet und in einer Transaktion zusammengefasst werden. Unter Oracle werden Transaktionen mit der Anmeldung und der ersten Änderung von Daten gestartet. Folgen weitere Änderungen, gehören diese mit zur aktuell laufenden Transaktion. Diese Transaktion kann bei erfolgreicher Durchführung der Änderung mit dem Befehl COMMIT festgeschrieben, bei nicht erfolgreicher Durchführung einzelner Änderungen mit dem Befehl ROLLBACK rückgängig gemacht werden. Nach dem Festschreiben oder Zurückführen der Transaktion startet automatisch eine neue Transaktion bei einer erneuten Änderung von Daten.
Beispiel einer Transaktion:
SQL> connect ac Kennwort eingeben: Connect durchgeführt. SQL> SELECT KUNR, NACHNAME, VORNAME FROM KUNDEN; KUNR NACHNAME VORNAME ------ ---------------------- ----------------------- 2124 Meier Hans 4711 Schulz Willy SQL> UPDATE KUNDEN SET NACHNAME='Müller' WHERE KUNR=2124; 1 Zeile wurde aktualisiert. SQL> UPDATE KUNDEN SET NACHNAME='Müller' WHERE KUNR=4711; 1 Zeile wurde aktualisiert. SQL> SELECT KUNR, NACHNAME, VORNAME FROM KUNDEN; KUNR NACHNAME VORNAME ------ ---------------------- ----------------------- 2124 Müller Hans 4711 Müller Willy SQL> rollback; Transaktion mit ROLLBACK rückgängig gemacht. SQL> SELECT KUNR, NACHNAME, VORNAME FROM KUNDEN; KUNR NACHNAME VORNAME ------ ---------------------- ----------------------- 2124 Meier Hans 4711 Schulz Willy SQL>
Oracle System Global Area (SGA)
Die System Global Area (SGA) beinhaltet die Speicherstrukturen der Oracle-Instanz, welche unter anderem Tabellendaten, Metadaten oder Systeminformationen der Datenbank speichern. Zu den Speicherstrukturen gehören zum Beispiel der Database-Buffer-Cache, der Redo-Log-Buffer, der Shared Pool, der Large Pool, der Java Pool und weitere hier nicht näher erläuterte Speicherbereiche.
Oracle-Speicherarchitektur: Database-Buffer-Cache
Der Database-Buffer-Cache speichert Datenblöcke der Datenbank. Die kleinste zu lesende oder zu schreibende Einheit der Oracle-Datenbank ist der Oracle-Datenbankblock. In den Datenbankblöcken werden beispielsweise Zeilen von Tabellen abgelegt. Wird über eine SQL-Abfrage ein Datensatz in einer Tabelle gesucht, so wird der Tabellenblock, in dem sich diese Zeile befindet, in den Database-Buffer-Cache geladen, aber nur die gesuchte Zeile angezeigt.
Durch das Laden des gesamten Blocks werden alle Datensätze, die sich in diesem Block befinden, mit geladen. Sollte der gleiche oder ein anderer Anwender Daten benötigen, die sich ebenfalls in diesem Block befinden, so fällt ein erneutes Laden des Blockes vom Plattensystem weg, wodurch eine erhöhte Zugriffsgeschwindigkeit erreicht wird. Durch eine optimale Größenkonfiguration des Database-Buffer-Caches können alle wichtigen Bewegungsdaten der Datenbank im Hauptspeicher vorgehalten werden.
Damit Oracle erkennen kann, welche Blöcke mehr benötigt werden als andere, wird die Präsenz der Blöcke im Database-Buffer-Cache durch einen LRU-Algorithmus (Least Recently Used) verwaltet. Das bedeutet, dass die Blöcke, auf die häufig zugegriffen wird, länger im Hauptspeicher vorgehalten werden als jene, die nur einmalig geladen und danach nicht mehr benötigt werden. Durch diesen LRU-Algorithmus fallen dann nicht mehr benötigte Blöcke aus dem Database-Buffer-Cache heraus, um Platz für neue zu schaffen.
Die Blockgröße wird während der Installation einer Datenbank festgelegt und kann zwischen 2 und 32 Kilobyte liegen. Eine Änderung der Blockgröße ist nach der Installation einer Datenbank nicht mehr möglich und kann nur durch eine Neuinstallation erreicht werden. Die eingestellte Standardblockgröße beträgt 8 KB.
Abhängig von der beabsichtigten Betriebsart einer Datenbank sollte die Blockgröße gesetzt werden: In sogenannten OLTP-Datenbanken (On-Line Transaction Processing) sind in der Regel kleinere Blöcke, in OLAP-Datenbanken (On-Line Analytical Processing) größere Blöcke zu bevorzugen.
OLTP-Datenbanken zeichnen sich durch eine hohe Transaktionsrate aus, deren Datenänderungen innerhalb der Transaktionen klein sind. Zusätzlich laufen viele Abfragen in die Datenbank ein, deren Ergebnismengen klein sind. Bei diesen Datenbanken werden meist kleine Blockgrößen bevorzugt, um pro Datensatzzugriff wenige Datensätze zusätzlich pro Block laden zu müssen. OLTP-Systeme sind zum Beispiel ERP-Systeme (Enterprise Resource Planning, Personalplanung, Kapital, Betriebsmittel, Verkauf, Marketing, Finanz- und Rechnungswesen) oder CRM-Systeme (Customer Relation Management, Systeme für Kundenbetreuung).
OLAP-Datenbanken werden in bestimmten Abständen mit Daten befüllt und dienen zur Analyse dieser Datenbestände. Da in diesen Datenbanken große Datenmengen verarbeitet werden, werden hier größere Blöcke bevorzugt, da mit dem Lesen eines Datensatzes, der sich in einem solchen großen Block befindet, gleichzeitig viele zusätzliche Datensätze geladen und verarbeitet werden können.
Oracle: Dirty-List
Werden Datensatzänderungen innerhalb der Datenbank durchgeführt, so werden die Blöcke, in denen die Änderungen vollzogen werden, nicht direkt in die Datenbank zurückgeschrieben. Vielmehr werden die Blockadressen der geänderten Blöcke in einem Speicherbereich, der Dirty-List, protokolliert. Somit befinden sich im Database-Buffer-Cache die geänderten Blöcke, während in der Datenbank die Blöcke noch ihren Originalzustand besitzen. Erst zu späterer Zeit werden sie dann anhand der Dirty-List aus dem Database-Buffer-Cache in die Datenbank übertragen.
Im Allgemeinen kann man sagen, dass sich Änderungen primär immer in der Instanz vollziehen und erst später in die Datenbank geschrieben werden, um auf diese Weise einen Geschwindigkeitsvorteil zu erreichen.
Redo-Log-Buffer
Aufgrund der Tatsache, dass Änderungen erst im Database-Buffer-Cache durchgeführt werden, gingen diese Änderungen bei einem Instanzabsturz verloren. Um dies zu verhindern, werden Änderungen zusätzlich im Redo-Log-Buffer protokolliert. Für jede Datensatzänderung werden unter anderem die Blockadresse, der Ort der Änderung innerhalb des Blockes, der neue Wert, ein Zeitstempel und eine Systemänderungsnummer (System Change Number – SCN) in diesen Speicherbereich geschrieben. Unter Oracle erhalten alle Änderungen, die zur gleichen Transaktion gehören, eine Systemänderungsnummer, um alle Änderungen einer Transaktion identifizieren zu können.
Trotz all dieser Informationen, die im Redo-Log-Buffer festgehalten werden, gingen vorgenommene Änderungen im Falle eines Instanzabsturzes verloren, da dieser Speicherbereich in Konsequenz selbst gelöscht würde. Somit muss es einen Mechanismus geben, der Datenverlust im soeben beschriebenen Szenario verhindert. Die einzige Möglichkeit, dieses Problem zu lösen, besteht darin, die Inhalte des Redo-Log-Buffers auf einem Permanentdatenträger zu speichern.
Oracle Prozess-Architektur: Redo-Log-Writer
Der Inhalt des Redo-Log-Buffers wird durch einen Hintergrundprozess, den sogenannten Redo-Log-Writer, regelmäßig geleert und in die Redo-Log-Dateien geschrieben. Der Schreibprozess erfolgt alle 3 Sekunden, wenn der Redo-Log-Buffer zu einem Drittel gefüllt ist, bevor der Database-Writer schreibt oder wenn innerhalb der Datenbank eine Transaktion mit einem COMMIT abgeschlossen wird.
Oracle Redo-Log-Dateien (Redo Log Files)
Um die Änderungen des Database-Buffer-Caches im Vorfeld zu speichern, werden die Inhalte des Redo-Log-Buffers in die Redo-Log-Dateien geschrieben. Eine Datenbank muss immer mindestens zwei dieser Dateien besitzen, hat in der Regel aus Performancegründen aber mehr.
Diese Dateien werden zyklisch beschrieben. Das bedeutet: Ist die erste Datei vollgeschrieben, wird in die zweite Datei geschaltet und der Schreibprozess dort fortgesetzt; ist auch diese Datei gefüllt, wird wieder zurück in die erste Datei geschaltet und der Schreibprozess erfolgt erneut. Die Redo-Log-Dateien beinhalten also die Informationen der Datensatzänderungen der Blöcke und dienen bei einem Instanzabsturz zur Wiederherstellung der geänderten Blöcke der Datenbank.
In früheren Versionen von Oracle wurden die geänderten Blöcke des Database-Buffer-Caches nach jedem Umschalten in eine neue Redo-Log-Datei in die Datenbank geschrieben. In neueren Versionen erfolgt das Zurückschreiben nach hier nicht genauer spezifizierten Regeln, aber spätestens dann, wenn wieder zurück von der letzten Datei in die erste gewechselt wird.
Da die Redo-Log-Dateien permanent beschrieben werden, sollten diese nicht auf dem gleichen Plattensubsystem des Betriebssystems oder der Datenbank, sondern auf einem gesonderten Plattensubsystem abgelegt werden. Auf diese Weise werden Zugriffskonflikte beim Schreiben der Daten verhindert, welche die Transaktionsgeschwindigkeit beeinträchtigen könnten.
Zusätzlich ist es notwendig, diese Dateien über Oracle spiegeln zu lassen, da ein Ausfall der aktiven Redo-Log-Datei einen aufwändigen Wiederherstellungsprozess zur Folge haben würde, denn alle Datenänderungen, die in die aktive Datei geschrieben werden, wurden noch nicht in die Datenbank übertragen.
Oracle Prozess-Architektur: Checkpoint-Prozess und der Database-Writer
Da Datensatzänderungen in Blöcken zuerst in den Redo-Log-Dateien protokolliert und nicht direkt in die Datenbank geschrieben werden, muss irgendwann der Zeitpunkt kommen, zu dem auch die geänderten Blöcke aus dem Database-Buffer-Cache in die Datenbank übertragen werden. Da die Blockadressen der geänderten Blöcke in der Dirty-List stehen, kann der Hintergrundprozess, der Database-Writer, diese Blöcke identifizieren und in die Datenbank schreiben.
Wann dieser Hintergrundprozess geänderte Blöcke in die Datenbank schreibt, hängt von unterschiedlichen Faktoren ab. Unter anderem gibt es unter Oracle Regeln und einige Parameter, die das Zurückschreiben geänderter Blöcke erzwingen.
Wichtig ist aber, dass ein Zurückschreiben erfolgt, bevor eine Redo-Log-Datei erneut überschrieben wird, deren protokollierte Änderungen noch nicht in die Datenbank übertragen wurden. Dies muss also spätestens geschehen, wenn von der letzten in die erste Redo-Log-Datei zurückgewechselt wird.
Wenn die Blockänderungen durch den Database-Writer zurückgeschrieben wurden, wird zusätzlich ein Hintergrundprozess – der sogenannte Checkpoint-Prozess – gestartet, der die letzte Systemänderungsnummer der Datenbank in die Header aller Datenbankdateien und der Kontrolldatei schreibt. Anhand dieser Nummer kann Oracle erkennen, auf welchem Stand sich derzeit die Datenbank befindet. Dies ist bei einem Wiederherstellungsprozess der Datenbank notwendig und wichtig. Das Zurückschreiben der geänderten Blöcke in die Datenbank und das Aktualisieren der Datendateien und Kontrolldatei mit der Systemänderungsnummer wird auch als Checkpoint bezeichnet.
Warum der Umweg über die Redo-Log-Dateien?
Warum schreibt Oracle die Blöcke nach Änderungen nicht direkt in die Datenbank? Diese Frage kann man relativ einfach beantworten. Der Hauptgrund liegt im schnelleren Schreiben der Daten auf einen Permanentdatenträger. Wenn man die Redo-Log-Dateien betrachtet, so werden diese von vorne bis hinten sequenziell beschrieben. Aufgrund des Aufbaus sind diese Dateien für das Schreiben optimiert. Der Schreib-Lesekopf der Festplatte muss sich nicht permanent neu positionieren, um eine Datenänderung wegschreiben zu können. Zudem sind diese Dateien im Gegensatz zur Datenbank klein, womit ein fortlaufendes Beschreiben beschleunigt wird.
Ein weiterer Grund liegt in der Menge der Daten, die in die Redo-Log-Dateien bei der Datenbearbeitung geschrieben werden muss. Wird innerhalb eines Blockes ein Datensatz geändert, so wird der gesamte Block zurück in die Datenbank übertragen. Ist also die Datensatzänderung im Verhältnis zum Block klein, so ist die Menge, die zurückgeschrieben werden muss, immer noch der gesamte Block. Wurden zum Beispiel 10 Datensätze in unterschiedlichen Blöcken geändert, deren Änderungsgröße insgesamt vielleicht nur 100 Bytes ausmachen, muss dennoch zehn Mal die Blockgröße zurückgeschrieben werden.
In den Redo-Log-Dateien werden standardmäßig keine gesamten Blöcke protokolliert, sondern eben nur die Änderungen an den Blöcken. Die damit verbundene Datenmenge ist, wie im Absatz zuvor bereits beschrieben, natürlich um ein Vielfaches geringer als jene aller Blöcke, in denen die Änderungen vollzogen wurden. Erst bei einem Checkpoint werden alle geänderten Blöcke in die Datenbank übertragen, so dass die Schreib-Leseköpfe die Blöcke in einem Gesamtprozess wegschreiben können; dies geht schneller, als wenn die Blöcke sofort einzeln geschrieben würden.
Undo-Segmente und Lesekonsistenz
Was passiert, wenn ein Anwender lesend auf Datensätze zugreift, die derzeit Bestandteil einer laufenden Transaktion eines anderen Anwenders sind? Um dieses Problem zu klären, muss ein weiterer Bestandteil der Architektur erörtert werden. Ändert ein Anwender einen Datensatz, so wird im Vorfeld eine Kopie des Blockes, in dem die Änderung stattfinden soll, angelegt. Das Anlegen der Kopie erfolgt durch Laden eines leeren Undo-Blockes aus den sogenannten Undo-Segmenten in den Database-Buffer-Cache und Kopieren des zu ändernden Blockes in diesen leeren Block. Somit befinden sich im Database-Buffer-Cache zwei Blöcke, die an der Änderung beteiligt sind. Erst nachdem eine Kopie des zu ändernden Blockes angelegt wurde, wird die eigentliche Änderung an dem Datensatz durchgeführt. Somit befinden sich im Cache der geänderte Block und der Block in seinem Ursprungszustand. Dieser Ursprungsblock wird unter Oracle auch als Before-Image bezeichnet.
Ist die Transaktion noch nicht mit einem COMMIT festgeschrieben, so greifen alle Anwender, die den Datensatz lesen wollen, auf den Undo-Block zu. Sie sehen also noch den alten Wert des Datensatzes, bis die Transaktion durch ein COMMIT abgeschlossen wird. Das Lesen des Ursprungsblockes beziehungsweise Undo-Blockes einer laufenden Transaktion bezeichnet man als Lesekonsistenz. Sollte der Anwender seine Transaktion mit einem ROLLBACK rückgängig machen wollen, so werden alle Änderungen, die zu dieser Transaktion gehören, über die Undo-Blöcke zurückgeführt, da in ihnen der Ursprungszustand vorhanden ist.
Undo-Segmente werden also unter anderem für das Transaktions-Rollback benötigt und halten die Lesekonsistenz der Datenbank aufrecht.
Oracle Instanz-Recovery
Sollte eine Instanz terminieren, so müssen die Datenänderungen des Database-Buffer-Caches, die noch nicht in die Datenbank übertragen wurden, nach einem Neustart der Instanz über die Redo-Log-Dateien wiederhergestellt werden. Dieser Prozess wird als Instanz-Recovery bezeichnet und wird durch den Hintergrundprozess SMON (System-Monitor) vollautomatisch bei einem Neustart der Instanz durchgeführt.
Intern prüft Oracle bei jedem Start der Instanz über die Kontrolldatei, ob sie sauber heruntergefahren wurde, ob also ein Checkpoint vor dem Beenden der Instanz erfolgte, oder ob sie terminierte. Sollte die Instanz terminiert sein, verwendet Oracle für die Wiederherstellung die Systemänderungsnummer der Datenbank, um herauszufinden, ab welchem Zeitpunkt Änderungen aus den Redo-Log-Dateien übertragen werden müssen. Alle durch COMMIT festgeschriebenen Transaktionen in den Redo-Log-Dateien werden auf die Datenbank angewendet. Sollten in den Undo-Segmenten offene Transaktionen vorhanden sein, so werden diese mithilfe der Undo-Segmente zurückgeführt.
Das Anwenden der Redo-Log-Dateien wird auch als ROLLFORWARD-Phase, das Anwenden der Undo-Segmente als ROLLBACK-Phase bezeichnet. Erst nachdem der Wiederherstellungsprozess erfolgreich durchgeführt wurde, kann die Datenbank für den Zugriff geöffnet werden.
Der Shared Pool einer Oracle-Instanz
Der Shared Pool ist ein wichtiger Bestandteil der SGA. Die Hauptaufgabe dieses Speicherbereiches liegt in der Verarbeitung von SQL-Anweisungen, um deren Ausführung zu beschleunigen.
Wird eine SQL-Anweisung an die Oracle-Instanz geschickt, so muss diese SQL-Anweisung verarbeitet werden. Zu diesem Vorgang gehören unter anderem die Syntaxüberprüfung, die Überprüfung, ob die in der Anweisung ausgewählten Objekte auch tatsächlich in der Datenbank existieren, und die Beantwortung der Frage, ob der Anwender über entsprechende Berechtigungen für diese Objekte verfügt. Zudem muss Oracle herausfinden, wo sich die entsprechenden Objekte der Anweisung in der Datenbank befinden.
All diese Metadaten befinden sich im sogenannten Data Dictionary, welches in der Datenbank im SYSTEM-Tablespace liegt. Oracle muss also bei der Ausführung von SQL-Anweisungen diese Metadaten extrahieren, um die Anweisungen überhaupt verarbeiten zu können. Damit ein permanenter Zugriff auf das Data Dictionary und somit der Zugriff auf das Plattensubsystem vermieden wird, werden diese Metadaten für die Wiederverwendbarkeit in einem entsprechenden Bereich des Shared Pools, dem Dictionary Cache, zwischengespeichert.
Im zweiten Schritt verarbeitet Oracle die SQL-Anweisung, wobei herausgefunden werden muss, wie der optimale Zugriffspfad auf die Daten auszusehen hat. Abhängig davon, ob die Daten zum Beispiel gefiltert, sortiert oder gruppiert werden sollen, gibt es für jede dieser Aktionen unterschiedliche Routinen, mit denen Oracle die SQL-Anweisung nachbaut. Dieses Aneinanderreihen der Routinen wird als Ausführungsplan bezeichnet. Für die Entscheidung, welche Routinen in welcher Reihenfolge die geringsten Kosten bzw. die geringste Zeit für die Ausführung der Anweisung benötigen, verwendet Oracle einen sogenannten Optimizer.
Beispiel: Aus einer Tabelle mit 100.000 Datensätzen soll ein Datensatz selektiert werden. Oracle hat die Möglichkeit, den entsprechenden Datensatz über ein komplettes Durchscannen der Tabelle oder – bei Existenz eines Index – gezielt über die zu durch-suchende Spalte zu finden. Beides würde das richtige Ergebnis liefern. Ist die Tabelle allerdings wie in diesem Beispiel sehr groß, so wäre die Suche über einen Index schneller als ein kompletter sequenzieller Suchvorgang (Full-Table-Scan). Hierzu stehen also zwei Ausführungspläne zur Verfügung, so dass Oracle den Ausführungsplan wählen muss, der die geringsten Kosten für die Rückgabe der Ergebnismenge liefert.
Im vorangegangenen Beispiel wurde eine sehr einfache SQL-Anweisung verwendet. SQL-Anweisungen können aber beliebig komplex werden, so dass die Erstellung eines Ausführungsplans eine gewisse Zeit in Anspruch nehmen kann. Um die Wiederverwendbarkeit von Ausführungsplänen zu gewährleisten, legt Oracle nach erfolgreicher Erstellung diesen Ausführungsplan und die SQL-Anweisung im Klartext in einem separaten Bereich des Shared Pools – dem Library-Cache – ab. Bei erneuter Ausführung der gleichen Anweisung ist Oracle in der Lage, den vorher erstellten Ausführungsplan wiederzuverwenden. Ein erneuter Parse fällt weg und die Ausführung wird beschleunigt.
Weitere Speicherbereiche in der System Global Area (SGA)
Oracle besitzt weitere Speicherbereiche in der SGA, die hier nur im Groben angesprochen werden sollen, um zumindest deren Aufgabe und Verwendung im Betrieb zu verstehen.
- Der Large Pool - Einige weitere Komponenten der Oracle-Umgebung benötigen Speicherplatz im Hauptspeicher der SGA, der durch die im Vorfeld angesprochenen Speicherstrukturen nicht abgedeckt werden kann oder nicht verwendet werden sollte. Diese Komponenten bedienen sich dann des Speichers, der durch den Large Pool zur Verfügung gestellt wird. Zu diesen Komponenten gehören unter anderem der Recovery Manager oder der Shared Server, die hier erst einmal nicht weiter erläutert werden sollen. Die Größenkonfiguration des Large Pools erfolgt über den Parameter LARGE_POOL_SIZE.
- Der Java Pool – Oracle bietet die Möglichkeit, interne Programme, die sogenannten gespeicherten Prozeduren, anstatt in der Oracle eigenen prozeduralen Sprache PL/SQL in Java zu programmieren. Da Java-Anwendungen eine virtuelle Umgebung benötigen, in der sie ausgeführt werden können, bietet Oracle einen Speicherbereich, in dem diese Programme ablaufen können. Die Größe des Java Pools kann mit dem Parameter JAVA_POOL_SIZE gesetzt werden.
- Der Streams Pool – Der Streams Pool ist neu in Oracle 10g und wird für die Replikation von Daten zwischen Datenbanken mit der Methode Advanced Queueing verwendet, indem Daten als Nachricht verschickt und in Warteschlangen, den sogenannten Queues, abgelegt werden. Diese Queues verwenden den Streams Pool zum Zwischenspeichern ihrer Daten. Die Größe des Streams Pools wird über den Parameter STREAMS_POOL_SIZE konfiguriert.
Oracle-Architektur: Zusammenfassung
- Die Oracle-Architektur besteht aus einem aktiven Teil, der Instanz, und einem passiven Teil, der Datenbank.
- Die Datenbankinstanz besteht aus Speicherstrukturen, der sogenannten System Global Area, Hintergrundprozessen und ist der Motor der Datenbankarchitektur.
- Die Datenbank besteht aus den Datenbankdateien und befindet sich auf dem Plattensubsystem.
- Die System Global Area beinhaltet die Speicherstrukturen, die sich unter anderem zusammensetzen aus:
- Dem Database-Buffer-Cache, der die gelesenen Blöcke aus der Datenbank beinhaltet.
- Der Dirty-List, die die Blockadressen der geänderten Blöcke beinhaltet.
- Dem Redo-Log-Buffer, der die Änderung der Datensätze innerhalb der Datenbankblöcke protokolliert.
- Dem Shared Pool, der die Ausführungspläne der SQL-Anweisungen, die SQL-Anweisung im Klartext und die Metadaten des Data Dictionarys speichert.
- Die im Redo-Log-Buffer protokollierten Änderungen werden wie folgt in die Redo-Log-Dateien geschrieben:
- Alle 3 Sekunden
- Vor dem Übertragen der geänderten Daten im Database-Buffer-Cache in die Datenbankdateien durch den Database-Writer
- Bei einem Füllgrad des Redo-Log-Buffers von einem Drittel
- Bei Abschluss einer Transaktion durch ein COMMIT
- Eine Datenbank muss mindestens zwei Redo-Log-Dateien besitzen, die zyklisch beschrieben werden. Ist die erste Datei befüllt, wird zum Beschreiben in die zweite geschaltet; ist diese wiederum voll, wird der Schreibvorgang erneut in der ersten fortgesetzt.
- Ein Checkpoint bedeutet, dass der Database-Writer-Prozess die geänderten Blöcke aus dem Database-Buffer-Cache mithilfe der Dirty-List zurück in die Datenbank schreibt und der Checkpoint-Prozess die Datenbankdateiheader und die Kontrolldatei mit der aktuellen Systemänderungsnummer versieht. Anhand dieser Nummer erkennt Oracle den aktuellen Stand der Datenbank.
- Dieser Aufbau der Architektur ermöglicht ein performantes Schreiben der geänderten Daten und gleichzeitig ein schnelles Servieren der gesuchten Daten aus der Datenbank.
Dieser Artikel basiert auf einem Auszug des Buches:
Marek Adar: Ein strukturierter Einstieg in die Oracle-Datenbankadministration, Books on Demand; Auflage: 3 (30. Juni 2015)
Publikationen
- Der Oracle DBA: Handbuch für die Administration der Oracle Database 12c: Von Mirko Hotzy, Andrea Held , et al.
- Das große Oracle Datenbank-Einsteigerbuch.: Marek Adar
- Ein strukturierter Einstieg in die Oracle-Datenbankadministration: Marek Adar
- Ein strukturierter Einstieg in Oracle Real Application Cluster 11g R2: Marek Adar
- Ein strukturierter Einstieg in die Oracle SQL und PL/SQL-Entwicklung: Marek Adar
- Recovery Manager Kompakt: Eine strukturierte Einführung in den Recovery Manager: Marek Adar