Concurrency Datenkonsistenz & Datensicherheit

From Coders.Bay Wiki
Jump to navigation Jump to search

Problemstellung

Überweisung von Konto1 auf Konto2.

Die Daten werden in einer Tabelle gespeichert:

Kontonummer Saldo
1 100
2 200

update Konto set Saldo = Saldo - 50 where KtoNr = 1; update Konto set Saldo = Saldo + 50 where KtoNr = 2;

Was ist das Problem, wenn der Rechner während der Verarbeitung „abstürzt“?

Lösung:

begin transaction; 
   update Konto set Saldo = Saldo - 50 where KtoNr = 1; 
   update Konto set Saldo = Saldo + 50 where KtoNr = 2; 
commit; 

Überweisung von Konto1 auf Konto2. Das soll aber nur dann möglich sein, wenn für eine entsprechende Kontodeckung gesorgt ist.

select Saldo from Konto where KtoNr = 1; 
if (Saldo > 60) { 
update Konto set Saldo = Saldo - 60 where KtoNr = 1; 
update Konto set Saldo = Saldo + 60 where KtoNr = 2; 
}
update Konto set Saldo = Saldo - 10 where KtoNr = 1;

Was ist das Problem, wenn zwischendurch eine andere Überweisung von Konto1 stattfindet?

Lösung:

begin transaction isolation level serializable; 
select Saldo from Konto where KtoNr = 1; 
if (Saldo > 60) { 
   update Konto set Saldo = Saldo - 60 where KtoNr = 1; 
   update Konto set Saldo = Saldo + 60 where KtoNr = 2; 
} 
commit;

isolation level serializable bedeutet, dass das selbe Ergebnis erzielt wird, wenn die beiden Transaktionen hintereinander ausgeführt geworden wären.


Concurrency

In computer science, concurrency is a property of systems in which several computations are executing simultaneously, and potentially interacting with each other. The computations may be executing on multiple cores in the same chip, preemptively time-shared threads on the same processor, or executed on physically separated processors.

Multiversion concurrency control (MCC, MVCC, multi-generational concurrency control) ist ein Verfahren aus der Datenbanktechnik, das dazu dient, konkurrierende Zugriffe auf eine Datenbank möglichst effizient auszuführen, ohne zu blockieren oder die Konsistenz der Datenbank zu gefährden.

(Wikipedia – 26. 10. 2015)

Konsistenz und Transaktion

Ein konsistenter Zustand der Datenbank bedeutet die Korrektheit der in der DB gespeicherten Daten.

Es muss sichergestellt werden, dass ein konsistenter DB-Zustand durch eine Benutzermanipulation in einen wiederum konsistenten Zustand übergeführt wird. Zwischen den beiden konsistenten Zuständen befindet sich die DB in einem inkonsistenten Zustand.    Die Concurrency Control sichert die korrekte Ausführung nebenläufiger Transaktionen.

Philosophenproblem

DiningPhilosophers.png

Das Dining-Philosophers-Problem bringt die Concurrency Problematik auf den Punkt. Es geht um den konkurrierenden zugriff auf Betriebsmittel, der zu einem Deadlock führen kann.

Wenn ein Philosoph hungrig ist, greift er zur linken Gabel, dann zu rechten Gabel und beginnt zu essen. Wenn er satt ist, legt er die Gabeln weg und beginnt wieder zu denken.

Kein Problem, wenn nur einzelne Philosophen speisen wollen. Wenn aber alle Philosophen gleichzeitig essen wollen, greifen alle Philosophen zur linken Gabel (das funktioniert noch), scheitern aber, wenn sie zur rechten Gabel greifen wollen (deadlock). => Synchronisierungsproblematik

Nebenläufigkeit

Zwei Prozesse A und B heißen nebenläufig, wenn sie voneinander unabhängig bearbeitet werden können. Dabei ist es egal, ob zuerst der Vorgang A und dann B ausgeführt wird, oder ob sie in umgekehrter Reihenfolge abgearbeitet werden oder ob sie gleichzeitig erledigt werden.

Nebenlaeufigkeit1.png Nebenlaeufigkeit2.png

Beispiel

Gegeben sind 2 Prozesse A und B

A bestehe aus den Schritten 1 und 2
B bestehe aus den Schritten 1 und 2 und 3

Nebenläufigkeit (allgemeiner als Parallelität), bedeutet die Ausführung der beiden Prozesse in verschiedenen Ausprägungsformen: 

Die Ausführung parallel auf verschiedenen Rechnern:

  • A1 A2
  • B1 B2 B3

  Die sequentielle Ausführung auf 1 Rechner:

  • A1 A2 B1 B2 B3

oder

  • B1 B2 B3 A1 A2

  Die verzahnte Ausführung auf 1 Rechner:

  • A1 B1 A2 B2 B3

Parallele Prozesse

Nebenläufige Prozesse heißen parallel, wenn sie aufeinander keinen Einfluss ausüben – also unabhängig sind.   Zwei Prozesse können auf 1 CPU nebenläufig, aber nicht parallel ablaufen.

2 Rechner, die nicht miteinander verbunden sind, arbeiten vollständig parallel.

Zusammenfassung

  • 2 Prozesse heißen nebenläufig, wenn sie voneinander unabhängig bearbeitet werden können.
  • Für 2 nebenläufige Vorgänge ist es irrelevant, wie sie ‚zeitlich zueinander liegen‘.
  • Nebenläufigkeit ist damit ein allgemeinerer Begriff als Parallelität.

Konsistenz

  • Ein konsistenter Zustand der Datenbank bedeutet die Korrektheit der in der Datenbank gespeicherten Daten („innere Widerspruchsfreiheit“)
  • Es muss sichergestellt werden, dass ein konsistenter Zustand einer Datenbank durch eine Benutzermanipulation in einen wiederum konsistenten Zustand übergeführt wird. Zwischen den beiden konsistenten Zuständen befindet sich die Datenbank in einem inkonsistenten Zustand.
  • Durch Recovery- Funktionalitäten wird sichergestellt, dass Soft- und Hardwarefehler die Konsistenz von Daten nicht beeinträchtigen.

Grundstruktur einer Transaktion

Das Wort Transaktion leitet sich vom lat. trans (hinüber) und Agere (handeln, führen) also Überführen her.

Das Prinzip ist, die Überführung von einem konsistenten Zustand zum nächsten.

Begin of transaction    -- BOT
	Read x
	Write y
End of transaction      -- EOT

Das ausführende System muss sicherstellen, dass immer entweder beide Aktionen ausgeführt werden oder keine der Aktionen ausgeführt wird.

Eine Transaktion wird auch als LUW (logical unit of work) bezeichnet.

Die Reihenfolge der Operationen innerhalb einer Transaktion kann nicht geändert werden.

Darstellung als gerichteter Graph:

r[x] => w[x] => r[y] => c
           r[z]

r[x] => w[x] und r[z] können gleichzeitig ausgeführt werden.

ACID

  • Atomic: alle oder keine Operationen einer Transaktion
  • Consistency preserving: vollständige Transaktionsausführung einer Transaktion bewahrt die Konsistenz der Daten (event. über inkonsistente Zwischenzustände)
  • Isolated: gewährleisten Schutz vor parallelen Datenbankzugriffen anderer Transaktionen (virtueller Einbenutzerbetrieb)
  • Durable: alle Transaktionsergebnisse sind nach Transaktionsende dauerhaft.

Transaktion

Eingabe: anr_alt, anr_neu ...

EXEC SQL WHENEVER SQLERROR GOTO undo;
EXEC SQL UPDATE artikelstamm
         SET anr = :anr_neu
         WHERE anr = :anr_alt;
EXEC SQL UPDATE bestellungen
         SET anr = :anr_neu
         WHERE anr = :anr_alt;
EXEC SQL COMMIT WORK;
undo:
EXEC SQL ROLLBACK WORK;

die Datenbank durchwandert während einer solchen LUW inkonsistente Zwischenzustände

Commit / Rollback

Auswirkungen von COMMIT:

  • eine Transaktion wird erfolgreich beendet
  • von der Transaktion geänderten Daten werden in die DB übernommen
  • andere Prozesse sehen ab diesem Zeitpunkt die geänderten Daten
  • alle von der Transaktion gesperrten Ressourcen werden freigegeben

Oracle führt nach jedem DDL Statement ein implizites COMMIT aus.

Auswirkungen von ROLLBACK:

  • eine Transaktion wird erfolglos beendet
  • alle von dieser Transaktion geänderten Daten werden auf den ursprünglichen Wert zurückgesetzt, wobei die ursprünglichen Werte aus dem Rollback Segment gewonnen werden
  • alle von der Transaktion gesperrten Ressourcen werden freigegeben

Die Daten werden aber zum COMMIT Zeitpunkt nicht zwangsweise physisch geschrieben, sondern es wird nur ein kurzer, die Transaktion beschreibender Eintrag in den REDO Log File geschrieben.

Beispiel Commit

CREATE TABLE accounts (account_id NUMBER(6), balance NUMBER (10,2));
INSERT INTO accounts VALUES (7715, 6350.00); 
INSERT INTO accounts VALUES (7720, 5100.50); 
DECLARE
  transfer NUMBER(8,2) := 250;
BEGIN
  UPDATE accounts SET balance = balance - transfer WHERE account_id = 7715;
  UPDATE accounts SET balance = balance + transfer WHERE account_id = 7720;
  COMMIT COMMENT 'Transfer From 7715 to 7720' WRITE IMMEDIATE NOWAIT;
END;
/

Beispiel Rollback

CREATE TABLE emp_name AS SELECT employee_id, last_name FROM emp;
CREATE UNIQUE INDEX empname_ix ON emp_name (employee_id);
CREATE TABLE emp_sal AS SELECT employee_id, salary FROM emp;
CREATE UNIQUE INDEX empsal_ix ON emp_sal (employee_id);
CREATE TABLE emp_job AS SELECT employee_id, job_id FROM emp;
CREATE UNIQUE INDEX empjobid_ix ON emp_job (employee_id);


2-Phasen Commit

2PhaseCommit.png

Verteilte Transaktion

Es gibt 2 Arten von verteilten Transaktionen. Flache Transaktionen besitzen eine Hierachieebene, verschachtelte Transaktionen besitzen mehrere Hierachieebenen.

VerteilteTransaktion.png


Read Only Transaktion

Werden verwendet, wenn in einer Transaktion mehrfache Abfragen auf eine andere Transaktion „treffen“, die dieselben Tabellen ändert. In dieser Situation wird durch read only transactions die Performance verbessert.   Nach der Festlegung einer Transaktion als read only transaction sehen alle nachfolgenden Queries nur diejenigen Änderungen die vor dem Start der Transaktion commited worden sind. Read Only hat keine Auswirkung auf andere Transaktionen.

Transaktion 1 read only Transaktion 2
Start Report
Query Table 1 Update Table 1
Query Table 2 Update Table 2
End Report

COMMIT;

SET TRANSACTION READ ONLY;

SELECT product_id, quantity_on_hand FROM inventories

  WHERE warehouse_id = 5
  ORDER BY product_id; 

COMMIT; -- Ende “read only”

DECLARE

  daily_order_total   NUMBER(12,2);
  weekly_order_total  NUMBER(12,2); 
  monthly_order_total NUMBER(12,2);

BEGIN

  COMMIT; -- ends previous transaction
  SET TRANSACTION READ ONLY NAME 'Calculate Order Totals';
  SELECT SUM (order_total) INTO daily_order_total FROM orders
    WHERE … Bestelldatum Heute;
  SELECT SUM (order_total) INTO weekly_order_total FROM orders
    WHERE … Bestelldatum in der letzten Woche inkl. Heute;
  SELECT SUM (order_total) INTO monthly_order_total FROM orders
    WHERE … Bestelldatum im letzten Monat inkl. Heute;
  COMMIT; -- ends read-only transaction

END; /

Autonome Transaktion

  • Eine autonome Transaktion ist eine unabhängige Transaktion, die durch eine andere Transaktion gestartet wird. Es werden keine Sperren weitergegeben.

AutonomeTransaktion.png Haupttransaktion

    • führt auf bestimmte Tabellen Änderungen durch. Wenn ein Fehler aufgetreten ist, soll ein Rollback durchgeführt werden.

 

  • Untergeordnete Transaktion
    • hier werden die in der Haupttransaktion aufgetretenen Fehler / Ausnahmebedingungen protokolliert in der Form, dass ein Eintrag in einer Fehlertabelle durchgeführt wird.

Unter diesen Umständen würde ein Rollback der Haupttransaktion auch die in der Protokolltabelle eingetragenen Fehlermeldungen zurückrollen.   AT laufen in einem eigenen Kontext - sie erlauben es, dass der Fehlereintrag durchgeführt und commited wird, ohne das Ergebnis der Haupttransaktion festzuschreiben.

Geschachtelte Transaktion

Commit Regel

Das (lokale) Commit einer Sub-Transaktion macht ihre Ergebnisse nur der Vater-Transaktion zugänglich. Das endgültige Commit der Sub-Transaktion erfolgt dann und nur dann, wenn für alle Vorfahren bis zur TopLevel-Transaktion das endgültige Commit erfolgreich verläuft.

Rücksetzregel

Wenn eine (Sub-) Transaktion auf irgendeiner Schachtelungsebene zurückgesetzt wird, werden alle ihre Sub-Transaktionen, unabhängig von ihrem lokalen Commit-Status ebenso zurückgesetzt. Diese Regel wird rekursiv angewendet.

Sichtbarkeits-Regel

Änderungen einer Sub-Transaktion werden bei ihrem Commit für die Vater-Transaktion sichtbar. Objekte, die eine Vater-Transaktion hält, können Sub-Transaktionen zugänglich gemacht werden.

Problemfelder

  • ACID ist auf kurze Transaktionen zugeschnitten.
  • Lange Batchvorgänge können zu einem hohen Arbeitsverlust führen => Rücksetzen der gesamten Aktivität möglicherweise nicht akzeptabel.
  • Lange Sperrdauer kann zu einem extrem schlechten Durchsatz führen.
  • Sperren vieler Objekte führt zu einer hohen Blockierungsrate.

Probleme mit langlaufenden Transaktionen

„Druck der Dokumente“ für eine Urlaubsreservierung umfasst:

  • Flugstatus zeigen
  • Flugreservierung durchführen
  • Hotelinfo anzeigen
  • Hotelreservierung durchführen
  • Leihauto reservieren
  • Dokumente Drucken

Mehrere ‚Transaktionen‘ werden hintereinander ausgeführt. Wenn bei der vorletzten Aktivität (Leihauto reservieren) ein Problem auftritt, muss die gesamte Transaktion zurückgesetzt werden.

Genau genommen spricht man hier nicht mehr von Transaktionen, sondern von Prozessen, die einer anderen Fehler- / Ausnahmebedingungsstrategie bedürfen.

Die Basis dieser Prozesse oder Prozessketten bilden einzelne Transaktionen. Dort ist die lokale ACID Eigenschaft sichergestellt.

Spezielle Rollbacks (Kompensation)

  • Wenn ein zustandsorientiertes Undo – Recovery nicht möglich ist, wird eine logische Kompensation notwendig (Stornierung, Terminabsage)
  • Problembereiche dabei:
    • Korrektheit des Kompensationsprogramms
    • Kompensationsprogramm darf nicht scheitern
    • Nicht alle Operationen sind kompensierbar (z.B. Ausgabe eines Betrags beim Bankomat, …). Nicht kompensierbare Operationen sollten an das Ende einer Verarbeitungsfolge gestellt werden.

SAVEPOINT

  • Dadurch können längere Transaktionen unterteilt werden verbunden mit der Möglichkeit des partiellen Zurückrollens.

 

  • Vor jedem INSERT, UPDATE oder DELETE wird ein impliziter Savepoint gesetzt. Wenn das Statement scheitert, wird auf diesen Savepoint zurückgerollt.

  Anwendungsfall: Aus einer Transaktion heraus werden mehrere Funktionen aufgerufen. Vor jedem Aufruf wird ein SAVEPOINT gesetzt – damit ist es problemlos möglich auf den Zustand vor Start der Funktion zurückzurollen, wenn die Funktionsausführung scheitert.

COMMIT
UPDATE PERS SET GEHALT = GEHALT * 1.5
SAVEPOINT VOR_INSERT
INSERT INTO PROJEKT VALUES ...
SAVEPOINT VOR_DELETE
DELETE FROM PROJEKT WHERE PROJ_NR = 4711
CASE ERROR IS
	WHEN 0		THEN COMMIT
	WHEN 1		THEN ROLLBACK TO VOR_DELETE
	WHEN 2		THEN ROLLBACK TO VOR_INSERT
	WHEN OTHERS 	THEN ROLLBACK;

Beispiel

CREATE TABLE emp_name AS SELECT employee_id, last_name, salary FROM employees; 
CREATE UNIQUE INDEX empname_ix ON emp_name (employee_id); 

DECLARE emp_id employees.employee_id%TYPE; 
        emp_lastname employees.last_name%TYPE; 
        emp_salary employees.salary%TYPE; 
BEGIN 
SELECT employee_id, last_name, salary 
   INTO emp_id, emp_lastname, emp_salary 
   FROM employees 
   WHERE employee_id = 120; 
UPDATE emp_name SET salary = salary * 1.1 WHERE employee_id = emp_id; 
DELETE FROM emp_name WHERE employee_id = 130; 
SAVEPOINT do_insert; 
INSERT INTO emp_name VALUES (emp_id, emp_lastname, emp_salary); 

EXCEPTION WHEN DUP_VAL_ON_INDEX THEN ROLLBACK TO do_insert; 
DBMS_OUTPUT.PUT_LINE('Insert has been rolled back'); 
END; 
/ 

Transaktion und Integrität

Integritätskontrolle erfolgt durch das DBMS: Für welche Operationen welche Überprüfungen durchzuführen sind Wann die Überprüfung durchgeführt werden soll (direkt bei der Änderungsoperation oder verzögert bei Transaktionsende)

CREATE TABLE games (scores NUMBER, CONSTRAINT unq_num UNIQUE (scores) INITIALLY DEFERRED DEFERRABLE); 

Hier wird die Constraint prinzipiell als deferrable (widerruflich) definiert. Initially deferred verzögert die Prüfung bis zum commit

  • Durch deferrable kann die Integritätsprüfung bis zum Transaktionsende ausgeschaltet werden – während der Transaktion kann sich die Datenbank ja in einem inkonsistenten Zustand befinden.
  • Bei Massenverarbeitung kann die zeitaufwändige Integritätskontrolle an das Transaktionsende verlegt werden – damit wird verhindert, dass jeder einzelne Satz (z.B. bei Insert) geprüft wird.

Transaction Log File

Logging ist das Protokollieren von Änderungen in der Datenbank sowie von Zustandsänderungen der Transaktionen in einer Log – Datei zum Zweck des Recovery.

TransactionLogFile.png

Recovery durch Log File

Eine Wiederherstellung (recovery) der Datenbank nach einem Fehlerfall erfordert eine Protokollierung (logging) aller Änderungen an der Datenbank um ein UNDO oder ein REDO auszuführen. Ausgangspunkt ist eine Sicherung (backup) der Datenbank.

  • Roll Forward Recovery
    • angenommen, ein File wurde zerstört und kann nicht mehr gelesen werden. In diesem Fall wird die letzte Sicherungskopie des Files geladen. Danach werden alle Log Files bearbeitet und alle aufgezeichneten Änderungen des zerstörten Files nachvollzogen.
  • Roll Back Recovery
    • angenommen, ein Programm stürzt ab. In dieser Situation wird der Log File 'rückwärts' gelesen und alle aufgezeichneten Änderungen werden mit umgekehrten Vorzeichen wiederholt.

Struktur der Log-Einträge

  • Eindeutige Nummer (Log Sequence Number - LSN) zur Identifizierung. Damit wird auch die zeitliche Ordnung bestimmt.
  • Eine Transaktionskennung
  • Ein Feld Previous LSN über das die Einträge rückwärts miteinander verknüpft sind.
  • Einträge, die Beginn, Ende oder Abbruch einer Transaktion kennzeichnen.
  • Nur für Änderungsoperationen:
    • Redo – Information: gibt an, wie die Änderung nachvollzogen werden kann
    • Undo – Information: gibt an, wie die Änderung rückgängig gemacht werden kann

Tipps im Umgang mit Log Files

  • Oracle Log Miner: zur Analyse von Log Files
  • Dadurch kann der Log File betrachtet werden SELECT * FROM v$log;
    • V$LOGMNR_DICTIONARY - The dictionary file in use.
    • V$LOGMNR_PARAMETERS - Current parameter settings for LogMiner.
    • V$LOGMNR_LOGS - Which redo log files are being analyzed.
    • V$LOGMNR_CONTENTS - The contents of the redo log files being analyzed.

Transaction Log

Im folgenden Beispiel werden folgende Einträge durchgeführt: (LSN, TransactionID, PageID, Redo, Undo, PrevLSN)

  • LSN (log sequence number) - eindeutige Kennung des Log Eintrags.
  • TransactionID - Transaktion, die die Änderung durchgeführt hat
  • PageID - Kennung der Seite, die geändert wurde
  • Redo - gibt an, wie die Änderung nachvollzogen werden kann
  • Undo - gibt an, wie die Änderung rückgängig gemacht werden kann
  • PrevLSN - Pointer auf vorhergehenden Log Eintrag der gegenständlichen Transaktion

Beispiel Log File

ExampleLogFile.png

Logfile Aufbau Schematisch

LogFileShema.png

Log File Speicherhierachie

LogFileSpeicherhierachie.png

Log Ringpuffer

Ringpuffer.png