Row Chaining & Row Migration Alte Bekannte - immer noch aktuell!
DOAG 2014 Datenbank
Dierk Lenz
Herrmann & Lenz Services GmbH Herrmann & Lenz Solutions GmbH
• Erfolgreich seit 1996 am Markt
• Firmensitz: Burscheid (bei Leverkusen)
• Beratung, Schulung und Betrieb/Fernwartung rund um das Thema Oracle Datenbanken
• Schwerpunktthemen: Hochverfügbarkeit, Tuning, Migrationen und Troubleshooting
• Herrmann & Lenz Solutions GmbH
– Produkt: Monitoring Module
2 2
Speicherung auf Blockebene
• In Oracle Datenbanken Speicherung von Daten grundsätzlich mit variabler Länge
– Immer für NUMBER- und VARCHAR2-Werte
– Leider nicht für DATE, TIMESTAMP, CHAR
– Sonderfall LOBs: meist out-of-line, d.h. von den anderen Daten getrennt
3
Variable Speicherung
Vorteile
• Platzsparende, kompakte Speicherung
• Row kann wachsen und schrumpfen
Nachteile
• Länge einer Row nicht konstant
• Row kann wachsen und schrumpfen
4
Bedeutung von PCTFREE
• Ausschließlich wichtig für das Verhalten bei INSERTs
• Definierter Blockanteil muss NACH dem INSERT frei sein
• Hierdurch Platz für UPDATEs
5
Chained Rows
• Bezeichnung für Datensätze, die grundsätzlich nicht in einen Block passen
• Aufteilung einer Row in mehrere Teile
• Reorganisation hier nicht hilfreich
6
Migrated Rows
• Bezeichnung für Datensätze, die nach einer Vergrößerung nicht mehr in den ursprünglichen Block passen
• Werden „als Ganzes“ in einen Block mit ausreichend Platz verschoben
• Rowid-Einträge der Indizes unverändert!
• Rowid-Pointer an der „alten Stelle“ notwendig
7
8
9
10
11
Was ist ein Row Piece?
• Teil einer Row, meist bestehend aus einer Untermenge der Spalten
• Wie viele Spalten kann eine Tabelle haben? – Aktuell: 1000
– Historisch: 255
• Physische Abbildung einer Row im Block: maximal 255 Spalten!
• Mehr als 255 Spalten: Eine Row besteht aus mehreren Row Pieces
12
Behandlung von Row Pieces
• Wie unabhängige Rows
• Ablage im gleichen Block eher zufällig
– Wie mehrere aufeinander folgende INSERTs
• Block voll nach dem ersten Row Piece:
– Speicherung weiterer Row Pieces in anderen Blöcken
– Row verteilt auf mehrere Blöcke
13
Begriffsverwirrung
• Einerseits – Genaue Unterscheidung zwischen Chained und
Migrated Rows (Speicherverfahren!)
• Andererseits – „Über einen Kamm geschert“: Alles wird als Chained
Row bezeichnet
• Richtig ist: – Wenig Unterschiede im tatsächlichen Verhalten
• Ab hier: – Chained Rows
14
Woher kommen Chained Rows im Live-Betrieb?
• Ad Hoc
– Schema-Upgrade bzw. „Neue Version der Anwendung“
– ALTER TABLE ADD iban VARCHAR2(34)
• Schleichend
– INSERT von „Basis-Rows“ (fast ausschließlich Schlüsselinformationen)
– Weitere Daten später durch UPDATE
15
Wie kann man Chained Rows erkennen?
• Vorsicht! – Spalte dba_tables.chain_cnt wird mit dbms_stats NICHT gefüllt!
– „Relikt“ aus früheren Zeiten ANALYZE TABLE … COMPUTE STATISTICS
• Nicht empfohlen (Sperrverhalten!)
• Bitte NICHT ANALYZE und dbms_stats „abwechselnd“ benutzen
• Hinweise aus Systemstatistiken – table fetch continued row
16
Chained Rows Read Ratio
• Chained Rows Read Ratio:
𝑡𝑓𝑐𝑟
𝑡𝑓𝑏𝑟+𝑡𝑠𝑟𝑔
• tfcr = „table fetch continued row“ (Chained Rows) tfbr = „table fetch by rowid“ (Index-Zugriffe) tsrg = „table scan rows gotten“ (Full Table Scan Rows)
• Sollte < 0,01 sein (Max. 1% Chained Row Reads)
17
V$SYSSTAT
• SELECT * FROM v$sysstat WHERE name IN ('table scan rows gotten', 'table fetch by rowid', 'table fetch continued row') ORDER BY name
18
V$SESSTAT
• SELECT n.name, s.value FROM v$sesstat s INNER JOIN v$statname n USING (statistic#) WHERE n.name IN ('table scan rows gotten', 'table fetch by rowid', 'table fetch continued row') AND s.sid = 71 ORDER BY n.name
19
Oracle‘s Lazy Read
• Nicht alle SQLs, die eine Chained Row betreffen, erhöhen den „Chained Row Read Count“
• Beispiel: SELECT COUNT(*) FROM …
• Annahme: Full Table Scan
– Lese alle Blöcke
– Zähle alle Row Pieces…
– …außer „Nicht-Head-Row“-Pieces!
– Somit kein „Hinterherlaufen“ von Row Chaining
20
Provozieren von Chained Row Reads
• SELECT <letzte Spalte> FROM …
• Oracle startet bei Head-Row-Pieces
• Nachverfolgung bis zum letzten Piece
21
Welche Rows sind Chained Rows?
• Tabelle chained_rows notwendig
• Skript: ?/rdbms/admin/utlchain.sql
• Kann anderen Namen haben • ANALYZE TABLE … LIST CHAINED ROWS [ INTO <chained_rows> ]
• Ermöglicht Row-basierte Reorganisation – Z.B. PL/SQL Schleife über FETCH – DELETE – INSERT
22
Reorganisation
• Bei verschwindend geringen Mengen:
– Keine Reorganisation
• Bei geringen Mengen (einige Prozent der Rows einer Tabelle):
– Row-basiert (s.o.)
• Bei großen Mengen:
– Z.B. MOVE der Tabelle
23
Reorganisation – Vorsicht!
• Vorherige Analyse: Migrated oder Chained Rows?
• Bei „klassischen“ Chained Rows keine Verbesserung „ad hoc“ möglich
• Weitere Parameter in Betracht ziehen, z.B. Blockgröße
24
Best Practices
• Vermeide Tabellen mit mehr als 255 Spalten!
• Vermeide den Datentyp CHAR!
• Verstehe Deine Anwendung – passe z.B. PCTFREE für bestimmte Tabellen an!
• Im Zweifel Reorganisation nach Datenmodell-Änderungen!
25
26
Vielen Dank für Ihre Aufmerksamkeit!
E-Mail [email protected] Twitter @ora1578 http://blog.hl-services.de