WEBVTT

00:07.070 --> 00:10.010
So, ich habe ja gestern auch mit der Implementierung angefangen, aber

00:10.010 --> 00:13.170
nur sehr kurz, indem ich gesagt habe, auf was stützen wir uns denn bei

00:13.170 --> 00:14.910
der physischen Dateiverwaltung ab.

00:15.590 --> 00:18.750
Und ich kann auch nicht sehr viel von den Implementierungstechniken

00:18.750 --> 00:21.750
abhandeln, obwohl da eine Menge spannender Fragen dabei sind.

00:22.310 --> 00:26.270
Wer von Ihnen also den Fragen der Implementierung so nebenbei ein

00:26.270 --> 00:29.250
bisschen nachgehen will, die Folien stehen ja zur Verfügung, im Buch

00:29.250 --> 00:33.350
ist auch einiges zugesagt, so die wichtigsten Techniken, die für die

00:33.350 --> 00:35.710
Implementierung und damit insbesondere für die Performance

00:35.710 --> 00:38.750
entscheidend sind, die finden Sie also an den Stellen.

00:39.170 --> 00:43.350
Aber einen Teil würde ich doch heute abhandeln, und zwar, das ist die

00:43.350 --> 00:47.110
Segmentschicht, wobei uns bei der Segmentschicht zwei Dinge

00:47.110 --> 00:47.510
interessieren.

00:47.590 --> 00:50.190
Erstmal, wie wir tatsächlich dort schon Performancesteigerung

00:50.190 --> 00:51.190
erreichen können.

00:51.350 --> 00:54.190
Das ist im Wesentlichen, besteht es darin, das Data Staging so zu

00:54.190 --> 00:57.830
treiben, dass man möglichst viel an Vorratshaltung im Hauptspeicher

00:57.830 --> 00:58.170
führt.

00:58.170 --> 01:00.930
Und dann aber vor allem, wie spielt das mit der Transaktionsverwaltung

01:00.930 --> 01:04.170
zusammen, denn die ist ja, wenn wir uns erinnern, mit dem Scheduler

01:04.170 --> 01:07.350
und dem Recovery-Verwalter auch in der Segmentschicht angesiedelt.

01:07.930 --> 01:10.050
Und das sehen wir schon mal an diesem Diagramm.

01:10.830 --> 01:16.330
Die Struktur dieser Segmentschicht, die sieht so aus, dass wir

01:16.330 --> 01:21.690
zunächst einmal alles was reinkommt an Anweisungen, auch wenn es

01:21.690 --> 01:25.350
durchgefiltert wird durch die höheren Schichten, das gehört einer

01:25.350 --> 01:26.370
Transaktion an.

01:28.130 --> 01:31.390
Und diese Transaktion, die manifestiert sich, wie wir inzwischen

01:31.390 --> 01:35.130
wissen, gegenüber der Segmentschicht einfach durch Lese- und

01:35.130 --> 01:37.590
Schreibanweisungen und natürlich durch Wortencommit.

01:38.370 --> 01:41.570
Lese- und Schreibanweisungen, die in dem Fall jetzt natürlich Seiten

01:41.570 --> 01:44.990
betreffen, denn auf der Segmentebene werden ja nur noch Seiten als

01:44.990 --> 01:46.230
Datenelemente angeboten.

01:46.870 --> 01:51.730
Und die erste Aufgabe, die wir ja haben, von gestern noch, ist, dass

01:51.730 --> 01:55.890
der Scheduler zunächst einmal einen Schedule erzeugen muss, der eben

01:55.890 --> 01:59.050
wieder anlaufbar ist und der realisierbar ist.

01:59.270 --> 02:01.050
Wir stellen also jetzt, dass das geleistet wird.

02:02.090 --> 02:05.350
Und er hat, wie wir auch wissen, einen Sperrenverwalter, über den er

02:05.350 --> 02:08.290
noch gewisse Strategien, zum Beispiel die Steuerung und die

02:08.290 --> 02:11.850
Bevorzugung oder ein faires Verhalten nachbildet.

02:12.330 --> 02:15.330
Und dann geht diese globale Historie, die jetzt

02:30.140 --> 02:35.000
aus...

02:35.000 --> 02:38.520
Dann geht diese globale Historie, die jetzt realisierbar und wieder

02:38.520 --> 02:43.120
anlaufbar ist eben, die enthält jetzt Read, Write-Anweisungen, dann

02:43.120 --> 02:47.680
hinterher sind noch eine eigene Anweisung, die Unfix-Operation.

02:48.440 --> 02:50.480
Wir werden gleich noch sehen, welche Bedeutung die hat.

02:52.360 --> 02:53.520
Dann Commit and Abort.

02:54.160 --> 02:56.460
So, der Segmentverwalter, der hat jetzt auch irgendwelche

02:56.460 --> 02:58.140
Verwaltungsaufgaben wahrzunehmen.

02:58.260 --> 03:01.160
Im Wesentlichen ist er derjenige, der sagt, wie die Seiten zu den

03:01.160 --> 03:05.220
Segmenten zugeordnet werden, wie die Seiten innerhalb eines Segments

03:05.220 --> 03:09.180
verwaltet werden, wo beispielsweise dann auch veränderte Seiten

03:09.180 --> 03:10.160
hingeschrieben werden.

03:12.500 --> 03:15.860
Und er bedient sich dann seinerseits eines Puffers, das heißt,

03:16.140 --> 03:18.800
eingelagert, ausgelagert wird immer aus einem Puffer.

03:20.080 --> 03:23.620
Und die Anweisungen, die er dafür vorsieht, heißen Fetch, das heißt,

03:23.680 --> 03:28.780
hol mir etwas von der Peripherie in den Hauptspeicher hinein, wenn es

03:28.780 --> 03:29.820
nicht schon dort ist.

03:30.780 --> 03:35.080
Mark wollen wir einführen, als die Möglichkeit zu markieren, ob man

03:35.080 --> 03:37.760
Änderungen vorgenommen hat an einer Seite.

03:38.220 --> 03:41.520
Flush ist das Rausschreiben auf den Hintergrundspeicher.

03:42.740 --> 03:49.120
Und Pin und Unpin bedeutet, nagle die Seite entweder fest im Puffer,

03:49.840 --> 03:53.360
oder gib sie wieder frei, sodass sie dann ausgelagert werden kann.

03:54.800 --> 03:56.140
Dann haben wir einen Pufferverwalter.

03:56.140 --> 04:00.400
Der Pufferverwalter, der hat als wesentliche Aufgabe, jetzt die

04:00.400 --> 04:02.940
Verbindung mit der Datenbasis herzustellen, also ein- und

04:02.940 --> 04:03.640
auszuschreiben.

04:04.760 --> 04:07.200
Das macht er über sogenannte Datenseiten.

04:08.480 --> 04:13.860
Und dann verfügt er zudem noch über einen Mechanismus, mit dem er

04:13.860 --> 04:15.980
Protokoll führt, und das werden wir uns noch etwas genauer ansehen,

04:16.080 --> 04:16.820
wozu das dient.

04:18.080 --> 04:21.480
Und dafür gibt es spezifische Protokollseiten, die man übrigens beide

04:21.480 --> 04:24.000
über den gleichen Puffer üblicherweise betreibt.

04:24.000 --> 04:27.560
So, und dann kommt noch der katastrophale Fall, den ich schon gestern

04:27.560 --> 04:28.260
angedeutet hatte.

04:28.340 --> 04:31.280
Was passiert denn jetzt, wenn das System zusammenbricht?

04:31.700 --> 04:34.500
Sind alle Spuren erstmal verloren gegangen?

04:34.600 --> 04:37.700
Das Einzige, was wir noch haben, ist, dass die Information, die nicht

04:37.700 --> 04:41.620
flüchtig auf dem Hintergrundspeicher abgelegt ist.

04:41.700 --> 04:45.520
Und wir haben die Aufgabe, einen Zustand wieder herzustellen, der

04:45.520 --> 04:49.260
konsistent ist bezüglich des Zeitpunktes, zu dem das System abgestürzt

04:49.260 --> 04:49.600
ist.

04:49.600 --> 04:56.220
Das heißt, alles, was bereits abgeschlossen war, muss verbleiben in

04:56.220 --> 05:00.100
seiner Wirkung, unabhängig davon, was mit den Seiten tatsächlich

05:00.100 --> 05:02.180
geschehen ist, in der Zwischenzeit.

05:02.740 --> 05:07.260
Und auf der anderen Seite, alles, was abgebrochen war, oder

05:07.260 --> 05:10.880
augenblicklich aktiv war, das muss auf jeden Fall in einen

05:10.880 --> 05:13.200
abgebrochenen Zustand gebracht werden, oder verbleiben.

05:13.780 --> 05:17.200
Und das machen wir bei einer Restart-Operation, und dazu gibt es einen

05:17.200 --> 05:19.160
eigenen Backup- und Recovery-Verwalter.

05:20.840 --> 05:21.880
Das sind die Architekturen.

05:21.960 --> 05:24.760
Jetzt schauen wir uns mal, nachdem wir Scheduler schon kennen, und den

05:24.760 --> 05:26.700
Sperrenverwalter schauen wir uns also mal den Rest an.

05:29.860 --> 05:33.200
So, wir hatten schon gesagt, auf der Segmentebene haben wir es nur

05:33.200 --> 05:34.400
noch mit Seiten zu tun.

05:34.680 --> 05:36.220
Seiten sind die Transporteinheiten.

05:36.320 --> 05:39.680
Und das Erste, was wir tun, ist, dass wir sagen, wenn wir eine Seite

05:39.680 --> 05:42.300
ansprechen, dann ist das die Einheit, die vom Hintergrund auf den

05:42.300 --> 05:44.460
Hauptspeicher, oder umgekehrt, transportiert wird.

05:44.460 --> 05:48.440
Und gestern hat man zum Abschluss noch gesagt, die blockorientierte

05:48.440 --> 05:51.760
Dateiverwaltung liefert uns logische Blöcke, und dann ist es ganz

05:51.760 --> 05:56.000
natürlich, dass wir die logischen Blöcke als die Behälter für Seiten

05:56.000 --> 05:56.540
ansehen.

05:57.340 --> 06:01.320
Und dann können wir noch logische Adressräume anlegen, sogenannte

06:01.320 --> 06:01.840
Segmente.

06:02.120 --> 06:04.820
Und diese Segmente, das müssen wir uns jetzt einfach vorstellen, als

06:04.820 --> 06:09.400
eine große Art Datei mit zusätzlichen Eigenschaften.

06:09.860 --> 06:13.420
Was wir insbesondere aber tun, ist, dass wir unterteilen ein Segment

06:13.420 --> 06:18.280
einfach in eine hinreichend große Zahl von Seiten.

06:18.980 --> 06:21.460
Und diese Seiten werden einfach durch Seitennummern adressiert.

06:21.560 --> 06:23.680
Man könnte sich aber auch vorstellen, dass das eine Art dynamischer

06:23.680 --> 06:25.780
Array mit Seiten ist.

06:27.540 --> 06:29.300
Das ist auch hier unten nochmal angegeben.

06:30.740 --> 06:34.620
Und eine weitere Annahme, die wir jetzt machen, ist, dass wir

06:34.620 --> 06:39.120
versuchen, wenn auf eine Seite zugegriffen wird, dass sie sich bereits

06:39.120 --> 06:45.540
im Hauptspeicher, also im Puffer, befindet, sodass wir tatsächlich im

06:45.540 --> 06:49.220
Wesentlichen nicht mit der großen Zugriffszeit auf den

06:49.220 --> 06:51.360
Hintergrundspeicher, sondern nur mit der verhältnismäßig geringen

06:51.360 --> 06:55.420
Zugriffszeit auf eine Pufferseite zu rechnen haben.

06:56.140 --> 06:58.980
Wir wollen aber von außen gesehen in jedem Fall gar nicht wissen, wo

06:58.980 --> 07:00.520
sich die Seite im Augenblick befindet.

07:00.920 --> 07:02.240
Hoffentlich, wie gesagt, im Puffer.

07:02.820 --> 07:06.920
Wir adressieren sie aber unabhängig davon, wo sie sich augenblicklich

07:06.920 --> 07:08.820
befindet, auf gleiche Weise.

07:09.280 --> 07:13.020
Wir können deshalb sagen, ein Segment ist so eine Art virtuelle Datei

07:13.020 --> 07:18.760
im Hauptspeicher, von der wir nicht wissen wollen, wo sie liegt, aber

07:18.760 --> 07:20.500
von der wir hoffen, dass sie sich im Hauptspeicher befindet.

07:22.520 --> 07:25.980
Speicherort und Transport sollen infolgedessen transparent sein.

07:27.780 --> 07:29.520
So, die Operatoren hatte ich schon genannt.

07:30.260 --> 07:31.940
Wir müssen nur jetzt Folgendes sehen.

07:33.560 --> 07:38.080
Wir müssen zunächst einmal überhaupt Segmente freigeben, definieren,

07:38.240 --> 07:38.980
öffnen, schließen.

07:39.420 --> 07:40.440
Wie bei einer Datei auch.

07:40.820 --> 07:43.900
Dann, wenn wir lesen, dann lesen wir eine Seite X.

07:45.040 --> 07:46.060
Das ist die Seitennummer.

07:46.520 --> 07:48.780
Und wir erhalten zurück eine Adresse.

07:49.400 --> 07:51.580
Nämlich eine Adresse im Puffer, das ist also eine

07:51.580 --> 07:51.940
Hauptspeicheradresse.

07:52.660 --> 07:55.600
Dieses X hier als Rückgabeparameter gibt uns also die

07:55.600 --> 08:00.000
Hauptspeicheradresse an, in der die Seite zu finden ist.

08:00.000 --> 08:02.520
Und diese Adresse geben wir der Anwendung nach außen.

08:02.600 --> 08:06.700
Das heißt, die wandert über die Grenze unserer Segmentverwaltung in

08:06.700 --> 08:10.140
die nächste Ebene, also beispielsweise in die physischen

08:10.140 --> 08:13.640
Datenstrukturen, wenn wir dann B-Baum etwa verwalten, dann kriegt er

08:13.640 --> 08:17.380
also zunächst einmal für die Seite, die er angefordert hat, einfach

08:17.380 --> 08:18.760
die Hauptspeicheradresse zurück.

08:19.260 --> 08:21.620
Und jetzt sehen wir schon, welche Folge das hat.

08:22.540 --> 08:28.640
Wenn wir nämlich nach außen die Adresse einer Seite geben, dann haben

08:28.640 --> 08:32.040
wir von dem Augenblick an, hat der Segmentverwalter und auch der

08:32.040 --> 08:34.980
Pufferverwalter völlig die Kontrolle darüber verloren, was denn mit

08:34.980 --> 08:35.900
dieser Seite passiert.

08:37.080 --> 08:40.440
Er wird also erst wieder beobachten können, dass mit der Seite etwas

08:40.440 --> 08:43.820
zu geschehen hat, wenn die Anwendung eine ausdrückliche Anweisung

08:43.820 --> 08:44.100
gibt.

08:45.180 --> 08:47.440
Diese ausdrückliche Anweisung, die einzige, die wir wissen, die

08:47.440 --> 08:48.540
möglich ist, ist ein Write.

08:49.400 --> 08:53.880
Das heißt, er sagt dann, schreib bitte diese Seite wieder aus auf den

08:53.880 --> 08:57.000
Hintergrundspeicher, mache sie jedenfalls am Ende der Transaktion dann

08:57.000 --> 08:57.780
persistent.

09:01.140 --> 09:07.980
Und damit jetzt verhindert wird, dass die Seite versehentlich aus dem

09:07.980 --> 09:12.500
Puffer entfernt wird, während die Anwendung sie noch benutzt, müssen

09:12.500 --> 09:22.100
wir diese Seite im Puffer festmachen und infolgedessen, das können wir

09:22.100 --> 09:26.900
automatisch machen mit der Leseanweisung, wenn sie nicht mehr benötigt

09:26.900 --> 09:35.880
wird, muss aber die ausdrücklich an die Transaktion eine

09:35.880 --> 09:37.220
Anfixoperation geben.

09:37.320 --> 09:41.440
Es ist ja durchaus möglich, dass sie zum Beispiel zwar schon ein Write

09:41.440 --> 09:44.780
gibt, aber durchaus diese Seite auch nachher noch lesen will.

09:44.780 --> 09:47.020
Sie darf sie nicht mehr ändern, wie wir wissen, denn wenn wir ein

09:47.020 --> 09:49.480
Write gegeben haben, darf kein zweites Write erfolgen, aber sie darf

09:49.480 --> 09:52.140
natürlich unverändert den Inhalt immer noch weiter lesen.

09:52.600 --> 09:55.900
Es kann also sein, dass sie für Lesezwecke die Seite noch länger im

09:55.900 --> 09:59.760
Puffer halten will, also nach dem Schreiben noch halten will und

09:59.760 --> 10:02.860
infolgedessen geben wir ihr eine eigene Anweisung, Anfix, die besagt,

10:03.320 --> 10:05.560
wann die Seite entfernt werden kann.

10:05.980 --> 10:08.960
Anfix hat überhaupt nichts mit Sperren zu tun, nebenbei.

10:09.640 --> 10:14.040
So ein Anfix ist nur eine Anweisung, dass die Pufferverwaltung die

10:14.040 --> 10:17.100
Seite jetzt nicht mehr weiter im Puffer zu halten hat, weil sie nicht

10:17.100 --> 10:19.180
mehr von der Transaktion benötigt wird.

10:19.640 --> 10:22.320
Es kann aber durchaus sein, dass die Sperre noch bis zum Ende, wenn

10:22.320 --> 10:25.200
wir strenges Zwei-Phasen-Sperrprotokoll fahren, trotzdem die Sperre

10:25.200 --> 10:29.340
auf der Seite selbst, aber jetzt muss man sagen, aus der Sicht von

10:29.340 --> 10:32.160
oben gesehen, unabhängig davon, wo sich die Seite im Augenblick

10:32.160 --> 10:34.600
befindet, dass die Seite immer noch mit der Sperre versehen ist.

10:35.600 --> 10:41.900
So, und Commit and Abort geben wir nur mit, um anzudeuten, ob jetzt

10:41.900 --> 10:44.400
die Transaktion abgebrochen oder abgeschlossen werden soll.

10:46.420 --> 10:50.740
Jetzt kommt noch etwas weiteres hinzu, wenn wir nochmal zurückgehen.

10:52.680 --> 10:57.480
Dann unterstellen wir, dass all diese Komponenten, die wir hier stehen

10:57.480 --> 11:01.500
haben, möglichst autonom agieren, also sich möglichst wenig

11:01.500 --> 11:02.720
gegenseitig beeinflussen.

11:02.720 --> 11:05.200
Die einzige Beeinflussung, die wir wirklich eigentlich nur zulassen

11:05.200 --> 11:07.920
wollen, ist direkt die Anweisung, die wir geben.

11:08.520 --> 11:15.280
Also heißt das insbesondere, wenn ich jetzt beispielsweise ein Write

11:15.280 --> 11:20.120
gebe, und dieses Write gebe ich weiter an die Pufferverwaltung, dann

11:20.120 --> 11:25.400
ist der Pufferverwalter völlig frei, wann er tatsächlich die Seite auf

11:25.400 --> 11:28.540
den Hintergrundspeicher schreibt.

11:29.340 --> 11:32.620
Es sei denn, wir zwingen ihn, oder der Segmentverwalter zwingt ihn

11:32.620 --> 11:33.500
ausdrücklich dazu.

11:35.060 --> 11:37.640
Und das hat gewisse Folgen, die wir auch noch genauer betrachten

11:37.640 --> 11:37.920
müssen.

11:39.940 --> 11:43.340
Also wir halten den Segmentverwalter autonom, wir wollen den

11:43.340 --> 11:48.140
Pufferverwalter autonom halten, über das Anfix entkoppeln wir Sperren

11:48.140 --> 11:52.020
und Segmentverwalter, das heißt die Sperre ist davon nicht berührt,

11:52.120 --> 11:55.320
sehr wohl, aber kann der Segmentverwalter erklären, demgegenüber, dass

11:55.320 --> 11:56.280
wir die Seite nicht mehr brauchen.

11:58.720 --> 12:00.220
So, das werde ich mal überspringen.

12:02.220 --> 12:05.300
Das, was uns interessiert, ist zunächst einmal, wie adressieren wir

12:05.300 --> 12:11.060
eigentlich die einzelne Seite innerhalb eines Segments.

12:13.920 --> 12:19.800
Wir werden folgendes wollen, dass die Zuordnung zwischen der Seite und

12:19.800 --> 12:24.380
dem logischen Block das 1 zu 1 erfolgt, das heißt, dass zu einer Seite

12:24.380 --> 12:25.560
genau ein logischer Block gehört.

12:25.560 --> 12:27.680
Logischer Block war, wenn Sie sich erinnern, wenn wir zur

12:27.680 --> 12:32.360
Dateiverwaltung gehen, genau die Übertragungseinheit und wir wollen

12:32.360 --> 12:37.260
natürlich dann auch so steuern, dass wenn wir eine Seite anfordern,

12:37.300 --> 12:42.840
dass wir damit genau eine Übertragung verursachen, maximal, wenn sich

12:42.840 --> 12:44.860
die Seite nicht bereits im Puffer befindet.

12:46.220 --> 12:50.680
Das heißt, wir wollen über die Segmentverwaltung selbst, wollen wir

12:50.680 --> 12:53.940
steuern, wie in welchen Einheiten übertragen wird.

12:54.840 --> 12:57.440
Damit wird nämlich auch das ganze Data Staging, das wir dann weiter

12:57.440 --> 13:00.240
oben treiben, das verlässt sich immer darauf, dass wenn ich eine Seite

13:00.240 --> 13:02.720
vorgebe und ich organisiere mir die Seite jetzt in passender Weise,

13:02.840 --> 13:06.260
zum Beispiel, indem ich zusammengehörige Tuppel auf einer Seite

13:06.260 --> 13:11.280
unterbringe, dann muss ich sicher sein, dass wenn ich auf einer Seite

13:11.280 --> 13:15.080
Sätze gemeinsam führe, dass das auch tatsächlich nur einen einzigen

13:15.080 --> 13:16.380
Übertragungsvorgang bedingt.

13:17.140 --> 13:20.980
Deshalb führen wir zunächst einmal strikt eine 1 zu 1 Zuordnung vor,

13:20.980 --> 13:24.420
das heißt, wenn ich eine Seite adressiere, dann wird damit genau ein

13:24.420 --> 13:28.220
Übertragungsvorgang ausgelöst.

13:29.500 --> 13:32.620
So, das Segmente selbst können dynamisch wachsen, weil wir uns

13:32.620 --> 13:36.880
erinnern, dass wir die physischen Dateien dynamisch wachsen lassen.

13:37.060 --> 13:38.280
Das kriegen wir also dann geschenkt.

13:39.180 --> 13:40.720
Wir werden noch ein bisschen mehr fordern.

13:41.220 --> 13:44.680
Wir werden zum Beispiel folgendes fordern, wenn wir Seiten

13:44.680 --> 13:50.200
durchnummerieren von 1 bis N und wir wollen beispielsweise die Seiten

13:50.200 --> 13:54.460
der Reihe nach aufgreifen, dann muss das bedeuten, dass wir auch

13:54.460 --> 14:01.180
entsprechend dem Zuordnen eine Durchnummerierung der logischen Blöcke

14:01.180 --> 14:02.420
von 1 bis N.

14:02.520 --> 14:07.560
Das heißt, wir sollten, und wenn wir es jetzt schaffen, dass

14:07.560 --> 14:13.480
aufeinanderfolgende logische Blöcke schneller übertragen werden, als

14:13.480 --> 14:21.220
dann, wenn die Folge der Blocknummern nicht kontinuierlich ist, dann

14:21.220 --> 14:24.840
kann ich umgekehrt auch sicherstellen, dass wenn ich von der

14:24.840 --> 14:28.540
Nummerierung her aufeinanderfolgende Seiten aufrufe, dass ich dann

14:28.540 --> 14:34.320
schneller bin, als wenn ich einfach willkürlich und zufallsgesteuert

14:34.320 --> 14:35.900
die Seitennummern aufrufe.

14:37.260 --> 14:42.200
Also kann man schon sehen, allein durch eine Zuordnung von Seiten und

14:42.200 --> 14:48.480
Segmenten zu Dateien und logischen Blöcken und die

14:48.480 --> 14:52.700
Zuordnungsverfahren, die man wählt, kann man versuchen, so weit als

14:52.700 --> 14:56.980
möglich auch auf dem abstrakten Niveau von Seiten und Segmenten eine

14:56.980 --> 14:59.680
gewisse Steuerung des Zugriffs und damit eine gewisse

14:59.680 --> 15:01.520
Performancekontrolle durchzuführen.

15:01.660 --> 15:04.080
Das steckt also so in diesen Strukturabbildungen drin.

15:06.580 --> 15:09.380
Jetzt kann man nicht immer damit was anfangen, das werden wir jetzt

15:09.380 --> 15:10.780
mal folgendermaßen hier ansehen.

15:12.120 --> 15:14.680
Wir müssen natürlich jetzt sagen, wie sieht die direkte

15:14.680 --> 15:18.160
Seitenadressierung aus, oder die Seitenadressierung aus.

15:19.880 --> 15:23.560
Ich habe nämlich bis jetzt beschrieben den Fall, dass

15:23.560 --> 15:27.740
aufeinanderfolgende logische Blöcke werden schneller zugriffen, als

15:27.740 --> 15:32.680
wenn ich im Zufallsverfahren zugreife und dann erreiche ich sicherlich

15:32.680 --> 15:35.880
auch höhere Geschwindigkeit, wenn ich auch die Seitennummern der Reihe

15:35.880 --> 15:36.500
nach aufgreife.

15:36.580 --> 15:40.840
Das gilt aber nur, wenn ich tatsächlich folgendermaßen vorgehe.

15:41.240 --> 15:43.820
Ich habe mal hier ein Segment und hier eine Datei.

15:43.940 --> 15:47.260
Übrigens hier ist mal ein Beispiel, das ist nicht ausgeschlossen, dass

15:47.260 --> 15:50.140
mehrere Segmente in einer Datei zu liegen kommen.

15:50.240 --> 15:53.800
Das macht man gelegentlich, wenn man bei den Segmenten unterscheiden

15:53.800 --> 15:53.980
will.

15:54.080 --> 15:56.820
Zum Beispiel das eine sind die Rohdaten und das andere sind

15:56.820 --> 15:58.000
Indexdaten.

15:58.480 --> 16:01.100
Dann will man die von den Segmenten her unterschiedlich behandeln,

16:01.180 --> 16:04.660
will sie aber trotzdem physisch in der gleichen Datei speichern.

16:05.240 --> 16:06.540
Dann haben wir aber folgende Situation.

16:07.080 --> 16:09.940
Wir nummerieren hier unsere Segmente der Reihe nach durch.

16:10.040 --> 16:13.240
Wir können uns das vorstellen, das besteht aus der Seite 1, der Seite

16:13.240 --> 16:15.300
2, Seite 3 usw.

16:15.420 --> 16:17.820
Dann haben wir nochmal ein zweites Segment, das besteht auch aus der

16:17.820 --> 16:19.260
Seite 1, 2 usw.

16:20.340 --> 16:25.760
Direkte Adressierung heißt jetzt, dass ich einen logischen Block

16:25.760 --> 16:28.260
genauso sequenziell zuordne.

16:28.360 --> 16:33.640
Also wenn ich hier jetzt N Seiten habe für das Segment 1, dann habe

16:33.640 --> 16:38.540
ich hier auch entsprechend N Blöcke für das Segment 1.

16:39.180 --> 16:42.860
Und die Zuordnung ist so, dass die Seite 1 dem ersten Block in dieser

16:42.860 --> 16:46.520
Folge zugeordnet wird, der zweiten Seite der zweite Block usw.

16:47.220 --> 16:50.740
Das heißt, eine ganz einfache Adressumrechnung, wenn ich also weiß,

16:51.480 --> 16:55.260
welches der erste Block in der Datei für mein Segment 1 ist, dann kann

16:55.260 --> 16:58.600
ich sofort für jede beliebige Seitennummer die entsprechende

16:58.600 --> 16:59.760
Blockadresse berechnen.

17:00.320 --> 17:04.860
Hier geht es dann weiter, ab hier geht unser Segment 2 weiter.

17:05.820 --> 17:09.800
Und an der Position N plus 1 befindet sich die Seite 1 des Segments 2,

17:09.940 --> 17:11.940
wie gesagt, wieder eine ganz einfache Adressumrechnung.

17:13.700 --> 17:20.800
Nur, wenn wir so vorgehen, wenn wir mehr als ein Segment in einer

17:20.800 --> 17:23.040
Datei speichern, dann sieht man natürlich deutlich, jetzt wird es mit

17:23.040 --> 17:24.420
dem Wachstum erheblich schwieriger.

17:24.900 --> 17:29.400
Wenn wir uns nämlich jetzt vorstellen, dass unser Segment 1 wachsen

17:29.400 --> 17:33.760
soll, dann müsste es natürlich auch aufgrund der direkten Adressierung

17:33.760 --> 17:34.740
an dieser Stelle wachsen.

17:35.400 --> 17:38.220
Und jetzt ist natürlich das Segment 2 im Weg, das heißt, wir müssen

17:38.220 --> 17:41.480
jetzt das ganze Segment 2 nach rechts verschieben und nach oben

17:41.480 --> 17:44.060
verschieben, um Platz für das Segment 1 zu schaffen.

17:45.280 --> 17:49.660
Das spricht eher dafür, dass man vermeiden sollte, zumindest wenn

17:49.660 --> 17:53.320
Segmente dynamisch wachsen können, dass man mehr als ein Segment in

17:53.320 --> 17:54.380
einer Datei unterbringt.

17:54.480 --> 17:58.160
Aber im Prinzip verbietet uns nichts, auch mehr als ein Segment

17:58.160 --> 17:58.920
unterzubringen.

18:01.340 --> 18:04.080
Wenn wir das nicht machen wollen, dann machen wir eine indirekte

18:04.080 --> 18:07.240
Satzadressierung, die sieht so aus.

18:09.440 --> 18:19.000
Bei der indirekten Seitenadressierung ermitteln wir zu einer gegebenen

18:19.000 --> 18:23.680
Seite, zum Beispiel zu Seite 1 des Segments 1, die zugehörige

18:23.680 --> 18:27.000
Blogadresse in unserer Datei.

18:28.100 --> 18:31.080
Und da die jetzt nicht mehr direkt ermittelbar ist, also nicht mehr

18:31.080 --> 18:34.600
durch unmittelbare Rechnung, hilft nur eine Indirektion mit Hilfe

18:34.600 --> 18:35.440
einer Seitentabelle.

18:36.680 --> 18:39.400
Also hier in diesem Fall sehen wir folgendes, wir haben hier eine

18:39.400 --> 18:44.140
Seitentabelle für das Segment 1, die besagt, die Seite 1 befindet sich

18:44.140 --> 18:46.480
im Block Nummer 2, also an dieser Stelle.

18:48.560 --> 18:51.500
Jetzt haben wir volle Flexibilität, wir haben jetzt hier so eine Art

18:51.500 --> 18:53.320
Halte in der Datei.

18:53.540 --> 18:55.840
Wir müssen auch an dieser Stelle in Folge dessen noch eine Bittabelle

18:55.840 --> 18:59.380
mitführen, die besagt, welche Blöcke sind denn in dieser Datei

18:59.380 --> 19:01.100
augenblicklich frei und welche sind besetzt.

19:01.100 --> 19:02.860
1 steht also für besetzt.

19:05.420 --> 19:09.120
Und wir können jetzt natürlich mit Wachstum hervorragend umgehen,

19:09.340 --> 19:11.900
zahlen aber zwei Preise.

19:12.460 --> 19:15.480
Der erste Preis besteht darin, dass wir natürlich eine Indirektion

19:15.480 --> 19:16.740
haben mit dieser Seitentabelle.

19:17.680 --> 19:21.940
Und wenn die Seitentabelle sehr groß ist, also zunächst mal wenn das

19:21.940 --> 19:24.580
Segment sehr groß ist, dann wird auch die Seitentabelle natürlich

19:24.580 --> 19:25.400
entsprechend groß.

19:25.960 --> 19:28.460
Und bald landet die Seitentabelle natürlich auch auf dem

19:28.460 --> 19:29.280
Hintergrundspeicher.

19:29.280 --> 19:32.020
Und im schlimmsten Fall kann Folgendes passieren.

19:32.500 --> 19:39.320
Wir fordern eine Seite an, um den Block zu bestimmen, in dem sich

19:39.320 --> 19:43.540
diese Seite befindet, müssen wir erstmal die Seitentabelle betrachten.

19:43.680 --> 19:46.120
Die Seitentabelle befindet sich auch nicht im Hauptspeicher,

19:46.220 --> 19:48.000
jedenfalls nicht im entsprechenden Teil, den wir brauchen.

19:48.760 --> 19:53.820
Also wird erstmal die zugeladen und anschließend wird dann daraus die

19:53.820 --> 19:57.600
Adresse entnommen, die Nummer des logischen Blocks und dann muss der

19:57.600 --> 19:59.100
auch noch eingelagert werden.

19:59.240 --> 20:00.400
Also zwei Seitenzugriffe.

20:01.020 --> 20:04.340
Jetzt kann man auch noch zeigen, dass wenn wir mit virtuellen

20:04.340 --> 20:08.620
Speichern arbeiten, dass sich dann noch bis zu zwei weitere, je

20:08.620 --> 20:12.940
Zugriff, noch mal bis zu zwei weitere Hintergrundspeicherzugriffe

20:12.940 --> 20:13.760
ergeben können.

20:14.280 --> 20:19.300
Und dann hat man plötzlich, im aller ungünstigsten Fall, zwei mal drei

20:19.300 --> 20:21.340
gleich sechs Seitenzugriffe.

20:21.340 --> 20:24.440
Und wenn das nur hinreichend häufig passiert, dann wird das System

20:24.440 --> 20:28.040
furchtbar langsam, weil statt, wie Sie glauben, einen einzigen

20:28.040 --> 20:31.240
Seitenzugriff, plötzlich sechs Zugriffe auf den Hintergrundspeicher

20:31.240 --> 20:31.680
erfolgen.

20:32.740 --> 20:37.680
Also wir verlieren an dieser Stelle zunächst einmal eine gewisse

20:37.680 --> 20:38.200
Kontrolle.

20:40.080 --> 20:43.680
Es können sich erheblich mehr Seitenzugriffe oder Blockzugriffe

20:43.680 --> 20:46.600
verbergen hinter einem Zugriff auf eine einzelne Seite.

20:46.600 --> 20:51.120
Zweiter Nachteil ist, gelegentlich wollen wir ja genau kontrollieren,

20:51.260 --> 20:55.480
dass Sätze zum Beispiel nicht nur auf die gleiche Seite zu liegen

20:55.480 --> 20:58.060
kommen, sondern wenn die Seite überläuft, dann wenigstens auf die

20:58.060 --> 20:59.040
benachbarte Seite.

21:01.340 --> 21:04.660
Wir unterstellen ja immer, wenn wir von Nachbarschaft sprechen, bei

21:04.660 --> 21:07.920
Seiten etwa, dann hätten wir gerne, dass das auch bedeutet, minimale

21:07.920 --> 21:10.660
Zugriffszeit beim Überwechseln von einer Seite zur nächsten.

21:12.200 --> 21:16.580
Wenn das nun zurückgeführt wird auf eine unmittelbare Nachbarschaft

21:16.580 --> 21:19.440
der logischen Blöcke, wenn da also die größte Geschwindigkeit erzielt

21:19.440 --> 21:20.400
wird, dann ist das hier verloren.

21:21.220 --> 21:25.020
Denn hier sehen wir zum Beispiel, wenn wir auf die Seite, wo haben wir

21:25.020 --> 21:28.660
denn das hier, hier ist zufällig alles ganz gut, wir nehmen hier mal

21:28.660 --> 21:33.440
P12 und P13, dann ist die eine 3 und die andere ist der Block J und

21:33.440 --> 21:36.740
wenn wir jetzt hier hin sehen, dann sehen wir das, das, das an dieser

21:36.740 --> 21:39.360
Stelle und an dieser Stelle, das heißt plötzlich liegen die Blöcke

21:39.360 --> 21:40.180
sehr weit auseinander.

21:40.180 --> 21:42.980
Möglicherweise auch auf unterschiedlichen Zylindern.

21:44.840 --> 21:51.840
Also die indirekte Adressierung, der hat insoweit Nachteile, als wir

21:51.840 --> 21:57.140
erheblich weniger Kontrolle ausüben können über unsere Performance.

21:57.460 --> 22:00.520
Wie schnell kann ich zugreifen, weil die Nachbarschaftsverhältnisse

22:00.520 --> 22:03.720
nicht mehr, weil die nicht mehr identisch sind auf der Segmentebene

22:03.720 --> 22:06.500
und auf der Ebene der physischen Datei.

22:09.260 --> 22:12.140
Also, erste Unterscheidung, wollen wir direkt oder indirekt

22:12.140 --> 22:12.680
adressieren.

22:13.200 --> 22:16.780
Die zweite Unterscheidung ist, wie, jetzt kommen wir zum

22:16.780 --> 22:20.220
Segmentverwalter, eigentlich zu seiner eigentlichen Aufgabe, wie

22:20.220 --> 22:24.160
bringt er eigentlich eine neue Seite in oder eine veränderte Seite in

22:24.160 --> 22:25.160
die Datenbasis ein.

22:26.240 --> 22:29.020
Da gibt es auch zwei, da gibt es auch wieder eine direkte

22:29.020 --> 22:32.200
Einbringstrategie, die direkte Einbringstrategie sagt nichts anderes,

22:32.280 --> 22:34.240
als schreibt das Ding dorthin, wo du es hergeholt hast.

22:35.120 --> 22:41.000
Also, wir lesen eine Seite ein, ändern die irgendwie und am Ende

22:41.000 --> 22:43.180
müssen wir sie wieder rausschreiben und wir schreiben sie wieder genau

22:43.180 --> 22:44.040
an die gleiche Stelle.

22:46.120 --> 22:48.900
Das heißt, die Seite wird nach jeder Änderung in ihren einmal

22:48.900 --> 22:51.340
zugeordneten Block zurückgeschrieben.

22:51.480 --> 22:58.080
Wir belassen, wir fixieren also die Zuordnung von Seite zu logischem

22:58.080 --> 23:02.360
Block und wir nennen das Ganze auf Englisch update and place.

23:02.840 --> 23:05.620
Also genau an der gleichen Stelle wird die Änderung untergebracht.

23:06.380 --> 23:08.780
Das funktioniert übrigens sowohl mit der direkten wie mit der

23:08.780 --> 23:12.240
indirekten Adressierung, aber man sieht deutlich, direkte Adressierung

23:12.240 --> 23:15.720
ist natürlich dann der schmerzloseste Weg, weil wir einfach mit

23:15.720 --> 23:16.960
Adressrechnung arbeiten können.

23:17.060 --> 23:19.280
Aber wir können natürlich auch eine indirekte Adressierung vornehmen

23:19.280 --> 23:24.100
und schreiben trotzdem dann halt in die einmal zugeordneten Block

23:24.100 --> 23:24.940
wieder zurück.

23:26.120 --> 23:32.700
Die indirekte Einbringstrategie hingegen sagt, jetzt denken wir mal an

23:32.700 --> 23:36.740
unsere Transaktionsverwaltung, über Transaktionsverwaltung gilt ja,

23:36.900 --> 23:40.500
wenn wir eine Änderung zurückschreiben und die Transaktion ist noch

23:40.500 --> 23:44.600
nicht am Ende, also noch nicht abgeschlossen, insbesondere eben auch

23:44.600 --> 23:47.740
noch nicht erfolgreich abgeschlossen, dann weiß man ja gar nicht, ob

23:47.740 --> 23:49.360
die Änderung eigentlich gültig ist oder nicht.

23:49.720 --> 23:52.420
Kann ja sein, dass wir hinterher noch abbrechen und folgendessen

23:52.420 --> 23:55.360
eigentlich den alten Wert und nicht den neuen Inhalt der Seite

23:55.360 --> 23:55.780
brauchen.

23:56.980 --> 23:59.520
Wir haben aber überschrieben, also ist der alte weg.

24:01.680 --> 24:06.340
Wenn wir indirekt vorgehen, indirekte Einbringstrategie, dann arbeiten

24:06.340 --> 24:07.000
wir uns daran vorbei.

24:07.120 --> 24:09.320
Dann sagen wir, naja, wir werden den alten Wert noch brauchen, dann

24:09.320 --> 24:10.020
lassen wir ihn halt mal drin.

24:10.560 --> 24:14.420
Also muss der neue Inhalt der Seite, muss woanders hingeschrieben

24:14.420 --> 24:14.760
werden.

24:15.180 --> 24:19.140
Also schaffen wir uns zunächst mal einen neuen Block, schreiben dort

24:19.140 --> 24:23.220
den neuen Inhalt hin und sollte jetzt irgendwas passieren, dann haben

24:23.220 --> 24:27.740
wir immer noch den alten Inhalt, nämlich die alte Seite und den alten

24:27.740 --> 24:33.020
Block und können einfach wieder die Adresse zurückrichten auf die

24:33.020 --> 24:35.480
Seitenadresse auf den alten Block.

24:36.240 --> 24:38.920
Das geht, wie wir sehen, natürlich nur noch mit der indirekten

24:38.920 --> 24:42.620
Adressierung, denn die Adresse ändert sich ja in jedem Fall spätestens

24:42.620 --> 24:46.340
zum Zeitpunkt des Commits der Transaktion.

24:48.320 --> 24:52.920
Dafür gibt es übrigens auch eine Strategie, der sogenannte

24:52.920 --> 24:56.460
Schattenspeicher, in dem man gleich auch noch etwas an

24:56.460 --> 24:57.560
Sicherungstechnik einbaut.

24:58.020 --> 24:59.200
Den führe ich gleich mal schnell vor.

25:00.620 --> 25:02.360
Der sieht nämlich folgendermaßen aus.

25:03.080 --> 25:07.560
Wir haben hier, also das kennen wir jetzt schon, hier haben wir unsere

25:07.560 --> 25:12.180
zwei Segmente, hier haben wir unsere beiden Seitentabellen, hier haben

25:12.180 --> 25:17.500
wir die eigentliche Datei und wir haben hier eine Bit-Tabelle.

25:17.600 --> 25:20.180
Jetzt ist die aber, der Freispeicher, zweimal da.

25:20.840 --> 25:24.740
Und, was auch zweimal da ist, ist diese Seitentabelle.

25:26.140 --> 25:27.260
Also wir arbeiten mit so ein paar.

25:28.400 --> 25:32.340
Und zwar arbeiten wir, wenn wir uns Folgendes vorstellen, wir haben

25:32.340 --> 25:34.880
irgendwo mal einen Zeitpunkt erreicht, da ist es unserer Ansicht nach

25:34.880 --> 25:36.000
alles schön konsistent.

25:37.060 --> 25:40.000
Das erklären wir zu einer Art Wiederaufsetzpunkt.

25:40.740 --> 25:45.320
Und diesen Zustand frieren wir jetzt ein, und zwar in Form einer

25:45.320 --> 25:48.520
sogenannten Schatten-Seitentabelle.

25:49.040 --> 25:54.280
Das ist also einfach die Beschreibung der Zuordnung von Seiten zu

25:54.280 --> 25:58.220
logischen Blöcken, zu dem Zeitpunkt, zu dem wir gesagt haben, jetzt

25:58.220 --> 26:00.600
haben wir hier die Konsistenz, das ist eine Art Wiederaufsetzpunkt.

26:01.280 --> 26:04.440
Natürlich müssen wir auch das gleiche dann noch für unseren

26:04.440 --> 26:05.300
Freispeicher tun.

26:05.300 --> 26:08.500
Wir müssen hier sagen, was war zu dem damaligen Zeitpunkt denn an

26:08.500 --> 26:09.880
Blöcken belegt und was war frei.

26:10.620 --> 26:12.900
Also führen wir auch noch eine Schatten-Bit-Tabelle für die

26:12.900 --> 26:13.820
Freispeicherverwaltung.

26:14.780 --> 26:16.000
Und jetzt fangen wir an zu arbeiten.

26:16.860 --> 26:24.220
Jetzt geht es also los, sukzessive ersetzen wir jetzt Seiteninhalte.

26:24.320 --> 26:28.300
Das bedeutet, dass wir sukzessive in Folge dessen auch Blöcke, neue

26:28.300 --> 26:32.900
Blöcke zuweisen und in Folge dessen auch die Seitentabelle

26:32.900 --> 26:34.200
entsprechend anpassen müssen.

26:35.340 --> 26:39.020
Wir führen also eine aktuelle, mit der wir wirklich arbeiten, eine

26:39.020 --> 26:42.000
aktuelle Seitentabelle mit uns.

26:43.440 --> 26:47.280
Und wir müssen natürlich ganz entsprechend auch eine aktuelle Bit

26:47.280 --> 26:48.520
-Tabelle führen.

26:49.340 --> 26:52.880
Da wird natürlich jetzt immer nur zusätzlicher Speicher belegt, denn

26:52.880 --> 26:55.620
wir müssen natürlich den Speicher, den wir für den Schatten haben,

26:55.720 --> 26:57.120
immer auch mit belegen.

26:58.020 --> 27:01.340
Das heißt, wir brauchen so allmählich immer mehr Speicher auf, weil

27:01.340 --> 27:04.500
wir den alten Zustand eingefroren haben und der neue Zustand immer

27:04.500 --> 27:05.440
additiv dazu kommt.

27:11.230 --> 27:13.090
Jetzt können zwei Dinge passieren.

27:14.190 --> 27:17.710
Erste Situation, der ominöse Systemzusammenbruch.

27:18.930 --> 27:22.470
Dann würden wir an dieser Stelle sagen, naja, was zwischendrin ist

27:22.470 --> 27:25.030
passiert, wissen wir nicht so genau, aber was wir auf jeden Fall

27:25.030 --> 27:28.450
wissen, ist der konsistente Zustand, der im Schatten geführt wird.

27:28.450 --> 27:32.570
Dann setzt man einfach auf den Schatten zurück und gibt dann eben die

27:32.570 --> 27:37.650
Seiten, die danach verbraucht worden sind, frei und hat am Ende halt

27:37.650 --> 27:40.730
wieder den alten Zustand des Schattens erreicht und arbeitet erneut

27:40.730 --> 27:41.330
von dem ab.

27:42.370 --> 27:44.650
Hat übrigens nichts mit Transaktionen zu tun, wie wir sehen, sondern

27:44.650 --> 27:47.690
wir wählen irgendwie willkürlich einen Zeitpunkt, das ist ein

27:47.690 --> 27:49.870
Zeitpunkt, an dem wir wieder aufsetzen wollen.

27:50.810 --> 27:54.150
Wenn wir erfolgreich sind und jetzt hinreichend viele Änderungen

27:54.150 --> 27:57.390
durchgeführt haben, dann sagen wir uns, naja, jetzt wird es mir doch

27:57.390 --> 28:00.290
ein bisschen unheimlich, ich will das nicht alles verlieren, was da

28:00.290 --> 28:03.810
zwischendrin geschehen ist, dann nehmen wir einfach den aktuellen

28:03.810 --> 28:07.130
Zustand, frieren den wieder ein, das heißt, machen den zum neuen

28:07.130 --> 28:12.090
Wiederaufsetzpunkt oder Sicherungspunkt und infolgedessen wird jetzt

28:12.090 --> 28:17.610
der alte Schatten entfernt und der aktuelle Zustand wird zum neuen

28:17.610 --> 28:17.950
Schatten.

28:18.750 --> 28:22.010
Und da werden dann hier, wie wir sehen, etwa die Änderungen, die

28:22.010 --> 28:24.910
werden durch so ein Änderungsbit markiert, das sind also hier diese

28:24.910 --> 28:28.170
Änderungsmarkierungen.

28:28.830 --> 28:31.290
Und zwar, wir sehen auch schon, dass da Änderungen erfolgt sind, denn

28:31.290 --> 28:33.190
beispielsweise, wenn wir es mit der alten, mit dem Schatten

28:33.190 --> 28:35.690
vergleichen, dann ist hier aus der 2 eine 4 geworden.

28:36.670 --> 28:38.670
Die 3 ist unverändert, also keine Markierung.

28:39.110 --> 28:43.250
Die J, da haben wir auch inzwischen einen neuen Zustand im Block K.

28:44.150 --> 28:51.050
Und wir haben hier eine neue Seite neu geschaffen, die Seite 5,

28:52.190 --> 28:57.250
beziehungsweise den Block 5, seit der P1N als Seite erstmals gefüllt

28:57.250 --> 28:57.610
wird.

28:57.710 --> 29:01.450
Hier hat es auch eine Änderung gegeben und diese Änderung sind hier

29:01.450 --> 29:04.610
unten auch markiert, in der aktuellen Bit-Tabelle.

29:05.330 --> 29:08.110
Und mit diesen Markierungen sind wir jetzt in der Lage, wenn wir die

29:08.110 --> 29:12.310
inspizieren, gibt es entsprechende Algorithmen, entweder wieder

29:12.310 --> 29:15.390
zurück, den alten Zustand zu rekonstruieren, das heißt also wieder

29:15.390 --> 29:18.970
alles wegzuwerfen, was in der Zwischenzeit geschehen ist, oder den

29:18.970 --> 29:20.710
neuen Zustand herzustellen.

29:20.790 --> 29:24.850
Dann müssen wir nämlich umgekehrt die alten Seiten jetzt entfernen und

29:24.850 --> 29:25.790
freigeben.

29:26.750 --> 29:30.430
Oder die alten Blöcke, genauer, die alten Blöcke freigeben.

29:32.290 --> 29:36.850
Auch da geht wieder folgendes, es gibt einen Algorithmus, der ist auch

29:36.850 --> 29:40.970
nicht besonders kompliziert, für beide Situationen.

29:41.410 --> 29:43.930
Nur, dieser Algorithmus muss natürlich wieder eine Eigenschaft haben.

29:44.230 --> 29:50.670
Nämlich, nehmen wir mal an, während wir dabei sind, wieder auf den

29:50.670 --> 29:56.210
alten Zustand zurückzusetzen, weil wir der Meinung sind, dass wir da

29:56.210 --> 29:59.690
nicht erfolgreich einen neuen, konsistenten Zustand ansteuern können,

30:00.110 --> 30:02.450
und während wir rücksetzen, bricht das System zusammen.

30:04.110 --> 30:08.570
Auch dann gilt wieder, wir müssen den Algorithmus so erweitern, dass

30:08.570 --> 30:12.250
wir in der Lage sind, idempotenz zu erreichen, das heißt, wieder von

30:12.250 --> 30:15.250
vorne anzufangen, wenn das System wieder hochfährt, so als ob wir erst

30:15.250 --> 30:18.910
jetzt mit dem Rücksetzen auf den alten Zustand beginnen.

30:20.510 --> 30:23.930
Wenn wir eine umgekehrte Situation haben, wir sind gerade mittendrin,

30:24.110 --> 30:27.650
den neuen Schatten herzustellen, jetzt bricht das System wieder

30:27.650 --> 30:33.450
zusammen, dann fahren wir wieder hoch, und jetzt ist die Frage, was

30:33.450 --> 30:34.290
müssen wir eigentlich jetzt tun?

30:36.610 --> 30:39.010
Müssen wir jetzt auf den alten Zustand, auf den alten Schatten zurück,

30:39.070 --> 30:41.850
oder wollen wir den neuen vollends konstruieren?

30:43.570 --> 30:44.290
Das ist so die Meinung.

30:46.370 --> 30:47.510
Und wie machen wir das?

30:50.770 --> 30:51.830
Nein, die ist weg.

30:53.410 --> 30:55.730
Die Seitentabelle ist...

30:55.730 --> 30:57.970
Wir sind irgendwo mittendrin,

31:01.470 --> 31:05.130
wir wissen auch nicht genau, wo es abgebrochen ist, wir können ja gar

31:05.130 --> 31:07.590
nicht ständig Buch führen, wir kennen eigentlich den Zustand des

31:07.590 --> 31:10.490
Wiederherstellens, wo das gerade war, kennen wir nicht.

31:12.630 --> 31:15.650
Systemzusammenbruch ist ekelhaft, weil immer alle aktuelle Information

31:15.650 --> 31:17.170
über den Zustand verloren ist.

31:18.390 --> 31:22.250
Wir können persistente Zustände, kommen wir immer ran, das heißt, wir

31:22.250 --> 31:24.910
können immer alles, was wir persistent abgelegt haben, das können wir

31:24.910 --> 31:28.670
verfolgen, aber wir sind nie schnell genug, um auf der nicht flüchtig

31:28.670 --> 31:29.570
speichern zu können.

31:30.330 --> 31:32.650
Wenn das System zusammenbricht, bricht es halt immer zum schlechtesten

31:32.650 --> 31:33.390
Zeitpunkt zusammen.

31:34.910 --> 31:38.410
Also wir haben nicht genügend Informationen, um den Vorgang zu Ende zu

31:38.410 --> 31:40.870
bringen, wir haben wahrscheinlich eine Menge Informationen inzwischen

31:40.870 --> 31:43.310
schon, um zu wissen, dass wir relativ weit gekommen sind, aber wir

31:43.310 --> 31:44.430
wissen nicht, wo wir aktuell sind.

31:45.690 --> 31:48.010
Also bleibt uns auch an dieser Stelle nichts anderes übrig, als

31:48.010 --> 31:48.950
nochmal zurück zu gehen.

31:50.830 --> 31:56.230
Alle Sicherungsmaßnahmen im Datenbankbereich funktionieren immer nur

31:56.230 --> 32:02.250
so, dass man versucht rückwärts zu laufen und den Zustand, von dem man

32:02.250 --> 32:06.410
weiß, dass der konsistent ist, den anzusteuern, bei allen Störungen.

32:07.130 --> 32:09.890
Erst wenn ich mehr über die Anwendungen weiß, also wenn ich

32:09.890 --> 32:13.670
zusätzliche Semantik habe, dann gibt es auch andere Verfahren, die

32:13.670 --> 32:14.570
marschieren nach vorwärts.

32:14.690 --> 32:19.250
Die sagen, naja, ich weiß ja immerhin, wo ich hinwollte und mit

32:19.250 --> 32:22.330
zusätzlicher Kenntnis, wie welche Abläufe zum Beispiel waren, kann man

32:22.330 --> 32:24.950
tatsächlich sogenannte Kompensationsverfahren einsetzen, das heißt,

32:25.010 --> 32:27.490
man setzt ein Stück zurück und läuft dann nach vorne weiter.

32:28.030 --> 32:31.190
Aber wenn ich keinerlei Kenntnis über die Anwendung habe, gibt es nur

32:31.190 --> 32:34.670
eine Rettung und die ist immer zurück auf einen Zustand, von dem ich

32:34.670 --> 32:35.830
weiß, dass er konsistent war.

32:36.630 --> 32:39.990
Also müssen wir in diese Schattenspeicher-Algorithmen jetzt noch so

32:39.990 --> 32:45.450
Idempotenzverfahren einsetzen, die zumindest idempotent bezüglich des

32:45.450 --> 32:46.290
Rücksetzens sind.

32:46.970 --> 32:49.430
Hier sieht man übrigens, was dann am Ende herausgekommen ist, wenn man

32:49.430 --> 32:50.150
erfolgreich war.

32:52.010 --> 32:54.130
So, jetzt schauen wir uns mal den Pufferverwalter etwas genauer an.

32:55.330 --> 32:58.610
Das war jetzt der Segmentverwalter, der eigentlich nichts mit dem

32:58.610 --> 33:01.750
Puffer zu tun hatte, der sagt nur, wo kommen die Dinge auf dem

33:01.750 --> 33:02.630
Hintergrundspeicher hin.

33:02.810 --> 33:08.390
Der verwaltet also rein die Zuordnung der Seiten und Segmente zu den

33:08.390 --> 33:09.090
Dateien bzw.

33:09.210 --> 33:09.930
den logischen Blöcken.

33:10.570 --> 33:13.070
Der Pufferverwalter hingegen ist der Vorratshalter.

33:13.690 --> 33:16.670
Der versucht alles hier im Hauptspeicher zu halten, damit man

33:16.670 --> 33:17.550
möglichst schnell rankommt.

33:22.820 --> 33:28.140
Und jetzt könnten wir folgendes tun, wir könnten für jede Transaktion

33:28.140 --> 33:29.320
einen eigenen Puffer anlegen.

33:30.420 --> 33:34.420
Das wäre dann auch sinnvoll, wenn die Transaktionen alle völlig

33:34.420 --> 33:37.420
isoliert voneinander ablaufen würden, zwar isoliert auch in dem Sinn,

33:37.500 --> 33:40.320
dass sie eigentlich überhaupt nie gemeinsame Daten benötigen.

33:41.260 --> 33:44.940
Bei den meisten Transaktionssystemen ist es aber so, dass es eine

33:44.940 --> 33:49.160
Anzahl von Seiten gibt, die von sehr vielen Transaktionen in Anspruch

33:49.160 --> 33:49.820
genommen werden.

33:50.180 --> 33:53.860
Da wäre es natürlich unsinnig, wir würden für einen Arbeitsbereich für

33:53.860 --> 33:57.760
jede Transaktion vorsehen, sondern da wird ein gemeinsamer großer

33:57.760 --> 34:01.060
Puffer hervorgehalten, der allen Transaktionen zugänglich ist.

34:01.100 --> 34:03.540
Das hat noch einen zweiten Vorteil, manche Transaktionen brauchen

34:03.540 --> 34:05.240
wenig Seiten, andere brauchen viel.

34:05.740 --> 34:10.020
Und in einem gemeinsamen Puffer lässt sich das dynamisch sehr gut

34:10.020 --> 34:10.720
anpassen.

34:15.200 --> 34:18.600
Ein solcher Puffer sieht also folgendermaßen aus, wir haben so eine

34:18.600 --> 34:20.340
Anzahl Pufferrahmen N.

34:21.020 --> 34:23.400
Diese Zahl wird heute so hoch als möglich gewählt.

34:24.140 --> 34:27.420
Meistens sehen wir also heute viele Megabyte für den Puffer vor.

34:28.980 --> 34:35.320
Und wir verlangen als zweites, dass die Rahmen alle identische Größe

34:35.320 --> 34:35.640
haben.

34:35.720 --> 34:39.440
Und das heißt sofort, dass die Seitengrößen identisch sind für alle

34:39.440 --> 34:41.040
Segmente.

34:42.620 --> 34:46.120
Denn nur dann vereinfachen wir uns die Verwaltung, weil wir alle

34:46.120 --> 34:47.480
Pufferrahmen gleicher Größe haben.

34:47.600 --> 34:50.440
Das heißt, jede Seite passt in jeden Pufferrahmen rein.

34:50.560 --> 34:53.800
Wir sind völlig freizügig, wo wir jeweils einlagern.

34:54.500 --> 34:58.660
Dann kriegt natürlich der Puffer noch so ein Pufferkontrollblock mit.

34:59.880 --> 35:05.060
Und der besagt im Wesentlichen, welche Seite sich an welcher Adresse

35:05.060 --> 35:07.880
befindet, ob eine Änderung vorgenommen worden ist.

35:08.240 --> 35:10.360
Das sind so die wesentlichen Aufgaben, die Sie in einem

35:10.360 --> 35:11.700
Pufferkontrollblock mitführen.

35:14.080 --> 35:17.840
Und wenn man jetzt beurteilen will, wie gut ist der Puffer oder auch

35:17.840 --> 35:20.360
welche Pufferstrategie verwendet man.

35:21.560 --> 35:25.540
Vorausschauend heißt ja, wie errate ich vernünftig, welche Seiten als

35:25.540 --> 35:26.700
nächste benötigt werden.

35:27.380 --> 35:31.660
Dann sollte ich das Zugriffsprofil in etwa abschätzen können.

35:32.580 --> 35:35.660
Und dieses Zugriffsprofil beschreibt man in Form sogenannter logischer

35:35.660 --> 35:36.780
Seitenreferenzstrings.

35:36.900 --> 35:41.060
Das heißt, in welcher Abfolge werden denn die Seiten angefordert.

35:43.000 --> 35:45.840
Und dann gilt, man kann das auch übersetzen in physische

35:45.840 --> 35:46.820
Seitenreferenzstrings.

35:48.200 --> 35:51.340
Welche Seiten mussten denn vom Hintergrundspeicher geholt werden.

35:51.780 --> 35:54.640
Und dann lautet halt die Devise, für einen gegebenen logischen

35:54.640 --> 35:58.040
Seitenreferenzstring will ich einen möglichst kurzen physischen

35:58.040 --> 35:59.380
Seitenreferenzstring haben.

36:04.870 --> 36:07.810
So, wie kommunizieren wir nun mit den Pufferverwaltern?

36:07.970 --> 36:10.450
Also, wenn wir was haben wollen, dann ist das Fetch.

36:11.490 --> 36:13.270
Das ist also das Lesen.

36:14.250 --> 36:17.710
Und wenn sich die Seite nicht im Puffer befinden, dann muss sie

36:17.710 --> 36:18.930
erstmal reingeholt werden.

36:19.930 --> 36:23.550
Mark soll bedeuten, dass wir ein Änderungsvermerk setzen.

36:25.330 --> 36:27.210
Flush veranlasst sofortiges Schreiben.

36:27.370 --> 36:30.290
Das heißt, da wird in die Autonomie des Puffers eingegriffen.

36:30.410 --> 36:33.770
Es wird ihm gesagt, mir völlig egal, wann du dir das vorziehen

36:33.770 --> 36:34.990
würdest, die Seite rauszuschreiben.

36:35.050 --> 36:36.110
Du schreibst sie jetzt raus.

36:37.870 --> 36:42.410
Dann haben wir das Pinnen durch das Festnageln und das Anpinnen, das

36:42.410 --> 36:46.230
umgekehrt sagt, jetzt braucht die Seite nicht weiter im Puffer

36:46.230 --> 36:47.090
gehalten zu werden.

36:47.090 --> 36:48.890
Unabhängig von den Sperren.

36:49.690 --> 36:52.950
Und dann sieht man auch deutlich, wenn wir ein Read an den

36:52.950 --> 36:56.450
Segmentverwalter geben, dann übersetzt er das in ein Fetch und holt

36:56.450 --> 36:57.570
die Seite rein.

36:58.370 --> 37:03.450
Und er gibt ein Pin und sagt, jetzt halte diese Seite erstmal fest im

37:03.450 --> 37:03.870
Puffer.

37:04.530 --> 37:09.030
Und Write wird in eine Markierung verwandelt.

37:09.330 --> 37:13.650
Zunächst einmal, also nicht zwingend in ein Flush, sondern heißt nur

37:13.650 --> 37:14.610
Änderungsvermerk.

37:14.610 --> 37:16.730
Jetzt wissen wir, dass die Änderung erfolgt ist.

37:18.270 --> 37:21.030
Und Anfix übersetzen wir in ein Anpin.

37:23.290 --> 37:28.590
Es gibt Varianten, die erheblich mehr Kontrolle durch den

37:28.590 --> 37:31.190
Pufferverwalter zulassen, aber leider etwas aufwändiger sind.

37:31.290 --> 37:34.930
Nämlich man gibt nicht die Hauptspeicheradresse an die Anwendung

37:34.930 --> 37:36.990
zurück, man gibt ja so einen sogenannten Handle.

37:36.990 --> 37:41.390
Ein Handle ist eine irgendwie geartete Struktur, können Sie sich als

37:41.390 --> 37:46.910
einen abstrakten Datentyp vorstellen, der irgendwie intern organisiert

37:46.910 --> 37:49.130
ist und man übergibt immer nur diesen Handle.

37:49.430 --> 37:51.290
Und im Handle steht unter anderem die Adresse drin.

37:52.730 --> 37:55.630
Und da jeder Zugriff nur noch über die Handle erfolgen kann, kann der

37:55.630 --> 37:58.250
Puffverwalter wunderbar verfolgen, was eigentlich die Anwendung jetzt

37:58.250 --> 37:59.390
mit der Seite gerade treibt.

38:00.210 --> 38:05.310
Aber wenn Sie sich erinnern, unser Modell für die Transaktion sah

38:05.310 --> 38:07.550
eigentlich vor, dass der Puffverwalter das gar nicht merkt, sondern

38:07.550 --> 38:09.510
dass er nur mit diesem einfachen Modell arbeitet.

38:12.390 --> 38:16.610
So, jetzt passiert halt folgendes, Fetch, gewünschte Seite im Puffer,

38:16.930 --> 38:18.330
kein Problem, wird fixiert.

38:18.970 --> 38:21.170
Gewünschte Seite nicht im Puffer, dann sprechen wir von einer

38:21.170 --> 38:24.970
sogenannten Fehlseitenbedingung, dann muss ich die reinholen, die

38:24.970 --> 38:25.230
Seite.

38:26.130 --> 38:27.850
Wenn jetzt der Puffer voll ist, habe ich ein Problem.

38:29.210 --> 38:30.290
Passt ja nicht mehr rein.

38:31.670 --> 38:36.510
Also die einzige Möglichkeit ist dann, ich muss durch den Puffer

38:36.510 --> 38:38.270
durchgehen und suche mir ein Opfer aus.

38:38.450 --> 38:39.390
Irgendjemand muss raus.

38:41.570 --> 38:47.090
Nicht raus kann, wer fixiert ist, wo bei dem noch kein Anpin gegeben

38:47.090 --> 38:47.370
ist.

38:47.430 --> 38:48.850
Die Seiten sind tabu.

38:50.730 --> 38:53.230
Von denen wird ja gesagt, von irgendeiner Transaktion, die wird noch

38:53.230 --> 38:53.650
benötigt.

38:54.830 --> 38:58.870
Also kann ich mir nur als Opfer aussuchen, die Seiten, bei denen im

38:58.870 --> 39:00.830
Augenblick kein Pin dran ist.

39:02.510 --> 39:06.430
Und jetzt erhebt sich natürlich die Frage, welche Seite werfe ich

39:06.430 --> 39:06.810
raus.

39:06.970 --> 39:09.730
Und da gibt es natürlich eine ganz einfache Strategie.

39:10.270 --> 39:15.210
Diese Strategie besagt nämlich, wirf die Seite raus, die am längsten

39:15.210 --> 39:16.850
nicht mehr benutzt werden wird.

39:20.140 --> 39:22.340
Sie lächeln etwas, ist das ein Problem?

39:29.700 --> 39:31.840
Sie müssen dazugeben, das Prinzip ist einfach.

39:32.500 --> 39:35.140
Wirf die Seite raus, die am längsten nicht mehr benutzt werden wird.

39:36.460 --> 39:38.500
Ein einziges Problem ist, dass man das normalerweise nicht weiß.

39:39.840 --> 39:40.700
Also muss ich raten.

39:41.600 --> 39:44.220
Raten ist natürlich auch keine besonders gute Strategie.

39:45.480 --> 39:50.040
Wir müssen also entwickeln, was wir eine Ersetzungsstrategie nennen.

39:51.160 --> 39:55.540
Suchstrategie heißt noch, rauszukriegen, ob sich die Seite Puffer

39:55.540 --> 39:56.080
befindet.

39:56.740 --> 40:00.940
Aber Ersetzungsstrategie heißt also, wir müssen eine Strategie

40:00.940 --> 40:06.280
entwickeln, die so aussieht, dass das, was wir tatsächlich tun, so

40:06.280 --> 40:11.520
nahe als möglich diesem Grundsatz kommt, wirf die Seite raus, die am

40:11.520 --> 40:12.940
längsten nicht mehr benötigt wird.

40:13.600 --> 40:14.900
Nun, was steht uns denn zur Verfügung?

40:14.900 --> 40:20.300
Wir müssen ja wahrscheinlich darauf losraten oder Abschätzungen geben.

40:21.600 --> 40:24.600
Da gilt nur die Devise, zur Verfügung steht uns natürlich nur die

40:24.600 --> 40:25.280
Vergangenheit.

40:26.440 --> 40:30.600
Ich versuche also aus der Vergangenheit, aus dieser Historie, welche

40:30.600 --> 40:34.420
Seiten von einer Transaktion in Anspruch genommen worden sind, oder

40:34.420 --> 40:38.460
welche Seiten über den gesamten Transaktionsmix, über eine längere

40:38.460 --> 40:40.300
Periode hinweg beobachtet.

40:42.900 --> 40:48.740
Aus den Aussagen über diese Seiten dann abzuschätzen, welche Seiten in

40:48.740 --> 40:52.600
Zukunft mit großer Wahrscheinlichkeit wieder benötigt werden.

40:53.460 --> 40:57.180
Also, wir nehmen die Vergangenheit und versuchen dann, in die Zukunft

40:57.180 --> 40:58.000
zu projizieren.

40:58.680 --> 41:01.220
Wenn Sie sich das jetzt überlegen, dann muss ich mir überlegen, dann

41:01.220 --> 41:05.100
kann ich nicht sagen, was gibt es denn an Eigenschaften, die ich in

41:05.100 --> 41:08.060
der Vergangenheit herausmessen sollte, aus der Vergangenheit.

41:08.060 --> 41:11.540
Da gibt es halt so Regeln wie, das Alter spielt eine Rolle, die

41:11.540 --> 41:16.380
Häufigkeit, mit der zugegriffen worden ist, spielt eine Rolle.

41:17.880 --> 41:22.580
Jetzt kann ich die entweder mitteln, oder ich kann die jüngste

41:22.580 --> 41:24.180
Vergangenheit stärker gewichten.

41:24.620 --> 41:28.540
Da kann man sich eine relativ große Zahl unterschiedlicher Strategien

41:28.540 --> 41:29.240
vorstellen.

41:30.440 --> 41:33.200
Und infolgedessen, wenn Sie Literatur nachsehen, finden Sie auch eine

41:33.200 --> 41:37.660
Fülle von Vorschlägen, wie eine solche Ersetzungsstrategie aussieht.

41:39.980 --> 41:44.320
Ich führe Ihnen mal eine vor, die ganz einfach zu implementieren ist.

41:45.140 --> 41:47.780
Und die eigentlich gar nicht so schlecht ist.

41:47.960 --> 41:50.060
Sie berücksichtigt das Alter.

41:51.260 --> 41:54.720
Etwas, was sehr lange schon drin ist, vielleicht sollte aus faires

41:54.720 --> 41:57.240
Gründen nicht mehr zu lange im Puffer bleiben.

41:57.760 --> 42:01.300
Und zum Zweiten wird auch irgendwie berücksichtigt, die Häufigkeit,

42:01.420 --> 42:02.600
mit der zugegriffen wird.

42:02.600 --> 42:06.620
Aber wir versuchen eine einfache Strategie, bei der wir nicht allzu

42:06.620 --> 42:08.180
viel an Informationen erfassen müssen.

42:10.840 --> 42:13.080
Das machen wir folgendermaßen.

42:14.280 --> 42:17.700
Ich hatte ja schon gesagt, Alter und Zahl der Referenzen ist das, was

42:17.700 --> 42:19.100
wir irgendwie berücksichtigen müssen.

42:19.200 --> 42:24.740
Wir wollen bei unserem Vorhersagemodell, oder wenn man es statistisch

42:24.740 --> 42:27.940
betrachtet, der Erwartungswert für die Wiederbenutzung minimal ist.

42:28.700 --> 42:34.840
Und ein Verfahren dieser Art ist eine Least Recently Used Strategie.

42:35.000 --> 42:37.500
Das heißt, wir betrachten, wer ist denn am längsten schon nicht mehr

42:37.500 --> 42:39.260
benutzt worden.

42:42.140 --> 42:46.760
Und sagen dann, daraus kann ich auch in gewissem Maße auf die

42:46.760 --> 42:49.940
Häufigkeit zurückschließen.

42:50.620 --> 42:53.880
Aber ich führe noch eine Änderung durch, einen sogenannten Second

42:53.880 --> 42:58.280
Chance Algorithmus führe ich ein, der sogar noch berücksichtigt, zwar

42:58.280 --> 43:03.760
nicht gerade die Häufigkeit, aber doch das erneute Auftreten von einer

43:03.760 --> 43:04.640
Referenzierung.

43:05.360 --> 43:08.180
Und das sieht folgendermaßen aus, den kann man sehen, der heißt auch

43:08.180 --> 43:11.300
nicht nur LRU, sondern gelegentlich läuft er mit dem schönen Namen

43:11.300 --> 43:11.820
CLOCK.

43:14.500 --> 43:16.380
Dann gibt es auch noch verschiedene Modifikationen.

43:16.440 --> 43:19.320
Hier ist die einfachste Fassung und die sieht folgendermaßen aus.

43:19.600 --> 43:22.040
Wir nehmen mal für einen Augenblick an, die Seiten hätten alle keinen

43:22.040 --> 43:22.820
Fixvermerk.

43:24.400 --> 43:28.900
Dann sehen wir, dass wir hier in so einem Eintrag, da steht also

43:28.900 --> 43:36.220
meinetwegen jetzt die Seitennummer, also welche Seite da drin liegt,

43:36.660 --> 43:39.320
und hier haben wir noch ein Markierbit.

43:43.470 --> 43:44.790
Und da sehen wir dann so 1 oder 0.

43:45.330 --> 43:49.370
So, wir stellen uns mal vor, dass im Augenblick diese rote Seite, so

43:49.370 --> 43:50.970
die letzte, die eingelagert worden ist.

43:50.970 --> 43:56.570
Der Uhrzeiger zeigt auf diesen letzten Pufferblock, in dem diese

43:56.570 --> 43:57.530
Einlagung erfolgt.

43:57.690 --> 43:59.790
Jetzt kommt eine neue Anforderung.

44:00.810 --> 44:02.910
Und die neue Anforderung sieht folgendermaßen aus.

44:03.670 --> 44:08.910
Wir lassen den Zeiger loslaufen, bis er auf eine Markierung mit 0

44:08.910 --> 44:10.070
stößt.

44:12.010 --> 44:17.530
Also alles, was mit 1 markiert ist, ist noch so kurz im Puffer, dass

44:17.530 --> 44:18.830
wir es zunächst mal drin lassen.

44:19.550 --> 44:22.870
Dort, wo wir auf eine 0 stoßen, das ist schon hinreichend lang im

44:22.870 --> 44:26.490
Puffer, aber nicht nur das, sondern vor allem ist es auch seitdem es

44:26.490 --> 44:29.290
im Puffer ist, oder seitdem wir das letzte Mal daran vorbeigekommen

44:29.290 --> 44:31.210
sind, nicht mehr angefasst worden.

44:32.670 --> 44:36.730
Infolgedessen steht das auf 0 und das ist der Kandidat für die

44:36.730 --> 44:37.890
Ersetzung.

44:38.870 --> 44:42.170
So, jetzt überstreichen wir an dieser Stelle, wie man deutlich sieht,

44:42.550 --> 44:44.970
aber wir werden ja irgendwo da an dieser Stelle da hinkommen.

44:46.850 --> 44:52.790
Überstreichen wir ja zwei weitere Rahmen, bei denen ist die Markierung

44:52.790 --> 44:53.850
auf 1 gesetzt.

44:54.430 --> 44:56.910
Und da marschieren wir jetzt vorbei und setzen die Markierung auf 0.

44:57.570 --> 45:01.470
Und das bedeutet, wenn ich inzwischen wieder vorbeikomme, angefasst

45:01.470 --> 45:03.450
wirst, dann bist du der Nächste, der rausfliegt.

45:05.890 --> 45:08.770
So, jetzt lassen wir uns also loslaufen, nächste Anforderung.

45:08.770 --> 45:13.630
Und wir sehen also, wir kommen bis hier hin und tatsächlich, hier, das

45:13.630 --> 45:15.450
hat sich inzwischen in 0 verwandelt.

45:17.110 --> 45:21.210
So, jetzt kommen weitere Anforderungen rein und wir sehen schon, die

45:21.210 --> 45:24.170
nächste Anforderung müsste also dann hier sein, an dieser Stelle.

45:24.710 --> 45:27.630
Und während wir überstreichen, muss natürlich diese 1 hier in eine 0

45:27.630 --> 45:28.550
verwandelt werden.

45:29.590 --> 45:32.890
Also sind wir jetzt hier und inzwischen, als wir hier angekommen sind,

45:33.010 --> 45:35.810
stellt sich inzwischen heraus, sind zwei der Seiten inzwischen wieder

45:35.810 --> 45:36.690
angefasst worden.

45:37.570 --> 45:40.650
Infolgedessen ist das wieder in eine 1 verwandelt worden.

45:40.810 --> 45:42.410
So, und jetzt stellen Sie sich vor, wenn wir einen sehr großen

45:42.410 --> 45:46.290
Pufferblock haben, dann läuft halt unser Zeiger da immer rundum über

45:46.290 --> 45:50.030
diesen Puffer und jede Seite, die irgendwann zwischendrin wieder mal

45:50.030 --> 45:53.630
angefasst wird, bevor der Zeiger erneut vorbeikommt, die wird auf 1

45:53.630 --> 45:55.810
gesetzt und kann sich deshalb im Puffer halten.

45:57.410 --> 45:59.750
Das ist ein außerordentlich einfacher Algorithmus.

45:59.890 --> 46:02.610
Das ist eigentlich der Standardalgorithmus, der auch heute in der

46:02.610 --> 46:04.650
Pufferverwaltung Verwendung findet.

46:04.750 --> 46:07.210
Man kann doch etwas modifizieren, wenn man tatsächlich Häufigkeiten

46:07.210 --> 46:10.390
messen will, dann zählt man nicht nur zwischen 0 und 1, sondern zählt

46:10.390 --> 46:11.190
man hoch und runter.

46:12.290 --> 46:15.210
Dann verbleiben also Zeiten, die besonders häufig angefasst werden,

46:15.990 --> 46:19.350
aber gelegentlich mal ruhige Perioden haben, die verbleiben dann auch

46:19.350 --> 46:19.790
im Puffer.

46:20.470 --> 46:24.870
Das sehen Sie also, dass man durchaus, je nachdem, was man alles

46:24.870 --> 46:27.950
einbeziehen will, in der Überlegung halt diese Strategie auch noch

46:27.950 --> 46:28.690
etwas abändert.

46:32.700 --> 46:36.200
Das war so ein ganz einfacher Durchgang durch die Pufferverwaltung.

46:38.020 --> 46:42.220
Man kann sich natürlich die Frage stellen, ob wir nun wirklich alle

46:42.220 --> 46:49.280
Seiten ganz gleich behandeln sollten oder ob sich gewisse Seitenarten

46:49.280 --> 46:55.140
auszeichnen durch ein völlig anderes Verhalten als zum Beispiel reine

46:55.140 --> 46:55.840
Datenseiten.

46:55.960 --> 46:56.560
Da kann man sich überlegen.

46:57.340 --> 47:00.700
Indexseiten verhalten sich häufig anders, insbesondere auch

47:00.700 --> 47:04.360
Verwaltungsseiten wie Seitentabellen oder Bittabellen, die wir vorhin

47:04.360 --> 47:05.260
kennengelernt haben.

47:06.460 --> 47:09.280
Außerdem sind nicht alle Anwendungen von der Bauart, dass die Sätze

47:09.280 --> 47:12.840
nur sehr kurz sind, also nur tuppelorientiert, sondern denken Sie mal

47:12.840 --> 47:20.160
an Bilder oder an Video, die wir ja auch heute auf Hintergrund

47:20.160 --> 47:23.600
speichern oder lange Texte.

47:24.060 --> 47:27.880
Die haben ein völlig andersartiges Verhalten und deshalb hat zum

47:27.880 --> 47:31.760
Beispiel Oracle mehrere Pufferbereiche für unterschiedliche

47:31.760 --> 47:38.420
Seitenarten und bei IBM DB2 kann man sich sogar eigene Pufferbereiche

47:38.420 --> 47:44.620
einrichten, wenn man glaubt, dass das Verhalten von der Typisierung

47:44.620 --> 47:49.360
her ganz anders aussieht, als das von reinen klassischen Datenseiten

47:49.360 --> 47:51.100
bei relationalen Systemen.

47:51.580 --> 47:54.680
Also da gibt es viele Varianten und infolgedessen ist diese

47:54.680 --> 48:00.340
Segmentschicht im Grunde genommen eine hochkomplexe Maschinerie, bei

48:00.340 --> 48:04.980
allen Anbietern eigene gewaltige Systeme und was ich Ihnen halt gebe,

48:05.080 --> 48:07.300
hier so mal einen ganz kleinen Blick hinein.

48:07.900 --> 48:11.100
Dieser Blick wird nun etwas noch verdüstet dadurch, dass wir ja auch

48:11.100 --> 48:12.600
mit unseren Transaktionen zu tun haben.

48:14.200 --> 48:17.520
Und als erstes betrachten wir mal die Atomicität, von der ja gilt,

48:18.680 --> 48:22.540
dass die alles oder nichts Eigenschaft, schafft die Transaktion bis

48:22.540 --> 48:28.340
zum Ende, dann müssen wir den Zustand einfrieren, dann muss er also

48:28.340 --> 48:30.980
persistent gemacht werden und schafft es nicht bis zum Ende, sondern

48:30.980 --> 48:34.220
wird abgebrochen, aus welchen Gründen auch immer, dann müssen wir ihre

48:34.220 --> 48:35.580
Spuren tilgen.

48:36.880 --> 48:44.520
Jetzt ist die Atomicität und die Transaktionen, das funktioniert nicht

48:44.520 --> 48:47.540
mit dem Schattenspeicher, denn der Schattenspeicher oder schlecht.

48:48.660 --> 48:51.380
Wir müssen nämlich dann folgendes machen, für jede Transaktion, die

48:51.380 --> 48:56.920
wir anlegen, müssen wir zu Beginn den Wiederaufsetzpunkt, nämlich den

48:56.920 --> 49:01.680
Schatten herstellen und dann, wenn das Transaktionsende erreicht ist,

49:02.060 --> 49:04.780
müssen wir umschalten und einen neuen Schatten herstellen.

49:04.780 --> 49:07.800
Für eine Transaktion geht das ja auch noch einigermaßen, aber stellen

49:07.800 --> 49:11.100
sie vor, dass sie lauter verzahnte Transaktionen haben, da kriegen wir

49:11.100 --> 49:12.020
das offensichtlich nicht hin.

49:12.800 --> 49:16.240
Also ist der Schattenspeicher für die Transaktionsverwaltung und für

49:16.240 --> 49:20.100
die Atomicität eigentlich denkbar ungeeignet und deshalb wird er nur

49:20.100 --> 49:24.380
als eine Zusatzstrategie, die etwas großflächiger angelegt wird, noch

49:24.380 --> 49:24.920
verwendet.

49:26.000 --> 49:29.660
Jetzt schauen wir uns mal an, wie das hier, wir sind jetzt eigentlich

49:29.660 --> 49:36.380
an dieser Stelle, jetzt kommt unser Recovery-Verwalter ins Spiel und

49:36.380 --> 49:44.760
wir müssen uns also jetzt ansehen, wie funktioniert nun, wie sorgen

49:44.760 --> 49:45.960
wir für die Atomicität.

49:46.780 --> 49:50.860
Jetzt sehen wir schon mal folgendes, der Segment-Verwalter und der

49:50.860 --> 49:52.840
Puffer -Verwalter sind jeweils autonom.

49:55.800 --> 49:59.700
Eigentlich ist nur der Segment-Verwalter, der wirklich mit

49:59.700 --> 50:03.860
Transaktionen zu tun hat, der Puffer-Verwalter, der hat mit

50:03.860 --> 50:05.320
Transaktionen überhaupt nichts zu tun.

50:05.760 --> 50:10.060
Der hat nur eine Aufgabe, seine Aufgabe ist immer, die Seiten, die

50:10.060 --> 50:12.620
benötigt werden, bereits auf Vorrat im Hauptspeicher zu halten.

50:13.080 --> 50:16.660
Dafür haben wir ihn, die Aufgabe hat er übernommen, dafür haben wir

50:16.660 --> 50:19.200
ihn eingerichtet, mit Transaktionen hat er nichts zu tun.

50:20.220 --> 50:22.340
Der Segment-Verwalter hat auch mit Transaktionen zu tun.

50:22.940 --> 50:25.760
Der kriegt Abort und Commit überreicht oder auch das Beginn der

50:25.760 --> 50:29.900
Transaktion und der muss jetzt irgendwie Sorge tragen, dass

50:29.900 --> 50:35.320
tatsächlich, wenn das Commit erfolgt, Persistenz erreicht wird und

50:35.320 --> 50:38.100
wenn es ein Abort gibt, dann muss er dafür Sorge tragen, dass der alte

50:38.100 --> 50:39.140
Zustand wieder hergestellt wird.

50:39.240 --> 50:42.640
Er ist ja auch derjenige, der weiß, wo sich jeweils die Informationen,

50:42.840 --> 50:44.720
die Seiten auf dem Hintergrundspeicher befinden.

50:45.980 --> 50:49.280
Nur leider gibt es da den Puffer-Verwalter dazwischen, der eigentlich

50:49.280 --> 50:50.400
den Transport besorgt.

50:51.000 --> 50:53.720
Und wie gesagt, der schert sich um Transaktionen überhaupt nicht.

50:53.720 --> 50:59.700
Auch eine sehr typische Eigenschaft in großen Systemen, und zwar auch

50:59.700 --> 51:02.420
schon in zentralen Systemen und nicht erst in verteilten Systemen,

51:02.680 --> 51:06.120
dass sie eine Menge Komponenten haben, die eigentlich zunächst einmal

51:06.560 --> 51:10.040
mit einer gewissen Autonomie versehen werden, weil sie ihrer eigenen

51:10.040 --> 51:12.560
Aufgabe so gut als möglich nachkommen müssen.

51:12.900 --> 51:16.040
Also eben die Frage, wie kriegen wir jetzt die beiden hier dazu,

51:16.300 --> 51:17.160
zusammenzuarbeiten.

51:18.720 --> 51:22.640
Im Segment-Verwalter gilt also folgendes, kommt ein Abort rein, da

51:22.640 --> 51:25.100
muss der also hektische Aktivität ergreifen, der muss nämlich den

51:25.100 --> 51:26.140
alten Zustand wiederherstellen.

51:27.060 --> 51:32.260
Und COMIT löst auch hektische Aktivität aus, nämlich er muss den neuen

51:32.260 --> 51:35.640
Zustand festschreiben, aber wir wissen ja schon, wie das geht, lokales

51:35.640 --> 51:40.040
Zwei -Phasen-Festschreiben, da hat man ja schon gesagt, wenn das Abort

51:40.040 --> 51:43.600
oder COMIT einläuft, dann gibt das der Scheduler weiter an den

51:43.600 --> 51:46.520
Datenbasis -Verwalter, sprich jetzt den Segment-Verwalter, und der

51:46.520 --> 51:47.500
soll sich gefälligst darum kümmern.

51:48.600 --> 51:52.920
Der muss also jetzt seine ganzen Aktionen, und dazu braucht er

51:52.920 --> 51:58.960
natürlich den Puffer-Verwalter, die muss er jetzt irgendwie dann in

51:58.960 --> 52:00.720
Abstimmung mit dem Puffer-Verwalter leisten.

52:00.860 --> 52:04.440
Also der Teil, das ist die erste Phase des lokalen Zwei-Phasen

52:04.440 --> 52:08.180
-Festschreibens, da müssen irgendwie Segment-Verwalter und Puffer

52:08.180 --> 52:09.460
-Verwalter zusammenarbeiten.

52:09.880 --> 52:13.700
Re-Start hatte ich schon gesagt, das ist noch die weitere Komponente,

52:13.700 --> 52:18.160
die dann erstmal versucht, erfolgreiche Transaktionen auch wirklich

52:18.160 --> 52:20.680
wieder persistent zu machen und nicht erfolgreiche oder aktive

52:20.680 --> 52:21.840
Transaktionen rauszuwerfen.

52:24.580 --> 52:27.820
So, wir hatten schon gesagt, Speicherkonsistenz der logischen Blöcke

52:27.820 --> 52:29.200
ist ein entscheidendes Kriterium.

52:29.460 --> 52:32.840
Was immer wir jetzt tun, wir müssen davon ausgehen, ist das Ding

52:32.840 --> 52:36.920
draußen, auf dem Hintergrundspeicher ist es tatsächlich konsistent

52:36.920 --> 52:37.580
abgelegt.

52:41.450 --> 52:45.150
So, jetzt könnten wir ja immerhin sagen, der Segment-Verwalter

52:45.150 --> 52:47.990
beschließt sich, das Leben einfach zu machen oder er macht sich das

52:47.990 --> 52:48.970
Leben weniger einfach.

52:51.450 --> 52:56.450
Und dazu muss er also erstmal wissen, wie sich eigentlich unser Puffer

52:56.450 --> 53:03.130
-Verwalter nun verhält, beziehungsweise wie er ihn zwingen kann, dazu

53:03.130 --> 53:04.630
ein gewisses Verhalten zu zeigen.

53:05.970 --> 53:08.670
Jetzt betrachten wir erstmal den Fall, die Transaktion läuft.

53:10.010 --> 53:13.710
Und da laufen halt unsere Read&Write-Anweisungen herein.

53:14.890 --> 53:18.730
Und es gilt ja sicherlich folgendes, der frühestmögliche Zeitpunkt, zu

53:18.730 --> 53:24.450
dem wir überhaupt eine Seite auf den Hintergrundspeicher schreiben

53:24.450 --> 53:28.790
können, ist, wenn ein Unfix oder ein Unpin dem Puffer dann gegeben

53:28.790 --> 53:29.130
ist.

53:29.290 --> 53:31.530
Dann ist ja die Aussage, brauchen wir den Puffer nicht mehr.

53:32.650 --> 53:36.950
Frühestens dann kann also die Seite auf den Hintergrundspeicher

53:36.950 --> 53:37.750
gebracht werden.

53:38.670 --> 53:43.510
Jetzt könnten wir ja folgendes tun, ein Segmentverwalter kann jetzt

53:43.510 --> 53:44.830
eine gewisse Steuerung ausüben.

53:47.150 --> 53:52.670
Und er hat zwei Mittel an der Hand, mit denen er Einfluss ausüben

53:52.670 --> 53:53.010
kann.

53:54.410 --> 53:57.230
Er kann Anpin geben oder nicht.

53:57.630 --> 54:00.530
Wenn er keinen Anpin gibt, dann kann der Puffer-Verwalter beim besten

54:00.530 --> 54:01.690
Willen nichts ausschreiben.

54:02.630 --> 54:05.810
Also hat der Segmentverwalter über Anpin eine Möglichkeit, den Puffer

54:05.810 --> 54:07.530
-Verwalter daran zu hindern, etwas auszuschreiben.

54:08.670 --> 54:09.650
Wenn er kein Anpin gibt, dann ist es passiert.

54:09.770 --> 54:11.030
Von da an hat er die Kontrolle verloren.

54:16.930 --> 54:19.690
Zweitens, er kann, das werden wir noch sehen, außerdem hat er noch

54:19.690 --> 54:21.710
eine zweite Einflussmöglichkeit, das ist Flush.

54:22.270 --> 54:24.450
Flush heißt nämlich, jetzt muss er aber raus.

54:25.510 --> 54:29.190
Ich kann also den Puffer-Verwalter, so zäh oder so widerwurschtig der

54:29.190 --> 54:32.790
auch ist, der will nicht schreiben, aber bei Flush kann ich ihn

54:32.790 --> 54:34.570
zwingen, eine Seite rauszuschreiben.

54:34.570 --> 54:39.470
Das sind die beiden Eingriffsmöglichkeiten, die der Segmentverwalter

54:39.470 --> 54:39.690
hat.

54:39.790 --> 54:45.330
Nun schauen wir mal an, was er denn an Möglichkeiten hat, welche Dinge

54:45.330 --> 54:47.330
er mit Pin oder Anpin betreiben kann.

54:47.410 --> 54:48.530
Hier sehen wir mehrere Möglichkeiten.

54:49.070 --> 54:53.130
Nehmen wir mal an, wir hätten eine Transaktion, die sieht so aus, also

54:53.130 --> 54:59.130
hier ist ihr Commit an dieser Stelle in der Mitte und die Transaktion

54:59.130 --> 55:01.610
kommt mit einem Write und schließlich sagt sie, ich brauche das nicht

55:01.610 --> 55:07.770
mehr, nachdem sie ABC geschrieben hat, kann sie einen Anfix geben und

55:07.770 --> 55:09.210
sagen, die Seite brauche ich nicht mehr.

55:10.490 --> 55:20.430
Jetzt kann natürlich der Segmentverwalter sagen, was die Transaktion

55:20.430 --> 55:25.690
will, aus meiner Sicht interessiert mich das nur an Grenzen, ich

55:25.690 --> 55:28.110
diktiere jetzt, wie der Puffer-Verwalter damit umzugehen hat.

55:28.890 --> 55:32.310
Das heißt, er setzt also mit Write und Mark, klar, das ist jetzt hier

55:32.310 --> 55:34.350
nicht aufgeführt, aber z.B.

55:34.890 --> 55:38.330
hier in dieser Situation gibt er einfach das Anfix übersetzt und Anpin

55:38.330 --> 55:40.110
gibt es sofort an den Puffer-Verwalter weiter.

55:41.470 --> 55:44.970
Von da ab heißt es, Puffer-Verwalter, du bist frei zu tun, was du

55:44.970 --> 55:45.910
willst mit ABC.

55:46.630 --> 55:48.930
Ob nun der Puffer-Verwalter wirklich ausschreibt oder nicht, wissen

55:48.930 --> 55:49.550
wir gar nicht.

55:50.250 --> 55:53.850
Wir wissen aber eins, er kann ausschreiben und wir nennen

55:53.850 --> 55:56.610
infolgedessen das eine Steer-Strategie.

55:57.790 --> 56:04.310
Bei Steer kann also der Transaktion sozusagen, können die Seiten schon

56:04.310 --> 56:07.410
während sie noch läuft, weggenommen werden, gestohlen werden.

56:08.270 --> 56:10.870
Der Puffer-Verwalter stiehlt sie und wirft sie raus auf den

56:10.870 --> 56:11.590
Hintergrundspeicher.

56:12.830 --> 56:16.330
Die andere Strategie, die der Segmentverwalter treiben kann, ist, sagt

56:16.330 --> 56:22.130
er, die Seiten bleiben mal ordentlich drin, da gibt es Anpin erst in

56:22.130 --> 56:23.730
dem Augenblick, in dem das Kommit erfolgt.

56:23.730 --> 56:27.470
Wenn ein Kommit einläuft, dann sagt er, ja, ABC sind ja bis jetzt noch

56:27.470 --> 56:29.730
im Puffer drin, jetzt gehen wir erst mal anpinnen.

56:31.150 --> 56:35.490
So, und frühestens also nachdem das Kommit gegeben worden ist, kann

56:35.490 --> 56:39.770
der Puffer-Verwalter die Seite auf den Hintergrundspeicher verbringen.

56:42.690 --> 56:45.830
So, man sieht übrigens deutlich, wunderbare Strategie, wenn jetzt die

56:45.830 --> 56:50.230
Transaktion zuvor abbrechen sollte, bevor es überhaupt an ihr Kommit

56:50.230 --> 56:52.490
kommt, dann ist überhaupt nichts passiert.

56:52.490 --> 56:56.010
Da sitzen zwar die neuen Seiten im Puffer, aber die sind nie auf den

56:56.010 --> 56:58.290
Hintergrundspeicher geraten, da sitzt doch die alte Information.

56:58.890 --> 57:01.250
Also, wenn wir jetzt wieder einen alten Zustand herstellen wollen,

57:01.350 --> 57:04.650
dieser Transaktion, das heißt am Beginn zurücksetzen wollen, überhaupt

57:04.650 --> 57:05.170
nichts zu tun.

57:05.850 --> 57:07.870
Außer, dass wir die Sperren entfernen, das ist alles, was wir tun

57:07.870 --> 57:08.070
müssen.

57:09.250 --> 57:12.470
Also würde man sagen, ha, dann ist ja diese andere Strategie, die

57:12.470 --> 57:15.530
heißt No-Steal, nichts, der Puffer-Verwalter kann nichts wegnehmen,

57:17.130 --> 57:18.750
die sieht ideal aus.

57:19.450 --> 57:21.850
Allerdings muss ich sagen, hat auch einen Nachteil, nämlich jetzt

57:21.850 --> 57:23.930
hocken diese ganzen Seiten im Puffer drin.

57:40.680 --> 57:41.800
Darf ich Ihnen gratulieren?

57:42.480 --> 57:43.520
Darf ich Ihnen gratulieren?

57:43.700 --> 57:44.560
Herzlichen Glückwunsch!

57:45.080 --> 57:46.100
Physik wahrscheinlich, oder?

57:46.580 --> 57:47.260
Aha, gut.

57:48.420 --> 57:50.220
Also, wissen Sie schon, wo Sie hingehen?

57:51.100 --> 57:52.260
Wissen Sie auch schon, wo Sie hingehen?

57:52.740 --> 57:53.960
Als nächstes, oder bleiben Sie hier?

57:56.760 --> 57:58.260
Okay, gut, also.

58:29.140 --> 58:31.720
Ein erstrebenswertes Ziel, wenn man bis dahin gekommen ist.

58:32.740 --> 58:37.040
Ich weiß nicht, wie viele von Ihnen mal die Promotion vor Augen haben,

58:37.040 --> 58:39.420
aber Sie sehen, so endet das meistens, auch bei uns.

58:44.690 --> 58:48.910
So, also No-Steal ist, ich lasse das drin, Puffer-Verwalter kann

58:48.910 --> 58:53.290
einfach nicht verdrängen, aber dafür sind mehr Seiten belegt.

58:53.870 --> 58:55.610
Die andere Variante ist jetzt mit dem Flasch.

58:55.910 --> 58:57.470
Flasch ist eine zweite Möglichkeit.

58:58.110 --> 59:03.430
Bei Flasch sieht das folgendermaßen aus, solange die Transaktion nicht

59:03.430 --> 59:08.270
abgelaufen ist, wird der Puffer-Verwalter dem bestenfalls

59:08.270 --> 59:10.450
gleichgültig, wann ausgeschrieben wird.

59:13.030 --> 59:17.470
Aber, wenn wir mal annehmen, dass die Seiten A, B, C noch nicht

59:17.470 --> 59:22.350
ausgeschrieben sind, Puffer-Verwalter weiß es nicht, dann gibt es eine

59:22.350 --> 59:23.990
sogenannte No-Force-Strategie.

59:24.110 --> 59:29.350
Die No-Force-Strategie überlässt das Flasch eigentlich der

59:29.350 --> 59:30.610
Transaktion.

59:30.610 --> 59:35.850
Wir können also eigentlich sagen, das ist hier jeweils die

59:35.850 --> 59:38.790
Transaktion, die irgendwann mal dieses Flasch durchführt.

59:40.370 --> 59:41.150
Wir wissen nicht wann.

59:44.850 --> 59:50.070
Oder unser Segment-Verwalter sagt, aber nichts wie raus damit, und

59:50.070 --> 59:52.770
dann wird zum Commit-Zeitpunkt selbst dieses Flasch gegeben.

59:53.950 --> 59:56.750
Jetzt haben wir die andere Seite plötzlich.

59:57.410 --> 01:00:01.550
Wir sagen, bei Commit muss Persistenz erreicht werden, das heißt es

01:00:01.550 --> 01:00:05.550
ist sicher alles auf dem Hintergrundspeicher untergebracht.

01:00:06.190 --> 01:00:10.010
Das ist hier bei der Force-Strategie, wir zwingen die Seiten raus, ist

01:00:10.010 --> 01:00:15.850
das auch gegeben, aber bei No-Force ist das völlig unbekannt.

01:00:15.970 --> 01:00:17.510
Das Segment-Verwalter weiß es nicht mal.

01:00:19.330 --> 01:00:24.490
Also wir sehen, das einzige was wirklich, das kann man jetzt

01:00:24.490 --> 01:00:32.290
kombinieren, das Einzige, das Ideale aus der Sicht des Segment

01:00:32.290 --> 01:00:38.890
-Verwalters wäre diese Situation zum Commit, macht dann ein Unpin und

01:00:38.890 --> 01:00:40.550
ein Flasch.

01:00:41.330 --> 01:00:44.350
Vorher ist nichts rausgegangen und dann zum Commit-Zeitpunkt geht

01:00:44.350 --> 01:00:44.950
alles raus.

01:00:46.470 --> 01:00:53.150
Wenn wir den Segment-Verwalter völlig in Ruhe lassen, dann fährt er

01:00:53.150 --> 01:00:54.050
Steal -No-Force.

01:00:54.830 --> 01:00:55.650
Dann macht er das.

01:00:57.010 --> 01:00:58.470
Wir wissen gar nichts.

01:01:00.450 --> 01:01:02.730
Und irgendwo zwischen diesen Extremen muss man sich bewegen.

01:01:04.030 --> 01:01:07.330
Was glauben Sie, was unsere heutigen Puffer-Verwalter, unsere heutigen

01:01:07.330 --> 01:01:12.230
Segment -Verwalter den Fahren und Strategie, die da oben, No-Steal

01:01:12.230 --> 01:01:17.630
-Force oder Steal-No-Force, um mal beide Extremfälle zu nehmen.

01:01:18.390 --> 01:01:19.650
Was glauben Sie, was die machen heute?

01:01:23.840 --> 01:01:26.680
Die achten natürlich auf Performance.

01:01:26.940 --> 01:01:27.180
Welches?

01:01:28.680 --> 01:01:36.460
Ja, die untere ist zwar etwas unkontrolliert, aber sie richtet sich im

01:01:36.460 --> 01:01:39.940
Wesentlichen nach der Dynamik, die auf der Pufferebene beobachtet

01:01:39.940 --> 01:01:40.240
wird.

01:01:40.660 --> 01:01:43.160
Also eigentlich ist das die Strategie, die gefahren wird.

01:01:44.060 --> 01:01:47.280
Und die bedroht unsere Transaktionen ganz massiv.

01:01:49.620 --> 01:01:55.560
Die Atomicität ist weder beim Abort irgendwie gegeben, noch bei der

01:01:55.560 --> 01:01:57.440
Persistenz beim Commit.

01:01:57.820 --> 01:02:00.480
Also das ist eine höchst bedrohliche Angelegenheit.

01:02:01.200 --> 01:02:06.180
Und jetzt müssen wir uns überlegen, ob die Performance so wichtig ist,

01:02:06.320 --> 01:02:11.920
dass wir zunächst mal bei den Transaktionen dieses eigentlich nicht

01:02:11.920 --> 01:02:13.840
atomare Verhalten tolerieren wollen.

01:02:15.100 --> 01:02:19.320
Und wenn wir sagen, ja, das tolerieren wir, dann ist die nächste

01:02:19.320 --> 01:02:21.800
Aufgabe, wie kriegen wir jetzt Atomicität?

01:02:25.990 --> 01:02:29.170
So, da spielt auch noch ein bisschen die Einbringstrategie eine Rolle.

01:02:30.170 --> 01:02:37.070
Nun stellt sich raus, zu allem Überfluss auch noch, dass nicht nur wir

01:02:37.070 --> 01:02:41.530
der Puffverwaltung allgemein volle Freiheit geben, sondern wir fahren

01:02:41.530 --> 01:02:42.730
auch noch Update in Place.

01:02:45.370 --> 01:02:46.450
Das kommt noch dazu.

01:02:48.410 --> 01:02:51.650
Also wir haben im Grunde genommen jetzt folgendes Problem.

01:02:52.430 --> 01:02:53.730
Update in Place.

01:02:58.210 --> 01:02:59.910
Wir haben No Force.

01:03:01.790 --> 01:03:02.950
Und wir haben Steal.

01:03:03.570 --> 01:03:07.350
Das heißt, wir haben die schlechteste aller Welten uns ausgesucht, nur

01:03:07.350 --> 01:03:08.770
weil wir halt schnell sein wollen.

01:03:12.470 --> 01:03:14.750
So, schauen wir mal das etwas an, wie das aussieht.

01:03:14.750 --> 01:03:18.790
Ich betrachte also jetzt nur diesen letzten Fall, der also der gängige

01:03:18.790 --> 01:03:19.510
heute ist.

01:03:21.470 --> 01:03:28.550
Jetzt gilt folgende Regelung, um jetzt trotzdem Atomicität zu

01:03:28.550 --> 01:03:33.610
erreichen, bleibt natürlich, es gibt keine andere Möglichkeit als den

01:03:33.610 --> 01:03:38.210
alten Zustand aufzubewahren, bis das Komite erfolgt.

01:03:39.530 --> 01:03:42.210
Und erfolgt stattdessen ein Abort, dann müssen wir zum alten Zustand

01:03:42.210 --> 01:03:42.510
zurück.

01:03:43.330 --> 01:03:47.210
Und es bleibt uns auch nichts anderes übrig, als beim Komite selbst

01:03:47.210 --> 01:03:50.590
den neuen Zustand persistent zu machen.

01:03:54.000 --> 01:03:55.300
Also haben wir eigentlich noch gar nichts gewonnen.

01:03:56.060 --> 01:03:59.080
Wir sind doch zur obersten Variante übergegangen.

01:03:59.780 --> 01:04:07.180
Aber wenn wir Folgendes tun, wenn es uns gelingt, die Zustände, die

01:04:07.180 --> 01:04:11.980
wir temporär führen müssen, um den atomaren Zustand zu sichern, also

01:04:11.980 --> 01:04:15.520
wir müssen zum Beispiel noch den alten Zustand führen, solange das

01:04:15.520 --> 01:04:16.560
Komite nicht erfolgt ist.

01:04:16.880 --> 01:04:24.540
Und wir müssen den neuen Zustand führen, auch wenn wir eine

01:04:24.540 --> 01:04:27.180
Forststrategie fahren, wir müssen den neuen Zustand auch irgendwo

01:04:27.180 --> 01:04:27.580
ablegen.

01:04:28.380 --> 01:04:33.820
Wenn es uns gelingt, diese Ablage sehr viel schneller zu machen, als

01:04:33.820 --> 01:04:37.300
die eigentliche Ablage in der Datenbasis, dann haben wir doch was

01:04:37.300 --> 01:04:37.620
gewonnen.

01:04:38.160 --> 01:04:40.860
Also müssen wir uns irgendeinen speziellen Hintergrundspeicher

01:04:40.860 --> 01:04:43.460
schaffen, der sehr schnell ist, für diese Zwecke.

01:04:43.580 --> 01:04:44.940
Der wird dann auch sequenziell beschrieben.

01:04:45.160 --> 01:04:46.900
Das ist also die eigentliche Überlegung dahinter.

01:04:47.040 --> 01:04:51.600
Das heißt, wir bewegen den Kopf, den Lesearm möglichst wenig.

01:04:55.260 --> 01:04:58.600
Dann schreiben wir eine sogenannte Protokolldatei.

01:05:01.200 --> 01:05:04.060
Wir schreiben entweder eine Datenbasis oder eine Protokolldatei.

01:05:04.140 --> 01:05:05.740
Im Wesentlichen schreiben wir erstmal die Protokolldatei und

01:05:05.740 --> 01:05:07.480
überführen dann später die Datenbasis.

01:05:09.260 --> 01:05:11.860
So, jetzt müssen wir folgende Regel beachten.

01:05:12.460 --> 01:05:14.120
Einmal eine Undo-Regel.

01:05:14.900 --> 01:05:24.560
Die Undo-Regel besagt, dass wir, bevor wir einen Wert festschreiben

01:05:24.560 --> 01:05:32.960
auf einem stabilen Speicher, bevor wir einen neuen Wert vor dem Kommit

01:05:32.960 --> 01:05:37.480
überschreiben, muss der alte Wert im stabilen Speicher, in dem Fall in

01:05:37.480 --> 01:05:39.520
der Protokolldatei beispielsweise, gesichert werden.

01:05:40.260 --> 01:05:44.540
Und die Re-Do-Regel sagt, nach dem Kommit, oder besser gesagt, das

01:05:44.540 --> 01:05:48.040
Kommit selbst darf erst abgeschlossen werden, wenn wir all die

01:05:48.040 --> 01:05:51.300
Informationen, die wir für die Wiederholung benötigen, wenn wir die

01:05:51.300 --> 01:05:53.920
zunächst einmal wieder gesichert haben.

01:05:54.160 --> 01:05:56.420
Bei Update, Place und Force heißt das auch wie in einer

01:05:56.420 --> 01:05:58.700
Protokolldatei, sonst eben in der Datenbasis.

01:06:00.340 --> 01:06:03.240
Beim Protokollieren können wir uns jetzt überlegen, die einzige

01:06:03.240 --> 01:06:06.860
Forderung, die wir wirklich haben, ist immer, es muss entweder der

01:06:06.860 --> 01:06:09.400
alte Zustand wiederhergestellt werden können, oder es muss der neue

01:06:09.400 --> 01:06:11.420
Zustand nochmal reproduziert werden können.

01:06:12.840 --> 01:06:16.900
Was wir dafür an Informationen führen, das ist offen.

01:06:17.480 --> 01:06:19.640
Wir stellen nur die Forderung, es muss wiederhergestellt werden

01:06:19.640 --> 01:06:19.920
können.

01:06:21.040 --> 01:06:24.360
Die einfachste ist natürlich, wir nehmen genau den alten Zustand und

01:06:24.360 --> 01:06:27.940
den neuen Zustand, Bit für Bit, und werfen ihn in die Protokolldatei.

01:06:28.500 --> 01:06:31.980
Aber es gibt auch andere Methoden, gelegentlich beispielsweise braucht

01:06:31.980 --> 01:06:33.480
man überhaupt nur den Aufruf.

01:06:35.020 --> 01:06:39.860
Anweisungen zu speichern, weil man dann durch erneutes Wiederholen

01:06:39.860 --> 01:06:43.060
auch nochmal den neuen Zustand herstellen kann.

01:06:43.540 --> 01:06:45.560
Da gibt es wieder verschiedene Protokolle, aber die gängigsten

01:06:45.560 --> 01:06:49.840
Protokolle nehmen einfach den Zustand der Seite, wie sie ist, Bit für

01:06:49.840 --> 01:06:50.080
Bit.

01:06:50.640 --> 01:06:54.400
Man spricht dann beim alten Zustand von einem Before-Image und beim

01:06:54.400 --> 01:06:56.380
neuen Zustand von einem After-Image.

01:07:00.020 --> 01:07:02.060
So, jetzt ist die nächste Frage.

01:07:03.020 --> 01:07:05.240
Wir sind jetzt mitten in unserer Transaktion drin.

01:07:07.980 --> 01:07:10.740
Und was müssen wir jetzt in die Protokolldatei schreiben?

01:07:10.840 --> 01:07:12.760
Die Protokolldatei sieht folgendermaßen aus.

01:07:13.580 --> 01:07:16.440
Es kommt eine neue Transaktion an, mit Begin of Transaction.

01:07:17.500 --> 01:07:25.320
Dann wird unser Segmentverwalter Folgendes veranlassen, dass ein BOT

01:07:25.320 --> 01:07:31.240
-Record in das Protokoll als allererster Eintrag geschrieben wird.

01:07:31.480 --> 01:07:33.820
Der kann zum Beispiel warten, bis die erste Read-Anweisung einläuft

01:07:33.820 --> 01:07:40.600
und dann schreibt er in die Protokolldatei diesen ersten Eintrag, der

01:07:40.600 --> 01:07:43.340
nur besagt, hier beginnt eine neue Transaktion oder hier beginnt die

01:07:43.340 --> 01:07:46.120
Information für eine neue Transaktion.

01:07:47.020 --> 01:07:54.520
So, jetzt wenn verdrängt wird bei Steel, dann wird jedes Mal, wenn

01:07:54.520 --> 01:07:59.740
eine Write-Operation erfolgt, und zwar spätestens in dem Augenblick,

01:08:00.120 --> 01:08:06.660
in dem die neue Seite die alte überschreibt, in der Datenbasis, wird

01:08:06.660 --> 01:08:13.820
ein sogenannter Undo-Eintrag in die Protokolldatei geschrieben.

01:08:15.680 --> 01:08:21.760
Spätestens heißt, irgendwann weiß der Segmentverwalter frühestens,

01:08:22.220 --> 01:08:25.360
wann eine Änderung erfolgt, zum Beispiel wenn die Write-Anweisung

01:08:25.360 --> 01:08:29.780
erfolgt, dann muss spätestens zu diesem Zeitpunkt die Seite

01:08:29.780 --> 01:08:30.500
ausgeschaltet werden.

01:08:30.500 --> 01:08:36.340
Dann muss die alte Seite als Undo-Eintrag in das Protokoll geschrieben

01:08:36.340 --> 01:08:36.680
werden.

01:08:37.240 --> 01:08:40.540
Dummerweise, in dem Augenblick, in dem der rauskriegt, der

01:08:40.540 --> 01:08:44.860
Segmentverwalter, dass eine Write-Anweisung erfolgen soll, ist der

01:08:44.860 --> 01:08:47.420
neue Zustand im Puffer, aber nicht der alte.

01:08:47.760 --> 01:08:49.700
Der ist nämlich schon weg, der ist schon überschrieben.

01:08:50.540 --> 01:08:52.900
Was sofort die Frage aufwirft, wo kriegen wir jetzt eigentlich den

01:08:52.900 --> 01:08:53.760
alten Zustand her?

01:08:54.260 --> 01:08:56.840
Jetzt können Sie sagen, naja, der steht noch in der Datenbasis, dann

01:08:56.840 --> 01:08:59.000
holt man ihn sich nochmal aus der Datenbasis, muss natürlich den

01:08:59.000 --> 01:09:01.480
Puffer durchschleusen, und schreibt ihn dann raus in die

01:09:01.480 --> 01:09:02.340
Protokolldatei.

01:09:03.460 --> 01:09:08.780
Deshalb wäre es eigentlich gut, der Pufferverwalter würde vorher

01:09:08.780 --> 01:09:12.420
rauskriegen, oder zunächst mal der Segmentverwalter würde rauskriegen,

01:09:12.840 --> 01:09:16.700
wann das erste Mal eine Änderung im Puffer versucht wird.

01:09:17.400 --> 01:09:20.040
Und das geht eben nur über einen Handle, das heißt über eine

01:09:20.040 --> 01:09:23.340
Datenstruktur, die der Segmentverwalter selber inspizieren kann.

01:09:23.620 --> 01:09:26.180
Spricht also manches dafür, doch nicht mit der direkten Adresse zu

01:09:26.180 --> 01:09:27.680
arbeiten, sondern mit diesem Handle.

01:09:29.460 --> 01:09:32.860
So, sonst allgemein wird einfach mit dem Lesen gleich ausgeschrieben,

01:09:32.960 --> 01:09:33.620
auf Verdacht hin.

01:09:36.320 --> 01:09:42.040
Auf jeden Fall aber muss die alte Seite, das Before-Image, auf dem

01:09:42.040 --> 01:09:45.600
Protokoll stehen, bevor die neue Seite herausgeschrieben wird in die

01:09:45.600 --> 01:09:47.180
Datenbasis, sonst ist es verloren.

01:09:48.040 --> 01:09:50.040
Also, das nennt man ein Write-Ahead-Log.

01:09:52.300 --> 01:09:59.260
Bei No-Force, beim Commit, jetzt nicht in die Datenbasis geschrieben,

01:09:59.660 --> 01:10:04.240
sondern wir nehmen nur jede veränderte Seite und schreiben sie raus in

01:10:04.240 --> 01:10:05.040
die Protokolldatei.

01:10:05.120 --> 01:10:05.780
Das geht einfach schneller.

01:10:06.780 --> 01:10:09.020
Das erfolgt über einen sogenannten Redo-Eintrag.

01:10:09.760 --> 01:10:12.280
Da steht dann einfach wieder Transaktion, Seitennummer und dann ein

01:10:12.280 --> 01:10:12.960
neuer Zustand.

01:10:14.060 --> 01:10:17.860
Und wenn wir ganz am Ende fertig sind, wenn wir alle Seiten gesichert

01:10:17.860 --> 01:10:22.060
haben, dann schreiben wir nochmal einen Eintrag, und zwar einen

01:10:22.060 --> 01:10:25.180
Eintrag EOT, End of Transaction.

01:10:26.020 --> 01:10:31.080
Und jetzt gilt folgende Regel, eine Transaktion gilt genau dann als

01:10:31.080 --> 01:10:34.480
erfolgreich abgeschlossen, wenn in der Protokolldatei dieser EOT

01:10:34.480 --> 01:10:35.940
-Eintrag steht.

01:10:37.560 --> 01:10:40.760
Und jetzt kann das System zusammenbrechen, Sie brauchen nur noch die

01:10:40.760 --> 01:10:43.820
Protokolldatei abzulaufen, nach Symbol sind nur noch die EOT-Einträge,

01:10:43.960 --> 01:10:47.240
die waren erfolgreich, möglicherweise müssen Sie noch den Zustand

01:10:47.240 --> 01:10:51.280
nachführen, also noch die Redo-Einträge in die Datenbasis verbringen,

01:10:51.680 --> 01:10:55.340
und steht ein EOT-Eintrag nicht da, dann ist eindeutig, die ist nie

01:10:55.340 --> 01:10:58.340
erfolgreich zum Ende gekommen, Transaktion, also wird sie

01:10:58.340 --> 01:10:59.220
rausgeworfen.

01:10:59.320 --> 01:11:03.300
Das heißt, wir fahren dann alle diese Redo- und Undo-Einträge und

01:11:03.300 --> 01:11:05.860
erzeugen den alten Eintrag in der Datenbasis.

01:11:06.360 --> 01:11:07.780
Und jetzt sind wir wirklich auf der sicheren Seite.

01:11:07.780 --> 01:11:11.760
Sie sehen also, das Protokoll ist jetzt eigentlich der Garant dafür,

01:11:12.460 --> 01:11:16.420
dass wir auch bei hoher Performance, die wir eben über Update in

01:11:16.420 --> 01:11:20.440
Place, Steal und No Force erreichen wollen, trotzdem unsere

01:11:20.440 --> 01:11:21.820
Transaktionen sichern können.

01:11:23.500 --> 01:11:26.820
So, wenn natürlich alles normal abläuft und ab Bord gegeben wird, dann

01:11:26.820 --> 01:11:30.480
brauchen wir überhaupt nur das Protokoll kurz abzulaufen und führen

01:11:30.480 --> 01:11:34.880
die Undo-Anweisungen aus, aber wenn das System zusammenbricht, können

01:11:34.880 --> 01:11:38.480
wir das eben auch kontrolliert abführen, dann ist das ganze Protokoll

01:11:38.480 --> 01:11:39.080
abgefahren.

01:11:39.840 --> 01:11:42.320
So, das ist jetzt die einfache Vorstellung, natürlich ist es etwas

01:11:42.320 --> 01:11:45.600
komplizierter, aber wir schauen mal hier an, wir haben so eine Folge

01:11:45.600 --> 01:11:49.360
und vielleicht kann man es erkennen, da soll irgendwas blau werden.

01:11:50.660 --> 01:11:54.600
Nämlich die erste Anweisung, naja man kann es so schwach sehen, W1X,

01:11:55.620 --> 01:11:59.320
die ist jetzt durchgeführt worden und wir sehen, wir schreiben erstmal

01:11:59.320 --> 01:12:03.480
ein BOT und dann schreiben wir auch gleich die Ando-Information rein,

01:12:03.480 --> 01:12:07.500
weil ja Steal möglich ist und in Folge dessen denkbar ist, dass

01:12:07.500 --> 01:12:09.740
demnächst auch ausgeschrieben wird.

01:12:10.540 --> 01:12:13.700
Schreiben wir also ein Ando-Record rein mit dem alten Zustand.

01:12:14.320 --> 01:12:19.500
Dann kommt das W1Y, da kommt ein weiterer Ando-Eintrag, dann kommt das

01:12:19.500 --> 01:12:22.640
U1X, das ist nur das Unfix bzw.

01:12:22.660 --> 01:12:28.880
das Unpin, das ändert nichts weiter dran, dann kommt ein weiteres

01:12:28.880 --> 01:12:32.980
Unfix, interessiert uns auch nicht weiter, dann kommt ein Commit und

01:12:32.980 --> 01:12:35.520
beim Commit schreiben wir jetzt schnell die Redos raus, das heißt die

01:12:35.520 --> 01:12:36.300
neuen Zustände.

01:12:36.940 --> 01:12:39.160
Dann schreiben wir den EOT, wie wir hier sehen.

01:12:39.720 --> 01:12:44.440
Jetzt kommt die Transaktion T2A2, jetzt kriegt auch ihren BOT-Record

01:12:44.440 --> 01:12:50.100
ein Ando, erhält noch ein Ando, dann kommt noch ein Unpin oder Unfix

01:12:50.100 --> 01:12:52.240
und nochmal eins, das ändert nichts mehr dran.

01:12:52.540 --> 01:12:56.860
Das heißt, das steht jetzt in unserer Protokolldatei und Sie sehen

01:12:56.860 --> 01:13:00.340
auch sofort, wenn ich jetzt hier an der Stelle, wenn ein

01:13:00.340 --> 01:13:02.960
Systemzusammenbruch erfolgt, dann marschiere ich jetzt einfach von

01:13:02.960 --> 01:13:07.520
hinten, also von unten herkommt, durch mein Protokoll durch, stelle

01:13:07.520 --> 01:13:10.160
mal gleich fest, hoppla, da ist ja ein Ando und da gibt es gar kein

01:13:10.160 --> 01:13:10.880
EOT dazu.

01:13:12.580 --> 01:13:15.220
Also ist diese Transaktion nicht zum Ende gekommen, also müssen wir

01:13:15.220 --> 01:13:16.080
das Ando durchführen.

01:13:18.660 --> 01:13:24.640
Und dann kommen wir schließlich zu dem BOT, dann führen wir das Redo

01:13:24.640 --> 01:13:34.380
aus, beziehungsweise dann stellen wir erstmal fest, EOT und T1 ist

01:13:34.380 --> 01:13:35.560
erfolgreich abgelaufen.

01:13:36.220 --> 01:13:39.980
Jetzt ist die Frage, wenn wir etwas ausführen, ist das Redo, nicht

01:13:39.980 --> 01:13:40.460
mehr das Ando.

01:13:42.020 --> 01:13:43.540
Führen wir das Redo nur aus oder nicht?

01:13:46.720 --> 01:13:47.920
Ja, aber woher wissen wir denn das?

01:14:03.760 --> 01:14:06.300
Ja, ja, aber dann müsste man den Datenpass gehen, vergleichen, letzten

01:14:06.300 --> 01:14:08.840
Endes Inhalte vergleichen, dann können Sie auch gleich folgendes

01:14:08.840 --> 01:14:10.240
machen, Sie machen blindwürdig das Redo.

01:14:12.720 --> 01:14:14.780
Schlimmstenfalls schreiben Sie dann nochmal den gleichen Inhalt

01:14:14.780 --> 01:14:15.260
nochmal raus.

01:14:16.300 --> 01:14:18.220
Das ist in dem Fall tatsächlich das sichere Verfahren.

01:14:18.320 --> 01:14:22.820
Es geht nur darum, man sollte dann nicht versuchen, aus dem Log die

01:14:22.820 --> 01:14:28.020
Einträge zu löschen, die schon mal per Log-Verwaltung rausgeschrieben

01:14:28.020 --> 01:14:34.000
worden sind, sodass man nicht unnötig nochmal rausschreibt.

01:14:34.120 --> 01:14:37.940
Aber da muss man wieder Aufwand beim Protokoll treiben.

01:14:37.940 --> 01:14:41.240
Also da gibt es, wie Sie sehen, wieder viele Varianten, abgesehen

01:14:41.240 --> 01:14:44.140
davon, dass ich Ihnen nur die einfachste Version überhaupt der

01:14:44.140 --> 01:14:45.720
Protokollverwaltung vorführe.

01:14:46.280 --> 01:14:49.280
Und beispielsweise, um nur die großen Hersteller mal zu nehmen, die

01:14:49.280 --> 01:14:53.180
treiben einen enormen Aufwand allein nur um die Protokollverwaltung

01:14:53.180 --> 01:14:55.560
und die Recovery möglichst schnell zu machen.

01:14:56.580 --> 01:14:58.720
Dann stellen Sie sich mal vor, Sie haben einen Systemabbruch, Sie

01:14:58.720 --> 01:15:01.240
fahren das System, weil Sie ein System haben, das sehr schnell wieder

01:15:01.240 --> 01:15:03.960
hochgefahren wird, kriegen das innerhalb weniger Sekunden wieder hoch,

01:15:04.420 --> 01:15:06.500
dann wollen Sie ja nicht anschließend noch eine halbe Stunde damit

01:15:06.500 --> 01:15:09.000
verbringen, um jetzt erst mal Ihr Log abzuarbeiten, Ihre

01:15:09.000 --> 01:15:11.100
Protokolldatei abzuarbeiten und den Zustand wieder herzustellen.

01:15:11.660 --> 01:15:15.020
Also werden Sie dann auch versuchen, Maßnahmen zu führen, sodass Sie

01:15:15.020 --> 01:15:20.340
ein Minimum, mit einem Minimum an Zeit, den konsistenten Zustand, den

01:15:20.340 --> 01:15:21.880
persistenten Zustand hergestellt haben.

01:15:22.900 --> 01:15:24.860
Aber wenn wir nichts wissen, dann müssen wir halt das Redo

01:15:24.860 --> 01:15:25.360
durchführen.

01:15:26.020 --> 01:15:28.980
So, jetzt gilt natürlich auch noch folgendes, während ich mittendrin

01:15:28.980 --> 01:15:31.760
bin, bricht das System zusammen, erneut, das ist krank.

01:15:33.920 --> 01:15:37.560
Dann müssen wir in der Lage sein, das Ganze nochmal loslaufen zu

01:15:37.560 --> 01:15:40.280
lassen, ohne dass es irgendwie Folgen hat.

01:15:41.100 --> 01:15:43.560
Das sieht jetzt, das werde ich auch noch vorführen, wie das aussieht.

01:15:45.960 --> 01:15:49.020
Zunächst mal sieht man übrigens, dass eine gewisse Redundanz drin ist.

01:15:50.140 --> 01:15:51.840
Wenn wir nochmal zurückgehen.

01:15:55.460 --> 01:16:00.000
Nämlich, wenn wir jetzt zum Beispiel hier das X nehmen, dann sehen wir

01:16:00.000 --> 01:16:03.660
etwa, dass hier das V3 und das V3 doppelt vorkommen.

01:16:03.760 --> 01:16:08.540
Das heißt, sowohl im Redo als auch im nachfolgenden Undo-Eintrag kann

01:16:08.540 --> 01:16:11.560
man auch noch ein bisschen optimieren, wenn man das unbedingt will.

01:16:14.220 --> 01:16:18.640
Wir sehen außerdem natürlich, dass wir im Grundsatz eine Doppelführung

01:16:18.640 --> 01:16:19.800
der Datenbasis haben.

01:16:19.940 --> 01:16:21.780
Nämlich sowohl in der Datenbasis selbst, als auch in der

01:16:21.780 --> 01:16:22.660
Protokolldatei.

01:16:23.020 --> 01:16:25.100
Nur bei der Protokolldatei, da werden wir sehen, dass wir die

01:16:25.100 --> 01:16:27.360
natürlich immer so schnell als möglich kürzen.

01:16:31.240 --> 01:16:35.260
Also jetzt schauen wir mal an, was passiert, wenn wir jetzt unsere

01:16:35.260 --> 01:16:37.400
zwei Phasen festschreiben, nochmal ansehen.

01:16:37.960 --> 01:16:39.820
Der Segmentverwalter kriegt also das Commit.

01:16:40.920 --> 01:16:45.240
Dann ist die Phase 1 jetzt, was man bezeichnet als das Sicherstellen

01:16:45.240 --> 01:16:46.300
der Wiederholbarkeit.

01:16:47.140 --> 01:16:51.940
Er führt für jedes geänderte Datenelement X, für das also ein Write

01:16:51.940 --> 01:16:57.020
gegeben worden ist, ruft er übrigens bei Forced Flush auf und bei No

01:16:57.020 --> 01:16:58.440
Force, da schreibt er eben das Redo.

01:16:59.760 --> 01:17:04.340
Und in dieser Phase, wenn jetzt zum Beispiel, wir können nochmal

01:17:04.340 --> 01:17:04.920
zurückgehen.

01:17:22.120 --> 01:17:25.880
Wenn wir jetzt hier sind und nehmen wir mal an, wir wären genau an

01:17:25.880 --> 01:17:27.020
diese Stelle hier gekommen.

01:17:27.980 --> 01:17:29.100
Und jetzt bricht das System zusammen.

01:17:30.280 --> 01:17:33.460
Dann erkennen wir sofort, kein EOT da.

01:17:34.440 --> 01:17:38.180
Also kann man das Redo ignorieren, wir führen stattdessen das Undo

01:17:38.180 --> 01:17:38.540
aus.

01:17:40.200 --> 01:17:46.260
Sodass wir immer die Existenz der EOT, die sagt, wie wir zu verfahren

01:17:46.260 --> 01:17:46.960
haben.

01:17:49.400 --> 01:17:53.580
Also die Anforderung idempotent zu sein, die schaffen wir auch mit

01:17:53.580 --> 01:17:55.260
dieser Form des Protokolls.

01:17:56.960 --> 01:18:00.240
So, und am Ende wird eben dann das EOT gesetzt.

01:18:03.480 --> 01:18:06.460
Zurücksetzen bei Abort, übrigens wenn es nur Leseanweisungen gibt,

01:18:06.540 --> 01:18:08.280
dann ist es ganz trivial, da brauchen wir gar nichts zu tun.

01:18:09.100 --> 01:18:19.100
Und wenn wir Steal fahren, dann werden wir bei, das ist ein trivialer

01:18:19.100 --> 01:18:20.000
Fall, das lasse ich jetzt mal weg.

01:18:20.560 --> 01:18:25.860
Wenn wir jetzt bei Steal und direkt, also Update in Place fahren, dann

01:18:25.860 --> 01:18:26.720
gilt folgendes.

01:18:27.220 --> 01:18:32.460
Wir haben den Eintrag Undo, wir gelaufen also jetzt rückwärts, finden

01:18:32.460 --> 01:18:34.160
jetzt den Ando Eintrag.

01:18:35.000 --> 01:18:38.740
Jetzt, wir kriegen auch das Ando nur durch den Puffer durch.

01:18:39.780 --> 01:18:43.580
Man darf nicht vergessen, nie gehen wir von der Protokolldatei richtig

01:18:43.580 --> 01:18:48.200
direkt raus auf in die eigentliche Datenbasis, sondern wir gehen immer

01:18:48.200 --> 01:18:49.000
erstmal in den Puffer.

01:18:49.360 --> 01:18:52.840
Und in dem Augenblick, in dem wir beim Wiederherstellen, also beim

01:18:52.840 --> 01:18:56.180
Abarbeiten unserer Protokolldatei in den Puffer gehen, haben wir

01:18:56.180 --> 01:18:59.520
sofort wieder diesen autonomen Puffer, der auf eigene Faust das Ganze

01:18:59.520 --> 01:18:59.980
abwickelt.

01:18:59.980 --> 01:19:03.000
Der sagt also nicht gleich, ich schiebe das durch in die Datenbasis,

01:19:03.920 --> 01:19:07.680
sondern nimmt das zunächst einmal nur den Ando Record in den Puffer

01:19:07.680 --> 01:19:08.020
auf.

01:19:10.620 --> 01:19:20.380
So, dann wird also dieses X einfach auf den neuen Wert gebracht.

01:19:20.700 --> 01:19:26.040
Das heißt, hier lesen wir erstmal den alten Inhalt ein, ändern jetzt

01:19:26.040 --> 01:19:30.800
im Puffer selbst das wieder auf den alten Wert.

01:19:32.640 --> 01:19:39.480
Dann bei No Force wissen wir nicht, ob ausgeschrieben wird vom Puffer

01:19:39.480 --> 01:19:41.200
oder wann ausgeschrieben wird in die Datenbasis.

01:19:42.380 --> 01:19:43.160
Also machen wir einen Trick.

01:19:44.020 --> 01:19:53.140
Wir sagen nämlich jetzt, diese Transaktion, wir betrachten das

01:19:53.140 --> 01:19:57.160
Rücksetzen der Transaktion als ein Fortsetzen der Transaktion.

01:19:59.200 --> 01:20:02.280
Und zwar ein Fortsetzen derart, dass sie den alten Zustand

01:20:02.280 --> 01:20:02.940
wiederherstellt.

01:20:04.260 --> 01:20:09.340
Und infolgedessen mache ich das, was ich jetzt rausschreiben will als

01:20:09.340 --> 01:20:14.860
Veränderter, als alten Zustand, das mache ich zu einem Redo-Eintrag.

01:20:15.040 --> 01:20:19.640
Das heißt, ich sage Redo, schreiben des alten Eintrags und das

01:20:19.640 --> 01:20:20.560
schreibe ich wieder ins Protokoll.

01:20:21.420 --> 01:20:25.020
Und wenn ich jetzt bis zum Ende gekommen bin mit dem Wiederherstellen

01:20:25.020 --> 01:20:28.120
des alten Zustands, dann erkläre ich jetzt plötzlich die Transaktion

01:20:28.120 --> 01:20:28.620
für erfolgreich.

01:20:30.620 --> 01:20:33.940
So, entweder sie geht gut, dann steht der alte Zustand nämlich vor

01:20:33.940 --> 01:20:39.000
dieser Transaktion in der Datenbasis oder es geht hinterher schief,

01:20:39.280 --> 01:20:43.400
bevor der alte Zustand wirklich vom Puffer wieder in die Datenbasis

01:20:43.400 --> 01:20:44.140
geraten ist.

01:20:44.360 --> 01:20:47.160
Dann habe ich aber einen EOT-Eintrag und dann fahre ich durch und

01:20:47.160 --> 01:20:51.280
jetzt benutze ich ja die Redo-Einträge, sodass ich jetzt erneut den

01:20:51.280 --> 01:20:54.560
alten Zustand in die Datenbasis schreibe.

01:20:55.040 --> 01:20:59.840
Sie sehen also, wie man hier sozusagen auf recht elegante Weise eine

01:20:59.840 --> 01:21:01.900
Transaktion, die man abbrechen will,

01:21:05.640 --> 01:21:11.200
verwandelt in eine Transaktion, die man zum Erfolg fortsetzt, aber der

01:21:11.200 --> 01:21:14.080
Erfolg ist definiert als das Schreiben des alten Zustandes.

01:21:14.880 --> 01:21:16.860
Und dann haben wir ganz einheitlich, das können Sie sich vorstellen,

01:21:16.940 --> 01:21:20.460
wenn es jetzt einen Systemabbruch gibt, bevor der EOT-Eintrag

01:21:20.460 --> 01:21:23.220
rausgeht, dann ist ja immer noch der Undo-Eintrag da.

01:21:23.780 --> 01:21:25.540
Dann machen wir es halt erneut, dann versuchen wir wieder

01:21:25.540 --> 01:21:25.900
zurückzusetzen.

01:21:25.900 --> 01:21:30.640
Er war erfolgreich, ist aber noch nicht alles ausgeschrieben, dann

01:21:30.640 --> 01:21:33.540
wiederholen wir die Redos, die auch den alten Zustand rausschreiben.

01:21:34.360 --> 01:21:37.740
Und so machen wir unser Protokoll idempotent.

01:21:37.840 --> 01:21:43.360
Das heißt, wir überleben auch wiederholte Systemabbrüche, die relativ

01:21:43.360 --> 01:21:45.260
rasch aufeinander folgen.

01:21:46.200 --> 01:21:49.520
Und damit will ich Ihnen vorführen, wie kompliziert es eigentlich

01:21:49.520 --> 01:21:53.280
heute ist, wenn Sie Zustände zu verwalten haben, und eine große Zahl

01:21:53.280 --> 01:21:58.820
von Zuständen, wie in der Datenbasis, wie genau Sie Ihre Lösungen

01:21:58.820 --> 01:22:02.240
durchdenken müssen, damit Sie tatsächlich sicher sind, dass in jeder

01:22:02.240 --> 01:22:06.160
denkbaren Situation immer ein konsistenter Zustand erhalten bleibt.

01:22:06.340 --> 01:22:10.020
Denken Sie 100 Jahre Lebensdauer, Sie sind auf Gedeih und Verderb

01:22:10.020 --> 01:22:13.360
angewiesen, dass immer ein konsistenter Zustand garantiert wird.

01:22:14.240 --> 01:22:16.700
So, das sind natürlich relativ langsame Verfahren, also fängt man

01:22:16.700 --> 01:22:19.620
jetzt an, noch ganz komplizierte Verfahren zu entwickeln, wie man z.B.

01:22:19.720 --> 01:22:26.640
stückweise das Protokoll sichert, sodass man bei Wiederanlaufen

01:22:26.640 --> 01:22:30.160
möglichst wenig an Protokoll zu bearbeiten hat.

01:22:32.420 --> 01:22:34.700
So, das kann man jetzt noch kombinieren mit Abort.

01:22:40.160 --> 01:22:45.800
Das ist, wenn Sie sich erinnern, unser Zustand, den wir gerade vorhin

01:22:45.800 --> 01:22:46.340
verlassen haben.

01:22:46.340 --> 01:22:51.180
Jetzt kommt also der ominöse Systemzusammenbruch und wir bearbeiten

01:22:51.180 --> 01:22:52.820
jetzt das Protokoll ab.

01:22:52.960 --> 01:22:54.740
Und zwar arbeiten wir das Protokoll immer ab.

01:22:55.180 --> 01:22:57.820
Undo von rückwärts, redo von vorwärts.

01:23:00.500 --> 01:23:01.620
Das kann man sich auch vorstellen.

01:23:01.800 --> 01:23:04.840
Undo heißt immer, ich marschiere rückwärts, weil ich den ältesten

01:23:04.840 --> 01:23:09.860
Zustand brauche, einer nicht beendeten Transaktion.

01:23:11.660 --> 01:23:15.740
Und redo muss natürlich vorwärts laufen, denn da muss ich die jüngste

01:23:15.740 --> 01:23:16.320
Änderung machen.

01:23:16.980 --> 01:23:21.180
Und die jüngste Änderung steht da nicht ganz am Ende meines

01:23:21.180 --> 01:23:22.760
Protokolls.

01:23:23.020 --> 01:23:24.120
So, fangen wir wieder mal an.

01:23:25.000 --> 01:23:28.520
Das erste, was wir finden bei diesem Ando, holen wir ein Fetch und der

01:23:28.520 --> 01:23:29.420
Protokoll, das Redo.

01:23:30.960 --> 01:23:32.940
Also kommt jetzt das Redo, jetzt steht beides drin.

01:23:34.680 --> 01:23:38.460
Dann stoßen wir auf weites Ando, hat natürlich auch wieder zur Folge

01:23:38.460 --> 01:23:39.340
ein Redo.

01:23:40.960 --> 01:23:43.000
Und jetzt stoßen wir auf das BOT.

01:23:44.420 --> 01:23:46.700
Und jetzt können wir natürlich das EOT da hinschreiben.

01:23:46.900 --> 01:23:49.300
Und jetzt ist das eine erfolgreiche Transaktion gewesen.

01:23:49.440 --> 01:23:53.100
Aber Sie sehen, ob wir Redo oder Ando durchführen, ergibt immer den

01:23:53.100 --> 01:23:55.320
alten Zustand V4 und V3 und V4.

01:23:57.140 --> 01:23:58.820
So, und weiter brauchen wir nichts mehr zu machen.

01:23:59.260 --> 01:24:00.600
So, das will ich mir jetzt schenken.

01:24:06.860 --> 01:24:16.140
Ich werde noch schnell was zur Verbindung zwischen der

01:24:16.140 --> 01:24:23.180
Datenbasistechnik und der Übertragungstechnik sagen, sodass wir uns

01:24:23.180 --> 01:24:25.060
morgen allein mit der Mittelwehr beschäftigen können.

01:24:25.460 --> 01:24:27.200
So, wie komme ich jetzt aus diesem verdammten Ding raus?

01:24:28.400 --> 01:24:28.700
Bitte?

01:24:32.340 --> 01:24:33.720
Nächste Woche, nächste Woche.

01:24:35.560 --> 01:24:38.300
Sie sehen schon, dass bei mir, ich habe ein bisschen viel Vorlesung

01:24:38.300 --> 01:24:42.180
dieses Semester vor relativ vielen Leuten und da setzt so gegen

01:24:42.180 --> 01:24:43.660
Semesterende die Verwirrung ein.

01:24:44.220 --> 01:24:50.340
Wie komme ich aus diesem verdammten Ding da raus, in diesem Zustand?

01:24:52.960 --> 01:24:54.980
Also ich weiß natürlich, wenn ich das Ding hochklappe, wie ich

01:24:54.980 --> 01:24:55.420
rauskomme.

01:24:59.160 --> 01:25:00.240
Oder an dieser Stelle?

01:25:00.240 --> 01:25:02.660
Ach da.

01:25:06.020 --> 01:25:06.620
Ja, wie?

01:25:07.640 --> 01:25:08.320
Jetzt wird es spannend.

01:25:42.080 --> 01:25:45.020
Also ich bin halt immer noch ein Mensch, der mit Tasten arbeitet.

01:25:46.460 --> 01:25:48.900
Oder mit einer Maus, darum zu arbeiten.

01:25:51.440 --> 01:25:55.080
So, das letzte, und da gerade mal auch noch etwas unter Zeitdruck ist,

01:25:55.220 --> 01:25:58.340
wir hatten ja gesagt, am Ende wollen wir mal Folgendes tun, wir

01:25:58.340 --> 01:26:02.980
wollen, dass nicht zwei Vorlesungen, die zufällig in eine Vorlesung

01:26:02.980 --> 01:26:05.880
gepackt sind, erst kommt die Übertragung, Datenübertragung, dann kommt

01:26:05.880 --> 01:26:12.760
die Datenbasistechnik, sondern die beiden gehören heute zusammen, aber

01:26:12.760 --> 01:26:15.540
sie spielen durchaus eine etwas unterschiedliche Rolle, auch wenn man

01:26:15.540 --> 01:26:16.960
sie zusammenführt in verteilten Systemen.

01:26:18.760 --> 01:26:22.080
Und ich werde über Mittelwehr dann nächste Woche sprechen, aber wir

01:26:22.080 --> 01:26:25.220
werden es mal ansehen, also die beiden Dinge, die wir machen wollen,

01:26:25.360 --> 01:26:27.840
ist, wir wollen einmal sehen, wie integriert man, ach, da war ja

01:26:27.840 --> 01:26:30.280
wieder hier das...

01:26:37.510 --> 01:26:38.930
Jetzt werden wir auf eine andere Farbe wechseln.

01:26:41.130 --> 01:26:43.610
Ich werde es noch kurz ansehen, wie kann man sich die Integration

01:26:43.610 --> 01:26:48.310
vorstellen, und dann wird uns ein Kapitel Mittelwehr eben besonders

01:26:48.310 --> 01:26:49.510
beschäftigen.

01:26:50.250 --> 01:26:52.750
So, die Integration, die stellen wir uns einmal folgendermaßen vor.

01:26:52.750 --> 01:26:54.750
Was wir haben, ist...

01:26:57.710 --> 01:27:00.730
eine Funktionalität für unsere Informationssysteme, von denen wir

01:27:00.730 --> 01:27:05.530
gesagt haben, wir wollen insbesondere hier von den Dienstmerkmalen

01:27:05.530 --> 01:27:06.590
etliche zusammenführen.

01:27:06.750 --> 01:27:10.630
Und da hatten wir welche genommen, die passten mehr in die

01:27:10.630 --> 01:27:13.450
Datenübertragungstechnik, zum Beispiel die Allgegenwart und die

01:27:13.450 --> 01:27:16.390
Dauerhaftigkeit ist offensichtlich ein Merkmal, das gehört in die

01:27:16.390 --> 01:27:17.330
Datenbanktechnik.

01:27:18.830 --> 01:27:23.830
Und schauen wir mal an, wir haben ja über beides gesprochen.

01:27:23.990 --> 01:27:26.890
Man sieht also, wenn wir jetzt mal hier die Funktionen gegeneinander

01:27:26.890 --> 01:27:30.030
halten, der Datenübertragung und der Datenverwaltung, dann werden

01:27:30.030 --> 01:27:33.170
manche von beiden aber in unterschiedlicher Weise gehandhabt.

01:27:33.270 --> 01:27:36.350
Zum Beispiel sehen wir deutlich, bei der Funktionalität bewegen wir

01:27:36.350 --> 01:27:38.270
uns auf völlig unterschiedlichen Ebenen.

01:27:39.070 --> 01:27:42.630
Frau Zitterbart, die sieht immer noch Bittströme vor sich, was mir

01:27:42.630 --> 01:27:44.730
überhaupt nichts bringt, was fange ich mit Bittströmen an?

01:27:46.730 --> 01:27:50.210
Wir packen ordentlich in die Datenbanktechnik, wir packen Semantik

01:27:50.210 --> 01:27:52.650
drauf, das heißt, das sind Daten, die wir interpretieren können mit

01:27:52.650 --> 01:27:53.050
einem Schema.

01:27:53.790 --> 01:27:56.170
Also haben wir ein Datenmodell, Strukturen.

01:27:57.830 --> 01:28:00.750
Natürlich, auch Frau Zitterbart hat es schon angedeutet, es gab mal

01:28:00.750 --> 01:28:05.110
ehrgeizige Bestrebungen, im OSI-ISO-Schichtenmodell auf die Ebene 7

01:28:05.110 --> 01:28:07.870
hochzugehen, und plötzlich wollte man auch die Daten interpretieren.

01:28:08.310 --> 01:28:11.010
Inzwischen haben die Übertragungstechniker gesehen, dass sie schon

01:28:11.010 --> 01:28:16.590
genügend Probleme haben, weil es auf der Bittströmebene bleibt, und

01:28:16.590 --> 01:28:19.250
wir dominieren halt, wenn es ums Datenmodell geht.

01:28:19.430 --> 01:28:20.430
Das lassen wir uns auch nicht nehmen.

01:28:22.270 --> 01:28:25.870
Bei der Bedeutungstreue, das war nichts Aufregendes bei Frau

01:28:25.870 --> 01:28:28.630
Zitterbart, die hat halt die Nachrichtenstruktur genommen, aber wir

01:28:28.630 --> 01:28:30.750
schlagen uns, wie man gesehen hat, mit Konsistenz rum.

01:28:30.930 --> 01:28:33.830
Und allen Konsequenzen, die damit verbunden sind.

01:28:34.670 --> 01:28:38.930
Dauerhaftigkeit, kein Thema für die Telematiker, so nur für mich, für

01:28:38.930 --> 01:28:39.230
uns.

01:28:39.910 --> 01:28:41.350
Konnektivität, kein Thema.

01:28:44.730 --> 01:28:47.170
Verhältnismäßigen, kein Thema für die Datenbanktechnik.

01:28:48.530 --> 01:28:52.110
Und mit Allgegenwart beschäftigen wir uns wenig, die wird uns halt

01:28:52.110 --> 01:28:52.650
geliefert.

01:28:53.350 --> 01:28:55.730
Bei der Leistung, da müssen wir zusammenarbeiten.

01:28:55.850 --> 01:28:58.210
Da kommen plötzlich zwei ganz unterschiedliche Facetten ins Spiel.

01:28:58.610 --> 01:29:01.090
Ich hatte ja gesagt, Implementierung, muss ich um Performance kümmern.

01:29:02.410 --> 01:29:05.610
Bei der Telematik ist es vor allem die Übertragungskapazität, und zwar

01:29:05.610 --> 01:29:08.290
die nutzbare, die oben ankommt, und nicht die, die hier unten per

01:29:08.290 --> 01:29:09.390
Bandbreite geliefert wird.

01:29:10.470 --> 01:29:12.810
Bei der Skalierbarkeit haben wir es auch mit unterschiedlichen Dingen

01:29:12.810 --> 01:29:17.690
zu tun, nämlich da ist die Netzausdehnung, soll ja skalieren,

01:29:17.810 --> 01:29:23.530
weltweit, und bei der Datenbanktechnik, da ist es die untheoretische

01:29:23.530 --> 01:29:26.910
Größe der Datenbasen, die ja immer mehr in den Terabyte-Bereich gehen.

01:29:27.470 --> 01:29:30.370
Und bei der Robustheit, da haben wir schon gesehen, bei den

01:29:30.370 --> 01:29:32.590
Protokollen, die ich vorgeführt habe, im Bereich der

01:29:32.590 --> 01:29:35.970
Transaktionsverwaltung, wir verlassen uns drauf, dass da unten alles

01:29:35.970 --> 01:29:39.730
störungssicher ist, oder einigermaßen störungssicher, wir limitieren

01:29:39.730 --> 01:29:45.370
zu ganz bestimmten Arten, und kümmern uns dafür, um die Persistenz und

01:29:45.370 --> 01:29:45.870
Resistenz.

01:29:45.930 --> 01:29:48.630
Jetzt lassen wir mich gerade noch ein paar Minuten, dann sind wir da

01:29:48.630 --> 01:29:48.930
durch.

01:29:51.810 --> 01:29:55.550
Und was wir jetzt betrachten wollen, ist, wie weit wir die

01:29:55.550 --> 01:29:59.870
Eigenschaften, jetzt gehen wir etwas nach oben, wir wollen sozusagen

01:29:59.870 --> 01:30:03.850
Datenbank -Eigenschaften und Telematik-Eigenschaften zusammenführen,

01:30:03.970 --> 01:30:06.870
sinnvoll nach außen weitergeben, wo die Anwendungen liegen.

01:30:07.410 --> 01:30:10.470
Und da braucht man das Datenmodell, Konsistenz, wir liegen also auf

01:30:10.470 --> 01:30:11.570
der höheren Ebene,

01:30:14.730 --> 01:30:17.450
aber was wir in jedem Fall auch haben wollen, ist die Konnektivität,

01:30:17.550 --> 01:30:21.310
wir müssen die Performance auf beiden Seiten leisten, und die

01:30:21.310 --> 01:30:24.330
Skalierbarkeit auf beiden Seiten leisten, und außerdem haben wir hier

01:30:24.330 --> 01:30:25.930
noch etwas Persistenz und Resistenz.

01:30:26.010 --> 01:30:28.890
Und was wir schon sehen ist, dass wir eigentlich von der Datenbank

01:30:28.890 --> 01:30:32.810
-Technik sozusagen etwas mehr an Merkmalen haben wollen, als von der

01:30:32.810 --> 01:30:36.930
Telematik, und das hat halt damit zu tun, dass die Datenbank-Technik

01:30:36.930 --> 01:30:40.190
etwas näher an der Anwendung ist, als die Telematik.

01:30:40.490 --> 01:30:41.670
Aber das wollen wir jetzt kombinieren.

01:30:44.730 --> 01:30:46.510
Wenn ich mir Schichten ansehe, wir hatten ja in beiden Fällen eine

01:30:46.510 --> 01:30:48.990
Schichtenarchitektur, dann kann ich die einfach so orthogonal

01:30:48.990 --> 01:30:53.170
gegeneinander legen, denn sie sind ja zunächst mal unabhängig

01:30:53.170 --> 01:30:57.050
entstanden, und es gibt nur irgendwo einen Punkt, da müssen die beiden

01:30:57.050 --> 01:30:57.770
zusammenkommen.

01:30:58.730 --> 01:31:01.830
Da gibt es also einen Berührungspunkt, jede für sich wird unabhängig

01:31:01.830 --> 01:31:07.230
betrachtet, aber wir führen sie zusammen, und hier sehen wir sogar

01:31:07.230 --> 01:31:10.830
noch ein bisschen mehr, hier ist noch etwas verteilt, hier ist also

01:31:10.830 --> 01:31:15.710
einmal irgendwo ein Klient, also auf der anderen Seite unser

01:31:15.710 --> 01:31:23.150
Datenbanksystem, beide haben jeweils ihre Protokolltürme, und uns geht

01:31:23.150 --> 01:31:26.990
jetzt darum, wie können wir eine Verbindung auf dieser Ebene

01:31:26.990 --> 01:31:34.950
herstellen, so dass sowohl die Eigenschaften des Datenbanksystems als

01:31:34.950 --> 01:31:41.550
auch die Eigenschaften der Datenübertragung verdeckt bleiben, aber in

01:31:41.550 --> 01:31:45.810
einer sinnvollen Kombination als Merkmale und als Funktionalität zur

01:31:45.810 --> 01:31:46.530
Verfügung stehen.

01:31:47.930 --> 01:31:53.230
Und um das nun auch noch homogen hinzukriegen, das soll transparent

01:31:53.230 --> 01:31:58.010
bleiben, aber wir wollen auf irgendeiner höheren Ebene die

01:31:58.010 --> 01:32:02.090
Datenübertragung regeln, ohne auf die Funktionalität dieser einzelnen

01:32:02.090 --> 01:32:07.550
Komponenten abzuheben, und das, was wir jetzt hier einführen wollen,

01:32:07.890 --> 01:32:11.470
was also diese Verbindung sorgt, und trotzdem für die Transparenz nach

01:32:11.470 --> 01:32:14.870
beiden Richtungen sorgt, das bezeichnen wir jetzt als Mittelwehr.

01:32:15.750 --> 01:32:20.210
Die wird also reingeschoben, und so ist die Vermittlung zwischen, die

01:32:20.210 --> 01:32:24.370
soll also sowohl die Daten, die Allgegenwarte, also die ganzen

01:32:24.370 --> 01:32:26.870
Eigenschaften, die wir brauchen aus der Telematik, wie die

01:32:26.870 --> 01:32:32.410
Eigenschaften aus der Datenbanktechnik, aber auch aus anderen

01:32:32.410 --> 01:32:36.190
Anwendungen liefern, und das in einer Weise, so dass man also

01:32:36.190 --> 01:32:38.790
transparent davon Gebrauch machen kann.

01:32:42.690 --> 01:32:44.230
Wir werden auch noch verlangen, das können wir uns jetzt auch

01:32:44.230 --> 01:32:52.830
schenken, wir werden auch noch verlangen, dass diese Eigenschaften

01:32:52.830 --> 01:32:54.110
transparent sind.

01:32:54.210 --> 01:32:57.230
Wenn wir also jetzt die Vier-Stufen-Architektur nehmen, dann sehen wir

01:32:57.230 --> 01:32:58.790
sozusagen jetzt nur noch die Mittelwehr.

01:33:00.890 --> 01:33:07.230
Das heißt, wir wollen, die Eigenschaften der Telematik und die

01:33:07.230 --> 01:33:11.330
Eigenschaften der Datenhaltung, soweit sie eine Infrastruktur für alle

01:33:11.330 --> 01:33:14.710
darstellt, die wollen sich verbergen hinter dieser Mittelwehr.

01:33:14.870 --> 01:33:17.530
Das heißt, das ist selber auch eine komplexe Struktur.

01:33:18.530 --> 01:33:22.730
Und was wir dann nächste Woche besprechen werden, ist, wie kriegen wir

01:33:22.730 --> 01:33:25.750
jetzt bei dieser Vier-Stufen-Architektur, wenn wir die unterstellen,

01:33:26.370 --> 01:33:28.470
wie sehen die Eigenschaften der Mittelwehr aus?

01:33:28.650 --> 01:33:32.130
Was wollen wir denn eigentlich an Eigenschaften haben, so dass wir

01:33:32.130 --> 01:33:36.090
bequem diese Struktur oben drauf packen können, Klienten für sich

01:33:36.090 --> 01:33:39.690
programmieren können, Präsentationen, also Webserver für sich

01:33:39.690 --> 01:33:44.210
programmieren können, die eine Geschäftslogik enthalten, für sich

01:33:44.210 --> 01:33:45.190
programmieren können.

01:33:45.470 --> 01:33:50.250
Hier unten außerdem auch die Datenbanksysteme, wenn wir wollen, eigens

01:33:50.250 --> 01:33:52.710
nochmal als Dienstleister ins Spiel bringen.

01:33:53.670 --> 01:33:58.450
Zulassen, dass die alle heterogen sind, das heißt, vollautonom ihre

01:33:58.450 --> 01:34:01.470
eigenen Schnittstellen vorgeben, in eigener Programmiersprachenarbeit,

01:34:01.590 --> 01:34:04.910
möglicherweise sogar auf eigenen Betriebssystemen aufsetzen, verteilt

01:34:04.910 --> 01:34:05.270
sind.

01:34:06.570 --> 01:34:08.390
Und dann wollen wir eine Umgebung schaffen,

01:34:12.690 --> 01:34:14.790
die ganz einheitlich auf einem relativ hohen Abstraktionsniveau

01:34:15.550 --> 01:34:20.270
unterhalten kann, über Datenübertragung, über Aufrufe der

01:34:20.270 --> 01:34:24.030
verschiedenen Dienstgeber, über Datenhaltung, wenn sie Teil der

01:34:24.030 --> 01:34:28.130
Infrastruktur sein soll, über Transaktionssicherung, wenn wir auf

01:34:28.130 --> 01:34:30.390
dieser Ebene Robustheit erzielen wollen.

01:34:31.330 --> 01:34:34.150
Das ist ein ordentliches Thema, ein relativ modernes Thema, die

01:34:34.150 --> 01:34:38.110
Mittelwehr gibt es noch gar nicht so lange, und wir werden alle Mühe

01:34:38.110 --> 01:34:40.670
haben, das nächste Wochen noch wenigstens einigermaßen zum Ende zu

01:34:40.670 --> 01:34:40.870
bringen.

01:34:42.690 --> 01:34:43.790
Und das wollen wir diese Woche entlassen.

01:34:45.890 --> 01:34:47.410
Es sind aber Übergänge übrigens, nicht?

