Dienstag, Juni 27, 2017

Optimistisches Locking mit der ORA_ROWSCN

Da ich mir ziemlich sicher bin, gelegentlich wieder danach zu suchen, verlinke ich hier eine Artikelserie von Stew Ashton, die sich mit den Möglichkeiten beschäftigt, die die ORA_ROWSCN bietet, um Transaktionsprobleme zu vermeiden:
  • Avoiding Lost Updates with ORA_ROWSCN: zeigt, dass die ORA_ROWSCN als Versionsnummer zur Vermeidung von "lost updates" dienen kann, wenn bestimmte Voraussetzungen erfüllt sind (die Tabelle muss mit rowdependencies erzeugt worden sein, um eine row-genaue Zuordnung der ORA_ROWSCN zu erlauben; das Verfahren funktioniert nicht mit IOTs; vor allem muss in der WHERE-Bedingung des Updates eine Referenzierung zusätzlicher Spalten erfolgen, um Effekte zu berücksichtigen, die beim automatischen internen Restart von Updates entstehen).
  • Optimistic Locking: One SCN to rule them all: beschreibt eine API, mit der man Optimistisches Locking unterstützen kann.
  • More on Optimistic Locking with ORA_ROWSCN: liefert ergänzende Informationen zum Verhalten des Verfahrens im Kontext der internen Update-Restarts.
Offensichtlich sind meine Kommentare zu den Artikeln nicht besonders erhellend: sie dienen tatsächlich nur dazu, die Links grob einzuordnen.

Dienstag, Juni 13, 2017

Änderungen im SQL-Plan-Management mit 12.2

Wieder ein neuer Artikel von Jonathan Lewis: diesmal weist er auf einige interessante Änderungen hin, die sich beim SQL Plan Management mit 12.2 ergeben haben:
  • SQL Patches sind jetzt ein offizielles Feature: ihre Verwaltungsroutinen sind vom Package dbms_sqldiag_internal ins Package dbms_sqldiag gewandert.
  • der Hint-Text für SQL Patches ist nicht mehr auf 500 Zeichen begrenzt, sondern als CLOB definiert.
  • der zugehörige Funktionsname lautet nun create_patch (bisher i_create_patch).
  • neben der älteren Variante, bei der der Query-Text übergeben wird, gibt es eine neue Variante, die mit der sql_id arbeitet.
Darüber hinaus enthält der Artikel Abfragen auf sqlobj$data, mit denen man die Inhalte von SQL-Profiles, SQL-Baselines und SQL-Patches anzeigen kann, die alle ihre Hints in der gleichen Tabelle speichern. Eine Variante der Query erlaubt die Abfrage für ein einzelnes Objekt eines dieser Typen, bei der man den Namen explizit angibt (und dafür sqlobj$ zusätzlich joinen muss).

Mit 12.2 wurden weiterhin neue Funktionen für dbms_xplan eingeführt, mit denen man die Pläne zu den erwähnten Plan-Management-Varianten darstellen kann, die intern in sqlobj$plan gespeichert werden.

Freitag, Juni 09, 2017

Partitionierungs-Optionen in 12.2

Jonathan Lewis zeigt in seinem jüngsten Artikel die große Flexibilität, die die Definition von partitionierten Tabellen in Oracle 12.2 errreicht hat. Dabei liefert er größeres Code-Beispiel für ein ALTER TABLE ... MOVE, in dem folgende Punkte aufgeführt sind:
  • List-Partitionierung über mehrere Spalten.
  • automatic: das Schlüsselwort, das die Generierung neuer Partitionen für neu ankommende Daten erlaubt - das entspricht damit dem Interval-Partitioning für Ranges, das man schon aus älteren Releases kannte.
  • indexing off: erlaubt die Beschränkung der Indizierung auf einzelne Partitionen und damit die Definition partieller Indizes.
  • read only: erlaubt nur lesende Zugriffe für die betroffene Partition.
  • including rows where: erlaubt bei einer MOVE-Operation die Verschiebung von Daten auf der Basis eines Filter-Kriteriums.
  • online: erlaubt eine online-MOVE-Operation ohne downtime.
  • update indexes: aktualisiert Indizes im Rahmen einer MOVE-Operation.
    • local: die Indizes werden als lokale Indizes aufgebaut.
    • indexing partial: die Indizes werden für die Partitionen mit der Option "indexing off" nicht erzeugt (also ohne Segmente erzeugt und befinden sich daher im Status "unusable").
Dazu gibt es dann noch allerlei Analyse-Code zum Beleg, dass die MOVE-Operation tatsächlich das erwartete Ergebnis brachte, nämlich "Convert a simple table to partitioned with multi-column automatic list partitions, partially indexed, with read only segments, filtering out unwanted data, online in one operation." Insgesamt scheint mir das Partitioning ein Bereich zu sein, in dem 12.2 sehr nützliche Ergänzungen liefert und eine sehr große Flexibilität erlaubt.

Dienstag, Mai 30, 2017

Verzögerte Cursor Invalidierung nach DDL-Operationen in 12.2

Heute habe ich zwei neue Artikel in meinem Blog-Reader gefunden, die sich mit Themen der verzögerten Invalidierung abhängiger Cursor bei unterschiedlichen DDL-Operationen beschäftigen:
  • Richard Foote erläutert das Verhalten im Zusammenhang mit der Anlage von - was war es noch mal? Ach ja: - Indizes. Wenn man nicht möchte, dass die Erzeugung eines neuen Index automatisch alle von der zugehörigen Tabelle abhängigen Cursor invalidiert, dann kann man das in 12.2 durch die Ergänzung der Klausel DEFERRED INVALIDATION beeinflussen. Allerdings ist es durchaus möglich, Szenarien zu erzeugen, in denen das Verhalten nicht unbedingt dem entspricht, was man sich wünschen würde - und natürlich tut das der Herr Foote in seinem Artikel.
  • Frank Pachot spricht deferred invalidation im Kontext von partition exchange an. Dabei zeigt er, dass die Spalte v$sql.is_rolling_invalid in diesem Zusammenhang offenbar nicht plausibel aktualisiert wird, obwohl die verzögerte Invalidierung funktioniert. Werden nicht alle Indizes ausgetauscht, ergibt sich allerdings eine sofortige cursor-Invalidierung. Insgesamt kann das Feature nützlich sein, um einen hard-parse-peek beim partition exchange zu vermeiden.
Die verzögerte Invalidierung gab es bereits vor 12.2 im Rahmen von dbms_stats-Operationen und die Ausweitung auf explizite DDL-Operationen erscheint sehr plausibel.

Freitag, Mai 26, 2017

Semantik des parallel(n) Hints

Jonathan Lewis weist in seinem Blog darauf hin, dass der Hint /*+ parallel(n) */ keineswegs einen parallelen Plan erzwingt, auch wenn eine ausreichende Anzahl an parallelen Ausführungsprozessen zur Verfügung steht. Tatsächlich weist der Hint den Optimizer nur dazu an, die Kosten der parallelen Ausführung für jeden überprüften Plan zu berücksichtigen - aber letztlich wählt der Optimizer den Plan mit den niedrigsten Kosten (sofern kein Bug im Spiel ist) und das kann durchaus ein serieller Plan sein.

Dazu liefert der Artikel ein Beispiel dafür, wie sich das Verhalten zwischen unterschiedlichen Releases verändern kann: für die Beispielquery eines (eindeutigen) id-Zugriffs liefert 11.2.0.4 auch bei Verwendung eines parallel(4)-Hints einen seriellen Plan, was beim Index-Zugriff auf einen einzelnen Datensatz durchaus verständlich ist. Erst wenn man den Zugriff mit einem zusätzlichen FULL-hint ergänzt, ergibt sich die Parallelisierung. In 12.2.0.1 sieht das Verhalten anders aus: dort erscheint ein PX SELECTOR im Plan, der eine hash distribution über Blockadressen ermöglicht, was im Fall globaler Indizes in partitionierten Tabellen hilfreich sein könnte. Das Phänomen hat Jonathan Lewis bereits vor knapp einem Jahr in einem anderen Artikel beschrieben.