Private strand flush not complete - was bedeutet das?

04.
April
2016
Veröffentlicht von: Elke Fritsch

Man trifft häufig seit Oracle Version 10g auf Einträge, bei denen ein "cannot allocate new log" in Verbindung mit der Meldung "Private strand flush not complete" auftaucht. Ist das jetzt kritisch oder einfach nur Hintergrundrauschen?

Wir reagieren bei der Überwachung des Alert.logs für unsere Kunden auf diverse Fehlermeldungen. Dabei trifft man seit der Oracle Version 10g häufig auf Einträge, bei denen ein cannot allocate new log in Verbindung mit der Meldung Private strand flush not complete auftaucht.

Beispiel:

Thread 1 cannot allocate new log, sequence 74377
Private strand flush not complete
  Current log# 1 seq# 74376 mem# 0: /u02/app/oracle/oradata/redoA/redo_1a.rdo
  Current log# 1 seq# 74376 mem# 1: /u02/app/oracle/oradata/redoB/redo_1b.rdo
Beginning log switch checkpoint up to RBA [0x12289.2.10], SCN: 4211564670
Thread 1 advanced to log sequence 74377 (LGWR switch)....

Ist das jetzt kritisch oder einfach nur Hintergrundrauschen ?

Was sind Private Strands ?

In Version 9i wurde für jede Transaktion in einer Session ein redo record in den Log Buffer geschrieben. Um dort Platz für die Speicherung zu allokieren, benötigte die Session einen sog. redo allocation latch und um den gab es natürlich Gerangel (vornehmer ausgedrückt: contention), wenn viele Daten in vielen Sessions geändert wurden.

Darüber hinaus mußten für die Übertragung der Daten aus der PGA der Sessions in den Log Buffer zusätzliche redo copy latches angefordert werden, damit der Logwriter die Daten nicht in die Redo Logs schrieb, bevor der Kopiervorgang abgeschlossen war.

Mit der Version 10g hat Oracle den Log Buffer in mehrere Untereinheiten aufgespalten, die sogenannten public redo strands (Strand bedeutet hier Strang, die redo strands spiegeln also in etwa den Handlungsstrang einer Transaktion wieder). Deren Größe wurde in 10g über den Parameter log_parallelism kontrolliert, in  11g über den undokumentierten Parameter _log_parallelism_max. Bei weniger als 16 CPUs gibt es 2 public redo strands.

Das Vorhandensein mehrerer parallel nutzbarer Ressourcen verringert natürlich die Wartezeiten auf den allocation latch. Noch mehr Erleichterung brachte die Einführung der sogenannten private redo strands. Diese werden im Shared Pool allokiert (nicht in der PGA der Sessions), sind ebenfalls durch redo allocation latches geschützt und wesentlich kleiner als die public redo strands. Die Redo Records werden von den Sessions direkt in diese Speicherbereiche geschrieben. Jeder enthält die Informationen für eine Transaktion. Die private redo strands sind allerdings nur für kleine Transaktionen nutzbar und in bestimmten Situationen (z. B. bei RAC-Instanzen, beim Vorhandensein garantierter Restore Points und bei aktivem Supplemental Logging) nicht nutzbar. Größere Transaktionen nutzen immer die public redo strands.

Gute Informationen zu diesem Thema liefern vor allem Jonathan Lewis (in seinem genialen Buch Oracle Core: Essential Internals for DBAs and Developers oder in seinem Blog, z. B. Opens external link in new windowhttps://jonathanlewis.wordpress.com/2010/12/23/private-redo/) und Tanel Poder (z. B. in diesem PDF Opens external link in new windowOracle_Performance_Scalability_10g_11g.pdf).

Diese Datei (selects für private strands etc.sql) enthält ein paar mehr Informationen und Selects für Interessierte.

Bei einem Commit werden die privaten Redostränge mit den öffentlichen vereinigt und vom Logwriter zusammen in die Redo Logs geschrieben.

Wie entsteht die Meldung ?

Wenn eine Session noch aktiv ist und keinen Commit abgesetzt hat, trifft ein Log Switch auf Private Strands, die ihre Redo entries noch nicht übertragen haben. Dann erscheint die Meldung private strand flush not complete im Alert.log. Erst wenn alle Inhalte aus den Private Strands in die Redo Logs übertragen wurden, kann der Log Switch stattfinden.

Beispiel:

-- Session 1 (scott)
UPDATE emp SET sal=sal*2;
-- kein Commit. Die Session bleibt aktiv

-- Session 2 als sysdba
ALTER SYSTEM SWITCH LOGFILE;

--Eintrag im  Alert.log
Fri Apr 01 11:13:27 2016
Thread 1 cannot allocate new log, sequence 571
Private strand flush not complete
  Current log# 6 seq# 570 mem# 0: C:\ORACLE\ORADATA\O11G\REDO06.LOG
Thread 1 advanced to log sequence 571 (LGWR switch)
  Current log# 4 seq# 571 mem# 0: C:\ORACLE\ORADATA\O11G\REDO04.LOG
Fri Apr 01 11:13:28 2016
Archived Log entry 23 added for thread 1 sequence 570 ID 0x161e673d dest 1:

Dieser Umstand ist auch in einem MOS Dokument beschrieben (Opens external link in new windowDoc ID 372557.1). Der wichtigste Satz dort ist: These messages are not a cause for concern unless there is a significant time gap between the "cannot allocate new log" message and the "advanced to log sequence" message.

Auswertung der Meldungen

Der folgende Select sorgt dafür, dass man bei der Auswertung der Alert.logs nicht ständig über diese Meldungen stolpert, aber in kritischen Fällen eine Warnung erhält. Diese Lösung gilt nur für Oracle Versionen ab 11g. Hier bietet die View v$diag_alert_ext (die auch für Inhaber der SELECT_CATALOG_ROLE zugänglich ist) einen sehr komfortablen Blick auf im XML-Format gespeicherte Logfile.

Die innere Abfrage liefert alle Einträge mit Private strand flush not complete oder advanced to log sequence und die jeweils darauffolgende Zeile (über die analytische Funktion LEAD, gruppiert nach adr_home und dem auf Minutengenauigkeit gesetzten Timestamp).

Wichtig ist, dass man auch die Spalte adr_home mit einbezieht, da auf einem Server mehrere Datenbanken laufen können (ADR steht für Automatic Diagnostic Repository und die Spalten adr_home enthält z. B. Einträge wie diag/rdbms/o11g/o11g und diag/rdbms/o12c/o12c wenn 2 Instanzen mit den SIDs o11g und o12c sich auf dem selben Host befinden).

Die äußere Abfrage filtert dann die Fälle, bei denen nach der Meldung Private strand flush not complete der Log Switch länger als eine Minute auf sich warten lässt (Ich habe bis jetzt übrigens keine Instanz gesehen, bei der hier Zeilen zurückkamen).

SET TRIMSPOOL ON SET LIN 400 SET PAGES 4000
COL adr_home FOR a30
SELECT adr_home, CASE WHEN COUNT(*) > 0 
            THEN 'Warnung: Logswitches wegen Private Strand Flush verzögert'
       END auswertung
FROM (SELECT message_text, 
             adr_home,
             LEAD(message_text)
             OVER (PARTITION BY adr_home,
                                TRUNC(originating_timestamp, 'mi')
             ORDER BY originating_timestamp) naechste_zeile,
             originating_timestamp 
FROM v$diag_alert_ext
WHERE TRIM(component_id)= 'rdbms'
AND (INSTR(message_text, 'Private strand flush not complete') > 0
  OR INSTR(message_text, 'advanced to log sequence') > 0))
WHERE INSTR(message_text, 'Private strand flush not complete') > 0
AND   INSTR(naechste_zeile, 'advanced to log sequence') = 0
GROUP BY adr_home;

Wenn Sie sich nicht selber die Mühe machen wollen, Ihre Datenbank auf Herz und Nieren zu untersuchen und das Alert.log zu durchforsten: Wir erstellen Ihnen auch gerne einen Öffnet internen Link im aktuellen FensterHealthcheck und geben Ratschläge zur Verbesserung der Öffnet internen Link im aktuellen FensterPerformance und der Öffnet internen Link im aktuellen FensterSicherheit, kontaktieren Opens window for sending emailSie uns einfach.

Jede Menge Know-how für Sie!

In unserer Know-How Datenbank finden Sie mehr als 300 ausführliche Beiträge zu den Oracle-Themen wie DBA, SQL, PL/SQL, APEX und vielem mehr.
Hier erhalten Sie Antworten auf Ihre Fragen.