Transaktionsverwaltung in modernen IS

Werbung
Dr. H. Schuldt
Eidgen
ossische Technische Hochschule Z
urich
Swiss Federal Institute of Technology Zurich
K. Haller
Transaktionsverwaltung in modernen IS
Praktische U bung 1
Beispiellosung
Einleitung
Das Ziel dieser U bung ist die Untersuchung, wie die in der Vorlesung vorgestellten Konzepte zur Serialisierbarkeit in kommerziellen Systemen umgesetzt werden.
Hierzu betrachten wir das Datenbanksystem Oracle9i. Am Beispiel kleiner Anwendungsszenarien sollen die hier realisierten Protokolle analysiert werden.
Verwenden Sie als Referenz bei Fragen zu den von Oracle implementierten Verfahren
die Oracle9i Dokumentation (speziell Kapitel 22: Data Concurrency and Consistency), verfugbar unter:
http://www.dbs.ethz.ch/timi/WS 01 02/docs/Oracle9i-Concepts.pdf.
Vorbereitung
Zunachst benotigen Sie einen Account fur den Zugri
auf die Oracle{Datenbank.
U ber folgendes Web{Formular konnen Sie die Login-Information beantragen:
http://www.dbs.ethz.ch/timi/WS 01 02/uebungen/p1/oracleAccount.html .
Nach Angabe Ihres Namens und Ihrer Email-Adresse erhalten sie eine Mail, in der
Ihnen Ihr Oracle User Name, das zugehorige Passwort sowie der Host String (letzterer wird benotigt, um die Datenbank, mit der die U bung stattndet, zu lokalisieren)
mitgeteilt wird.
Sie konnen damit diese praktische Ubung
unter Windows NT auf den Rechnern in
Raum E31 oder C31 durchfuhren. Zur Vorbereitung sind folgende Schritte notig:
1. Netzwerklaufwerk verbinden: Zuerst muss eine Verbindung zum File-Server
hergestellt werden. Hierzu muss nndbsnsqlplus als Laufwerkbuchstabe U:
bereitstehen. Daher muss man entweder im Command Prompt >:
net use U: nndbsnsqlplus eingeben bzw. im Windows{Explorer unter Extras ! Netzlaufwerk verbinden das Laufwerk U: wie oben beschrieben belegen.
2. Registry{Eintragungen vornehmen: Auf dem Laufwerk U: liegt eine Datei namens install u.inf. Diese Datei anklicken und uber das Kontextmenu (rechte Maustaste) installieren. Dabei allfallig auftretende Fehlermeldungen konnen
ignoriert werden.
1
3. Startdatei und SQL-Skript kopieren: Auf dem Laufwerk U: nden Sie ebenfalls eine Datei namens sqlplus u.bat. Diese Datei startet SQLPLUS, das
SQL-Frontend zu unserer Oracle{Datenbank. Kopieren Sie diese Datei in Ihr
Home{Verzeichnis (H:). Im Unterverzeichnis U:nTimi nden Sie zudem das
SQL-Skript createAndFill.sql, das die in dieser U bung verwendete BeispielDatenbank anlegt und mit Daten fullt. Kopieren Sie auch diese Datei in Ihr
Home{Verzeichnis (in den gleichen Ordner, in den Sie zuvor auch sqlplus u.bat
abgelegt haben).
4. SQLPLUS starten: Mit Hilfe der ins Home{Verzeichnis kopierten Batch{Datei
sqlplus u.bat.
5. Anmelden an der Datenbank: Sie werden neben Username und Passwort auch
nach dem Host{String gefragt, der die Datenbank{Instanz, an die Sie sich
verbinden mochten, speziziert. In unserem Falle ist dies STUD6.
6. Skripte ausfuhren: In SQLPLUS konnen Sie mittels @filename (mit Pfad,
aber ohne .sql) sogenannte Skripten ausfuhren. Dies sind SQL{Befehlsdateien,
deren Name auf .sql endet. Die Beispieldatenbank wird also im SQLPLUS{
Fenster mittels @createAndFill angelegt.
Verwendete Daten
Die Basis der Aufgaben ist eine kleine relationale Datenbank (die Sie gerade eben
mittels createAndFill angelegt haben) aus einem Bankenszenario, welche folgende
Relationen enthalt:
Kunde (KundenNr, Name, Vorname, Wohnort)
Konto (KontoNr, Saldo, KundenNr)
Zins (KontoNr, Zinssatz)
(Primarschlussel sind unterstrichen, Fremdschlussel kursiv gesetzt)
Starten Sie in mehreren Fenstern SQLPLUS, d.h. bauen sie gleichzeitig mehrere
Datenbank{Verbindungen (unter dem gleichen Datenbank{Login) auf, um parallele
Benutzer zu simulieren. Experimentieren Sie mit den verschiedenen Moglichkeiten,
welche Ihnen Oracle in Bezug auf die Transaktionsverwaltung bietet, um folgende
Fragen zu beantworten. Ziehen Sie dazu auch die oben erwahnte Dokumentation zu
Rate.
2
Aufgabe 1: Konsistenz und Isolationslevel in Oracle
a) Geben Sie eine Denition der Konsistenz an, wie sie von Oracle aus gesehen
wird (Oracle9i-Concepts, Chapter 1: Data Concurrency and Consistency). Was
wird unter Lese-Konsistenz verstanden, wie wird es in Oracle eingesetzt und
was wird dadurch vom System garantiert?
Oracle vermeidet Dirty Reads durch die Schreibsperren, die automatisch durch
das System gesetzt werden, wenn Update-, Delete- oder Insert-Statements ausgefuhrt werden. Oracle spricht von \Statement-Level Read Consistency" und
meint, dass ein einzelnes SQL-Statement eine konsistente Sicht der Datenbank
hat. Es ist jedoch moglich, dass aufeinanderfolgende Statements innerhalb der
gleichen Transaktion unterschiedliche Zustande sehen konnen.
b) Welches sind die Vorteile der Konsistenz, so wie sie in Oracle deniert sind? Wo
sind die Schwachstellen?
Oracle's Konsistenzbegri ist auf grotmogliche Ezienz durch maximale Parallelitat von Transaktionen ausgerichtet. Deswegen wird so wenig wie moglich
gesperrt. Allerdings sind Transaktionen in Oracle nicht notwendigerweise koniktserialisierbar. (Beispiele hierfur gibt es in den folgenden Aufgaben).
c) Welche Isolationslevel werden von Oracle unterstutzt? Was ist jeweils die Semantik dieser Isolationslevel?
Oracle unterstutzt drei Isolationslevel: Read Committed, Serializable sowie
Read Only, wobei Read Committed die Standard-Einstellung ist. Es ist in keinem der Falle moglich, noch nicht committete Werte zu lesen, so dass inconsistent (dirty) reads nicht auftreten konnen.
Read Committed (siehe Aufgabe 2) besagt, dass nur Werte von erfolgreich beendeten Transaktionen gelesen werden. Ferner garantiert Oracle durch die \Statement-Level Read Consistency", dass fur die Dauer der Ausfuhrung des Statements der konsistente Datenbankzustand gesehen wird, der zu Beginn des Statements vorlag (so ist es zum Beispiel nicht moglich, dass ein Cursor Tupel sieht,
die nach seinem Onen
erzeugt wurden).
Repeatable Read wird hingegen fur die Isolationsstufe Read Committed nicht garantiert. Da Konsistenz nur bezuglich eines Statements gilt, ist es moglich, dass
zwei identische Select-Anfragen derselben Transaktion unterschiedliche Werte
zuruckliefern. Repeatable Read kann jedoch fur Nur-Lese-Transaktionen erzwungen werden, indem die Transaktion als read-only deklariert wird (SET TRANSACTION READ ONLY, siehe Aufgabe 3).
Mit dem Isolationslevel Serializable (siehe Aufgabe 4) schliesslich werden nur
SSI{Schedules erlaubt.
Aufgabe 2: Isolationslevel Read
Committed
a) In der Vorlesung IS-G wurde das Problem der verlorengegangenen A nderung
(lost update) vorgestellt. Untersuchen Sie anhand eines Beispiels, ob dieses
Problem auch in Oracle mit der Default-Einstellung des Isolationslevels (Read
3
) moglich ist. Was kann ein Anwendungs- bzw. SQL-Programmierer
tun, um lost updates zu vermeiden?
Folgender Beispielablauf zeigt, dass lost updates moglich sind (f1 und f2 sind
dabei die unterschiedlichen Fenster, in denen die Eingaben erfolgen):
Committed
f1: Select Saldo from Konto where KontoNr = 1111111 (*)
f2: Select Saldo from Konto where KontoNr = 1111111
f2: /* Berechnung der Anderung des Kontostandes aufgrund des
zuvor gelesenen Wertes */
Update Konto set Saldo = 18000 where KontoNr = 1111111 (#)
f2: commit work
f1: /* Berechnung der Anderung des Kontostandes aufgrund des
zuvor gelesenen Wertes */
Update Konto set Saldo = 17000 where KontoNr = 1111111 (%)
f1: commit work
Obiges Beispiel zeigt, dass in Oracle nicht-koniktserialisierbare Ablaufe moglich
sind.
Ein solcher Ablauf kann verhindert werden, wenn der Anwendungsprogrammierer von Transaktion 1 (in Fenster f1) explizit angibt, dass die gelesenen Werte
spater auch geschrieben werden sollen. Anstelle von (*) sollte daher
Select Saldo from Konto where KontoNr = 1111111 for Update
verwendet werden. Dadurch werden die gelesenen Datensatze implizit gesperrt
und ein nachfolgendes Schreiben einer anderen Transaktion (#) ist nur dann
moglich, wenn T 1 abgeschlossen ist.
b) Reinitialisieren Sie Ihre Datenbank (mit createAndFill) und betrachten sie die
beiden folgenden Transaktionen:
1. T 1 : Select * From Konto where Saldo > 10000
2. T 1 : Select * From Kunde where Name = 'Del Medico' (*)
3. T 2 : Select * From Kunde where Name = 'Del Medico' (%)
4. T 2 : Select * From Konto where Saldo > 10000
5. T 1 : Update Konto set Saldo = Saldo * 1.05 where Saldo > 10000
6. T 2 : Update Kunde set Name = 'Felix' where Name = 'Del Medico'
7. T 2 : Update Konto set Saldo = Saldo * 1.05 where Saldo > 10000
8. T 1 : Update Kunde set Name = 'Felix' where Name = 'Del Medico'
Was stellen Sie bei diesem Ablauf fest? Was wurde hier SELECT FOR UPDATE bewirken? Unter welchen Umstanden konnen dadurch Deadlocks vermieden werden? Konstruieren Sie einen Fall, in dem dies nicht moglich ist!
Gibt es eine Moglichkeit, Deadlocks in jedem Fall zu verhindern? Wenn ja, was
sind die Konsequenzen?
Der vorgegebene Ablauf ist so nicht moglich, da ein Deadlock eintritt. Die Verwendung vom SELECT FOR UPDATE sorgt, wie wir in der vorigen Teilaufgabe bereits festgestellt haben, dafur, dass fur die Tupel einer Leseaktion Schreibsperren
gesetzt werden. Dies blockiert andere Transaktionen mit konigierenden Operationen. Im obigen Beispiel wird auf diese Weise ein Deadlock verhindert, da T 2
4
blockiert wird, bis T 1 beendet ist. Vertauscht man im obigen Beispiel die Operationen (*) und (%), so tritt jedoch wieder ein Deadlock auf. Dies liegt an der
\ungunstigen" Reihenfolge der Operationen.
Generell lassen sich Deadlocks nur vollstandig vermeiden, indem zirkulares Warten verhindert wird. Dies kann entweder durch \Preclaiming" erreicht werden
(alle Transaktionen erwerben alle Sperren, die sie benotigen werden, sofort zu
Beginn der Transaktion in einer atomaren Sperranforderung), oder durch eine
vordenierte Reihenfolge, in der Sperren erworben werden mussen. Legt man im
obigen Beispiel zum Beispiel fest, dass jede Transaktion zuerst ihre Sperren fur
die \Konto"-Tabelle setzen muss, bevor sie Sperren fur die \Kunde"- Tabelle
setzen kann, so werden Deadlocks vermieden.
Aufgabe 3: Read Only-Transaktionen
a) Ein weiteres, aus IS-G bekanntes Problem ist das inkonsistente Lesen. Ist dies in
Oracle fur die Isolationsstufe READ COMMITTED moglich? Konnen Sie hier ein Beispiel nden, bei dem das Repeatable Read nicht gewahrleistet ist? Was kann ein
Anwendungsprogrammierer tun, damit zwei Select-Statements innerhalb einer
Transaktion dasselbe Resultat liefern?
Repeatable Read wird vom Isolatonslevel Read Committed nicht garantiert. Wurde man im Beispiel aus Aufgabe 2.a anstelle von (%) erneut das Select-Statement
(*) ausfuhren, so wurden beide unterschiedliche Resultate zuruckliefern. Repeatable Read kann fur Nur-Lese-Transaktionen erzwungen werden, indem die Transaktion als read-only deklariert wird (SET TRANSACTION READ ONLY). Fur Trans
aktionen, die auch Anderungen
vornehmen, muss das Isolationslevel SERIALIZABLE verwendet werden bzw. es m
ussen explizit Sperren gesetzt werden.
b) Zeigen Sie die Auswirkungen der Option SET TRANSACTION READ ONLY, wenn
gleichzeitig A nderungen erfolgen. Konstruieren Sie einen Fall, in welchem zu
einer Zeit ein und dieselbe Query in drei verschiedenen Fenstern unterschiedliche
Resultate liefert.
Was sagt das Handbuch zu der Option SET TRANSACTION READ ONLY? Ordnen
Sie sie in die Vorlesung ein. Zeigen Sie insbesondere die Zusammenhange zur
Mehrversionenverwaltung.
Das folgende Beispiel zeigt eine Folge von Operationen dreier Transaktionen T 1,
T 2 und T 3, wobei fur jede Transaktion ein eigenes SQLPLUS-Fenster verwendet
wird:
1. T 1: Set transaction Read Only
2. T 2: Update Kunde set Wohnort = 'Basel' where KundenNr = 1
3. T 2: commit work
4. T 2: Set transaction Read Only
5. T 3: Update Kunde set Wohnort = 'Bern' where KundenNr = 1
6. T 3: Commit work
7. T 3: Set transaction read only
5
8. T 1: Select * from Kunde where KundenNr = 1
9. T 2: Select * from Kunde where KundenNr = 1
10. T 3: Select * from Kunde where KundenNr = 1
Wurde die Option SET TRANSACTION READ ONLY gesetzt, so speichert Oracle den
Zeitpunkt des Beginns der Transaktion. Leseaktion der Transaktion sehen den
Zustand der Datenbank, wie er diesem Zeitpunkt existierte. Dies wird erreicht,
indem der alte Wert aus dem Log gelesen wird, falls sich der Wert eines Tupels
seit Transaktionsbeginn geandert hat.
Aufgabe 4: Isolationslevel Serializable
Im Isolationslevel Serializable verwendet Oracle das in der Vorlesung vorgestellte
Mehrversionen-Concurrency-Control-Protokoll mit der Bezeichnung Snapshot Isolation. Jede Transaktion arbeitet auf einer eigenen Version der Datenbank (snapshot ),
die den konsistenten Zustand aller committeter Daten zum Zeitpunkt des Transaktionsbeginns reektiert. Leseaktionen einer Transaktion lesen also Werte so, wie
sie zu Beginn der Transaktion vorlagen (ausser naturlich Werte, welche von dieser
Transaktion selbst geschrieben wurden). Beim Schreiben wird eine neue Version des
jeweiligen Objektes erzeugt, das bis zum erfolgreichen Commit nur fur die eigene
Transaktion sichtbar ist.
a) Setzen Sie die Isolationsstufe auf Set Transaction Isolation Level Serializable und testen Sie einen nicht mehrversionen-view-serialisierbaren Ablauf,
bei dem zwei parallele Transktionen schreibend auf dasselbe Objekt zugreifen.
Lasst sich die in der Vorlesung besprochene Eigenschaft der Snapshot{Isolation
(SSI) hier beobachten?
Wir betrachten den folgenden Ablauf:
1. T 1: Set transaction Isolation Level Serializable
2. T 2: Set transaction Isolation Level Serializable
3. T 1: Select * from Kunde where KundenNr = 1
4. T 2: Select * from Kunde where KundenNr = 1
5. T 2: Update Kunde set Wohnort = 'Bern' where KundenNr = 1
6. T 2: Commit work
7. T 1: Update Kunde set Vorname = 'Ruedi' where KundenNr = 1
Die Transaktion T 1 wird mit der Fehlermeldung ORA-08177: can't serialize
access for this transaction abgebrochen, da keine Serialisierbarkeit mehr
gewahrleistet werden kann.
Um lost updates zu vermeiden (und um die Bedingung SSI{W einzuhalten), wird
fur Schreibaktionen die folgende Regelung eingefuhrt: Wenn eine Transaktion T 1
ein Objekt schreiben will, das von einer anderen Transaktion T 2 geschrieben wurde, so wird |wie im obigen Beispielablauf| T 1 abgebrochen, falls das Commit
von T 2 nach dem Beginn von T 1 stattfand.
Oracle verbietet also korrekterweise diesen Ablauf, der nicht mehrversionenview{serialisierbar ist.
6
b) Modizieren Sie nun Ihren Beispielablauf so, dass einerseits die beiden parallelen Transktionen jeweils unterschiedliche Objekte schreiben, dass aber andererseits die Mehrversionen-View-Serialisierbarkeit immer noch verletzt ist (siehe
praktisches Beispiel, Folien II-108 { II-110 der Vorlesung). Was stellen Sie fest?
Was konnen Sie daraus uber die Korrektheit des von Oracle implementierten
Snapshot-Isolation-Protokolls schliessen?
Das Snapshot Isolation Protokoll erkennt lediglich Konikte zwischen Schreibern
unterschiedlicher Versionen. In dem hier betrachteten Beispielschedule liegen
jedoch keine solchen w/w-Konikte vor.
1. T 1: Set transaction Isolation Level Serializable
2. T 2: Set transaction Isolation Level Serializable
3. T 1: Select * from Kunde where KundenNr = 3
4. T 2: Select * from Konto where KontoNr = 1111111
5. T 2: Update Kunde set Name = 'Ramazotti' where KundenNr = 3
6. T 1: Update Konto set Saldo = Saldo * 1.05 where KontoNr = 1111111
7. T 1: Commit work
8. T 2: Commit work
Uberraschenderweise
ist dieser Ablauf in Oracle ohne Fehler moglich obwohl
dieser Schedule nicht mehrversionen-view-serialisierbar ist.
Dieses Beispiel zeigt also, dass die von Oracle unterstutzte Snapshot-Serialisierbarkeit nicht der in der Vorlesung vorgestellten Mehrversionen-View-Serialisierbarkeit entspricht und diese Implementierung oensichtlich Schedules ermoglicht,
die nicht serialisierbar sind.
7
Herunterladen