Concurrency Datenkonsistenz & Datensicherheit
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
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.
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
Verteilte Transaktion
Es gibt 2 Arten von verteilten Transaktionen. Flache Transaktionen besitzen eine Hierachieebene, verschachtelte Transaktionen besitzen mehrere Hierachieebenen.
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.
- 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.
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