Mögliche Abhängigkeiten
Für S1 T1 = (r(v), w(v)) T2 = (w(x), w(w), r(v)) T3 = (w(z), r(y), w(x)) T4 = (r(w), r(z), W(y))
⇒ Gleiche Tranasktions- & Aktionsmenge!
Abhängigkeiten:
⇒ S1 & S2 sind nicht Konfliktäquivalent!
⇒ Gleiche Tranasktions- & Aktionsmenge!
Abhängigkeiten:
⇒ S1 & S2 sind Konfliktäquivalent!
Serialisierungs-/Abhängigkeitsgraph:
a) T1, T2, T4, T3 oder T1, T4, T2, T3 b) nicht serialisierbar
⇒ Annomalien können nur auftreten, wenn Isolation verletzt wird!
Legaler Schedule
Problem von 2PL: Kaskadierendes Rücksetzen (T1 wird nach U1(x) zurückgesetzt (ABORT) ⇒ alle T2. die nach U1(x) auf x zugegriffen haben, müssen auch zurückgesetzt werden ⇒ Durability
Es gild
S0
S1
S2
S3
S4
Verklemmung bezgl. Zugriff auf Verschiedene Objekte:
⇒ Verlemmung, da T1 und T2 gegenseitig warten
Verklemmung bzgl. Sperrkonversion: T1 und T2 warten gegenseitig, aber weil das Protokoll es so will
Verhungern einer Transaktion auf erforderliche Sperre.
bestehend → angefordert | R | X |
---|---|---|
R | ![]() | ![]() |
X | ![]() | ![]() |
bestehend → angefordert | R | U | X |
---|---|---|---|
R | ![]() | ![]() | ![]() |
U | ![]() | ![]() | ![]() |
X | ![]() | ![]() | ![]() |
bestehend → angefordert | R | A | X |
---|---|---|---|
R | ![]() | ![]() | ![]() |
A | ![]() | ![]() | ![]() |
X | ![]() | ![]() | ![]() |
RX | RUX | RAX | |
---|---|---|---|
a) | ![]() | ![]() | ![]() |
b) | ![]() | ![]() | ![]() |
c) | ![]() | ![]() | ![]() |
R | X | IR | IX | RIX | |
---|---|---|---|---|---|
R | ![]() | ![]() | ![]() | ![]() | ![]() |
X | ![]() | ![]() | ![]() | ![]() | ![]() |
IR | ![]() | ![]() | ![]() | ![]() | ![]() |
IX | ![]() | ![]() | ![]() | ![]() | ![]() |
RIX | ![]() | ![]() | ![]() | ![]() | ![]() |
IR-Sperre: tiefere Ebene hat R-Sperre IX-Sperre: tiefere Ebene hat X-Sperre RIX-Sperre:Volle lesesperre, tiefe schreibsperre (R-IX-Sperre)
a) R-Sperre auf Tutpelebene entspricht IR-Sperre (auf Relationsebene) ⇒ Falls es sich um das selbe Tupel handelt, darf die Sperre nicht vergeben werden, sonst schon
b)
Anwendungen (mehrere) | |
Externe Ebene | Views (mehrere) |
---|---|
↓↓ Logische Datenunabhängigkeit ↓↓ | |
Konzeptionelle Ebene | |
↓↓ Physische Datenunabhängigkeit ↓↓ | |
Interne Ebene | Speicherformat |
Zyklus in Graph ⇒ Es liegen verklemmungen vor
⇒ T1 kommt durch
⇒ T3 & T1 kommen durch
T2,T3,T5,T4,T1
Neben an:
Drüber:
Loggranulat ⇐ Sperrgranulat, sonst Lost Updates ???
Update-in-place: geänderte Werte auf ursprüngliche Pos
Einbringstrategien
WAL-Prinzip (Write-Ahead-Log)
denn sonsst: 4-1 c) Schritt 4 (save[B', D]) findet vor EOT1 statt, d.h. wenn WAL-Prinzip verletzt würde, also keine Protokollierung hat Statgefunden & T1 wird zurückgespult ⇒ ursprünglicher Zustand d. DB kann nicht hergestellt werden
REDO Info muss vor COMMIT-Durchführung in der Log-Datei stehen (⇒ relevant für No-Focre)
Aufgabe des Logging:
Seite | PageLSN (Puffer) | PageLSN (Platte) |
---|---|---|
PA | 90 | 90 |
PB | 130 | 0 |
PC | 50 | 50 |
PD | 70 | 0 |
PE | 110 | 60 |
Weitere Datenstrukturen beim Recovery:
Phasen der Crash-Recovery:
Idempotenz von UNDO & REDO:
REDO- und UNDO-Phasen müssen idempotent sein, d.h. sie müssen auch bei mehrfacher Ausführung immer wieder das selbe Ergebniss liefern: f(f(x))=f(x)
Idempotenz von REDO wird durch Check der pageLSN (Platte) sichergestellt.
Idempotenz von UNDO wird durch CLRs sichergestellt.
Vollständiges REDO:
TA | Seite | PageLSN vs LSN | Änderungen in der DB (Platte) |
---|---|---|---|
T1 | PB | 0<20 | PB,20 |
T4 | PC | 50≮50 | |
T1 | PE | 60≮60 | |
T4 | PD | 0<70 | PD,70 |
T2 | PA | 90≮90 | |
T3 | PE | 60<110 | PE,110 |
T2 | PB | 0<130 | PB,130 |
UNDO:
TA | Seite | Zur Log-Date hinzugefügte Log-Einträge | Änderungen auf der DB Platte |
---|---|---|---|
T2 | PB | 180,T2,PB,R(B),U(B),130 | PB,180 |
T2 | PA | 190,T2,PA,R(A),U(A),180 | PA,190 |
T4 | PD | 200,T4,PD,R(D),U(D),70 | PD,200 |
T4 | PC | 210,T4,PC,R(C),U(C),200 | PC,210 |
Slektives REDO:
TA | Seite | Page LSN vs LSN | Änderungen in DB (Platte) |
---|---|---|---|
T1 | PB | 0<20 | PB,20 |
T1 | PE | 60≮60 | |
T3 | PE | 60≮110 | PE,110 |
UNDO:
TA | Seite |
---|
SELECT s.Name FROM student s, lehrveranstaltung v, Dozent d, Hoert h, Haelt hl WHERE d.Titel = "Prof." AND d.Name = "Einstein" AND v.LVType = "Seminar" AND s.MatrNr = h.MatrNr h.LVNr = v.LVNr AND hl.LVNr = v.LVNr AND hl.DozNr = d.DozNr AND
Anmerkung 1: Es bleiben genau die Tupel erhalten, für die gilt d.DozNr = hl.DozNr
d.h. für ursprünglich jedes Tupel aus Haelt
bleibt genau ein Tupel aus der neuen Relation erhaten ˆ=\nicefrac15.
Anmerkung 2: Die 10 Tupel nach s.MatrNr = h.MatrNr
entsprechen genau den Elementen aus Hoert
⇒ vgl. h.LVNr
mit v.LVNr
⇒ 2, 9, 9, 7 ⇒ 4 Tupel
Jeder mit jedem |R|⋅|S|=10⋅10=100
Ein Pointer pro Vergleichssetz. Bei ⇐ wird auf der einen Seite weitergegangen. Bei > wird auf der anderen Seite weitergegangen. Hierfür dürfen keine Duplikate in dem einen Set sein.
18
Hashfunktion h(x) = x mod 5
h(x) | Elemente aus R | Elemente aus S | Vergleiche |
---|---|---|---|
0 | 10, | 5, 10 | 1⋅2=2 |
1 | 1, 6, 11 | 1, 6 | 3⋅2=6 |
2 | 2, 7, 12 | 2 | 3⋅1=3 |
3 | 3,13 | 3,8,13 | 2⋅3=6 |
4 | 9 | 4, 14 | 1⋅2=2 |
Sum | 19 |
Jeder wird mit jedem, aber nur innerhalb des Buckets verglichen.
19
Hashfunktion für Blockbildung: hB(x)=xmod3
hB(x) | Elemente in R | Elemente in S |
---|---|---|
0 | 3, 6, 9, 12 | 3, 6 |
1 | 1, 7, 10, 13 | 1, 4, 10, 13 |
2 | 2, 11 | 2, 5, 8, 14 |
Hashfunktion für Join: h(x)=xmod2 (gerade und ungerade im Block miteinander Vergleichen)
16
|C|−1 Blöcke der äußeren Relation werden in den Cache eingelesen. Zu jedem Block der inneren Relation werden dies Blöcke gejoint.
Plattenzugriffe = BR+BS⋅⌈BR|C|−1⌉=10000+10000⋅⌈10000|1000|−1⌉=120000
Höchstens 100.000 Plattenzugriffe
10000+10000⋅⌈10000|C|−1⌉<=100000
⌈10000|C|−1⌉<=9
frac100009<|C|−1
1112,111<=|C|
Für max. 100000 Plattenzugriffe benötigt man einen Cache von 1113 Blöcken
Die selbe Rechnung nochmal ⇒ D.h. für ein Fünftel d. Plattenzugriffe benötigt man ca. das 10-Fache an cache
Für den Schnitt aus R_1 und R_2 erhält man genau die Tupel, die sowohl in R1 als auch in R2 vorhanden sind
R_1
A | B |
---|---|
a | b |
R_2
A | B |
---|---|
b | b |
Dann gilt πB(R1∩R2)={}, aber πB(R1)∩πB(R2)=b
πl(R1 cupR2)=πl(R1)∪πl(R2)
sei t∈πl(R1∪R2)⇔∃a∈R1∪R2:a.l=t
⇔∃b∈R1:b.l=t∨∃c∈R2:c.l=t
….
πl(R1−R2)=πl(R1)−πl(R2) (Für die Differenz werden alle Tupel aus R1 entfernt, die auch in R2 vorhanden sind)
s.o.
Warum eignen sich traditionalle Ansätze eher nicht für Big Data?
Welche der folgenden Punkte machen für Big Data Sinn?
Was sind Probleme im Umgang mit Computerclustern?
JavaRDD<String[]> gefiltert = linesfilter( new Function<String[]>, Boolean>() { public Boolean call(String[] s) { return !(s[5] == "404" && Integer.parseInt(s[6] > 0)); } } );
gefiltert = linesfilter(lambda x : not(x[5] == "404" and int(x[6]) > 0))
MapReduce:
map()
-Methode oder mapToPair()
-Methode).
reduceByKye()
-Methode)
JavaPairRDD<String, Integer> pairs = getfilter.mapToPair( new PairFunction<String[], String, Integer>() { public Tupel2<String, Integer> call(String[]) { return new Tupel2(s[0], Integer.parseInt(s[6])); } } ); JavaRDD<String, Integer> summiert = pairs.reduceByKey( new Function2<Integer, Integer, Integer>() { public Integer call<Integeri, Integer j) { return i+j; } } );
Spark nutzt den Hauptspeicher und reduziert dadurch die Anzahl der Plattenzugriffe.
Polynomielle Multiplikation um mögliche Ergebnisse aufzuzählen!
F = (P(Attenberger) * x + 1-P(Attenberger)) * (P(Brunner) * x + 1-P(Brunner)) * (P(Carl) * x + 1-P(Carl)) * (P(Deschler) * x + 1-P(Deschler)) = (0.8*x + 0.2) + (0.5*x + 0.5) + (0.6*x + 0.4) + (0.1*x + 0.9) = (0.4*x^2 + 0.4*x^1 + 0.1*x^1 + 0.1*x^0) * (0.6*x + 0.4) * (0.1*x + 0.9) = (0.4*x^2 + 0.5*x^1 + 0.1*x^0) * ... = (0.024*x^4 + 0.216*x^3 + 0.046^x^3 + 0.414*x^2 + 0.026*x^2 + 0.234*x + 0.004*x + 0.036 = 0.024*x^4 + 0.262*x^3 + 0.440*x^2 + 0.238*x^1 + 0.036*x^0