Hintergrund
Online Redo Logs sind dem DBA ein Begriff, doch rufen wir uns einleitend nochmals ihre Aufgabe ins Gedächtnis: Online Redo Logs sichern den Buffer Cache gegen Verlust ab. Damit ist es möglich, bei Absturz des DB-Systems die Veränderungen im Cache zu rekonstruieren. Das nennen wir dann ein Instance- oder Crash-Recovery. Zu diesem Zweck schreibt der Log Writer mit Umweg über den Log Buffer jede Änderung an einem Buffer im Online Redo Log fest, bevor der User den Commit erfolgreich zurückgemeldet bekommt. Nach einiger Zeit sorgt ein Checkpoint unter Zuhilfenahme des Database Writer dafür, dass manipulierte (="dirty") Buffers in die Datafiles synchronisiert werden. So wird der Weg frei, Speicherplatz im Online Redo Log wieder zu überschreiben, weil die Information im Redo nicht mehr nötig ist.
Performance, old school
Aus diesem Sachverhalt ergeben sich direkt zunächst zwei Zusammenhänge und Fragestellungen, die für die Performance des Systems relevant sind:
- Kann der Log Writer schnell genug ins Redo Log schreiben, damit ich meine Commit-Zeiten einhalten kann? Dies ist meist eine Frage der Schreib-IO-Performance.
- Kann der Database Writer schnell genug Dirty Buffers in die Data Files schreiben, damit der Log Writer genügend überschreibbaren Raum im (INACTIVE) Online Redo Log vorfindet? Neben der schreibenden IO-Leistung kommt es hier auch auf die für den DBW zur Verfügung stehende CPU- Leistung (Parallelität?) an.
Private Strands
Durch das seit Jahrzehnten praktizierte System, dass ein Commit den gesamten Log Buffer schreiben muss, würde es zu einem unschönen Nebeneffekt kommen: Eine kleine OLTP-Transaktion mit einem Umfang von wenigen Bytes müsste unter Umständen dann bei ihrem Abschluss das Festschreiben des gesamtem Log Buffers von vielleicht 160 MB abwarten. Damit würden Commit-Zeiten unkalkulierbar. Oracle hat dies durch das Konzept der "Private Strands" ergänzt und damit stark entschärft: Jede Session schreibt zunächst ihre Transaktions-Informationen in einen eigenen Speicherbereich in der PGA, den Private Strand. Der Log Buffer bleibt so lange frei für andere Aktivitäten. Erst wenn "ein Ende absehbar" oder der Rahmen des Strands ausgeschöpft ist, wandert dessen Inhalt in den Log Buffer und wird zeitnah durch die eigene Session committet. So belastet eine "Lastschieflage" nicht die Commit-Zeiten kleiner Vorgänge.
Nicht voll!
In der Praxis hat der DBA zwar aus Gründen der Checkpoint-Häufigkeit und wegen der damit verbundenen Schreibaktivität die Anzahl der Log Switches im Blick, selten aber deren Effizienz. Haben Sie schon einmal kontrolliert, ob das Redo Log beim Switch auch wirklich voll war? Ganz leicht geht das, indem man die Größe des entstehenden Archive Logs mit der Redo-Log-Größe vergleicht: Im Idealfall sind beide identisch. Häufig aber sind Archive Logs sehr viel kleiner – und damit wurde der Aufwand für einen Log Switch, einen Checkpoint, ein neues Archive Log etc. nicht optimal verwertet.
Woran liegt das?
An asymmetrischer Belastung durch ungleiches Transaktionsvolumen in gleichzeitig laufenden Sessions. Bedingt durch das Konzept der Private Strands kann man sich – vereinfacht gesagt – das Redo Log mehrspurig vorstellen. Wenn nun einige Strands parallel in Benutzung sind, kann es ja für jedes und zu jeder Zeit passieren, dass sie in den Log Buffer (und folglich bald ins Redo Log) geschrieben werden müssen. Dafür hält Oracle diese "Spur" frei, sprich es wird Platz reserviert. Ist nun eine solche "Spur" voll, kann Oracle durch die sequentielle Natur der Online Redo Logs nicht wieder "zurückspringen", um die nur teilweise beschriebene Redo-Log-Datei voll zu bekommen (der RBA Pointer ist schon fortgeschritten). Wir haben nun ein Redo Log, das zwar vom Pointer her "voll" ist, aber speicherseitig nur zu einem Bruchteil. Ein Füllstand von 20 - 40 % ist nicht selten.
Lösungsvorschlag
Die Frequenz der Log Switches zu reduzieren, und damit das "Zeitfenster" zu vergrößern, in dem "auch andere" Transaktionen fertig werden können. Klassisch erreicht man das durch Vergrößerung jeder einzelnen Redo-Log-Gruppe. Ohne den beschriebenen Effekt wäre die Reduzierung linear, die doppelte Redo Log File Size führte zu doppeltem Zeitabstand der Log Switches. So ergibt sich aber ein gegenseitiger Verstärkungseffekt: Die Gruppe bleibt durch die Vergrößerung doppelt so lange CURRENT, dadurch werden mehr Transaktionen in dem Zeitraum fertig, es bleiben weniger Blöcke im Redo ungenutzt (Füllstand erhöht sich), wir brauchen weniger Log Switches um das (gegebene) Transaktionsvolumen unterzubringen, dadurch bleibt das Log länger CURRENT.... In der Praxis haben wir damit durchaus eine Verfünffachung des Log-Switch-Intervalls erreicht – analog stieg der Füllgrad des Archive Logs von 20 auf 100 %.
Not a Silver Bullet
Bitte legen Sie jetzt nicht los und vergrößern alle Ihre Redo Logs. Nicht jede Workload verursacht dieses Problem, also löst auch mein Vorschlag nicht jedes Problem. Bitte arbeiten Sie professionell: Erst analysieren, dann eine Theorie entwickeln, die Theorie im Testsystem bestätigen, dann in Produktion umsetzen. Ist die Theorie widerlegt, so war sie einfach für die Situation falsch und bleibt im Werkzeugkasten für die nächste Einladung zum Denksport.
Mehr Input!
Jonathan Lewis hat ein paar technische Hintergrundinfos dazu zusammengetragen:
https://www.red-gate.com/simple-talk/sql/oracle/are-your-oracle-archived-log-files-much-too-small/
Ich hoffe, Sie fanden das Thema interessant. Bei Fragen können Sie mich gerne per E-Mail anschreiben. Bleiben Sie gesund und bis hoffentlich bald mal wieder persönlich auf einer Veranstaltung der DOAG!
Ihr
Martin Klier
Oracle ACE Director
Performing Databases GmbH
www.performing-databases.com


