[Allegro] update.job + optsget.inc überarbeitet

Thomas Berger ThB at Gymel.com
Mo Jan 16 12:18:36 CET 2012


Lieber Herr Eversberg,

>> Fazit: Ohne Wissen um die *vorgeschriebene* (= von allen Anwendungen
>> einzuhaltene und auch eingehaltene) Reihenfolge bei der Erlangung von
>> Satz- und Datenbanklocks gibt es keine wirkliche Sicherheit.
> 
> Sie meinen, der Anwender kann sich ohne dieses Wissen nicht sicher
> *fühlen.*
> Das Wissen oder Nichtwissen ist es hier nicht, was Sicherheit *schafft*,
> sondern ob die Prozeduren stimmig sind. Aber das ist spitzfindig.

Nein, ich meine nicht den Anwender, sondern den Job-Programmierer:
Sobald mehr als ein Lock in der Anwendung vorkommt, hier also
Datenbank- plus Datensatz-Lock, kann es zu Deadlocks kommen, und wenn
es keine Spielregeln gibt (Reihenfolge, Ruecknahme zwecks Konflikt-loesung),
wird es dazu kommen.


>>  und anschliessendem
>> "set tbl lock" nur im Fall einer zugeschalteten Parameterdatei,
> Was täte denn diese dabei zur Sache?

Die koennte - wg. eigener Indexzugriffe als Grundlage der
vorzunehmenden Manipulationen - Wert darauf legen, dass der Index
sich vor dem Speichern nicht noch einmal aendert (Zaehler,
Zustand von v14-Ersetzungsschluesseln, ...).


>> ansonsten einfachem "put" (mit implizitem "set rec fre") der
>> Ressourcenschonendste Weg, auch wenn dafuer mehrfach in der .cLD-
>> Datei herumgeschrieben wird.
> 
> Beim "put" wird stets, wenn es denn zugelassen wird, das erste
> Byte mit 1 überschrieben, und das ist die Freigabe.
> 
> Aber insgesamt haben wir erkannt, daß eigentlich im  update.job
> weniger Aufwand getrieben werden muß mit dem Locking, als wir dachten.
> Dazu folgendes:
> 
> Wie Sie hervorgehoben haben, ist es unbefriedigend, daß man
> nur mittels  "set lock"  ein sicheres Schreiben vorbereiten kann,
> und wenn man dies vergißt, die veränderten Schlüssel nicht
> korrigiert werden.
> Das muß geändert werden. Wir spalten den Vorgang ab: Jedes Laden
> eines Satzes ermittelt sofort die zugehörigen Schlüssel, ob nun
> hernach ein Speichern erfolgt oder nicht. Das kostet keine Server-
> leistung und keine extra Zugriffe, denn das kann acon alleine.

Die Schluesselermittlung des "vorher"-Zustands ist strenggenommen
nur unmittelbar im Zusammenhang des Speicherns zulaessig, denn
zwischen Einlesen des Satzes und Speichern koennte man zwar durch
eine Datensatzssperre gewaehrleisten, dass sich der Satz nicht
mehr aendert, die Schluessel (auch die existierenden) haengen
aber vom Gesamtzustand des Index ab (v14-Ersetzungen, explizit
in der .api vorgenommene Nachladungen)


> Der Job sollte direkt vor dem Speichern prüfen, ob gerade eine
> Sperre besteht. Wenn ja, ist es unentscheidbar, wie lange diese
> bestehen wird. Nur eine (einstellbare?) Anzahl Sekunden sollte
> abgewartet werden, dann der Fall protokolliert und zum nächsten
> Satz übergegangen.

Es ist noch nicht einmal entscheidbar, ob man selbst gerade eine
lange oder viele kurze Sperren beobachtet: Angenommen, Sie sehen
einen Monat lang jeden Morgen auf dem Weg zur Arbeit vor der Baeckerei
einen Lieferwagen im Parkverbot stehen: Das sollte Sie nicht
zu dem Schluss verleiten, dass der da rund um die Uhr steht
und langsam vor sich hinrottet.


> Um die Sperre von .tbl und Satz zu den kritischen Zeiten kümmert
> seit je sich der Vorgang hinter "put" selber, wobei die .tbl nur
> dann kritisch ist, wenn es um die interne Nummernvergabe geht.
> Diese Sache kommt also wieder raus aus update.job.

.tbl steht auch stellvertretend fuer exklusiven Schreibzugriff
auf Index, Tabellen und auch Logdatei.


> Eine Satzsperre wird sodann im Job nicht gesetzt! Denn:
> "put" vergleicht vor dem Speichern das Änderungsdatum, und dies
> ist der entscheidende Punkt für die Schreibsicherheit:
> Ist dieses nicht mehr identisch mit demjenigen zum Zeitpunkt des
> Einlesens im Job, wird das Speichern verweigert. Im Job kann dies
> bemerkt werden und der Satz daraufhin in die Protokolldatei
> geschrieben, die man daher tunlichst am Ende auf solche Fälle hin
> betrachtet. Dies aus der Überlegung heraus, daß man sicher *nicht*
> ganz allgemein entscheiden kann, ob ein während des update-Vorgangs
> genau zu der Zeit anderweitig geänderter Satz überschrieben
> werden soll oder nicht! acon wird dann also wie a99 verfahren, nur
> daß es keine Konsolmeldung gibt mit Abwarten, was der Operator
> entscheidet - genau das geht ja nicht - sondern eben Protokollieren
> des Sachverhalts. Wir denken, das ist dann der akzeptable Weg,
> der einerseits wenig internen Overhead und wenig Sperrzeit verursacht,
> andererseits in gewiß nur sehr seltenen Fällen ein Nachbearbeiten
> von Sätzen notwendig macht. (Wir hatten im update.job gedacht, diese
> Fälle noch reduzieren zu können, aber solches Bemühen ist sehr
> wahrscheinlich wenig fruchtbar.)

1. umso wichtiger wird es, die Heuristik vom Zeitstempel zu loesen
(die Sekunden-Aufloesung ist viel zu grob, und es besteht die
Gefahr, dass hochfrequente Aenderungen *uebersehen* werden koennen)
und auf eine kryptographische Pruefsumme umzustellen (irgendein
Standardverfahren auf die String-Darstellung des Satzes wie eingelesen
anwenden, und die zugehoerigen 64 oder 128 Bytes irgendwo hinterlegen)

2. Das Update einer groesseren Datei sollte sich nicht von einem
fluechtigen Phaenomen wie einer fast-simultanen Bearbeitung aus der
Bahn werfen lassen, jeder "ignorierte" Datensatz bleibt potentiell
unbemekrt bzw. ist extrem muehsam zu ermitteln und wiedervorzulegen.
Zudem wird das Speichern wird auch verweigert, wenn eine (fremde)
Satzsperre besteht, das abzuwarten koennte sich lohnen.

In update.job sollte daher Ablauflogik implementiert werden,
die beim Scheitern des "put" (bzw. qualifiziert auf die Gruende
des Scheiterns reagierend) auf Grundlage des bereits eingelesenen
Update-Satzes die Schritte ab Primaerschluesselberechnung, Ermittlung
des Zielsatzes in der Datenbank etc. in einer gewissen Anzahl
oder Zeitdauer erneut versucht.


> (Übrigens führt acon keine Liste der während des Jobs gesperrten
> Sätze, um diese am Ende wieder freizugeben, falls noch nicht
> geschehen.)

aber warum hiess es dann, man koenne keine sitzungsuebergreifenden
Datensatzsperren "mit avanti" realisieren, oder erinnere ich mich
da ganz falsch?



> Zu überlegen ist auch noch, ob die nicht gespeicherten Sätze besser
> in einer eigenen Datei gespeichert werden sollten, und zwar im
> Externformat, damit man diese Datei dann evtl. unmittelbar für
> das weitere Procedere der Nachbearbeitung heranziehen kann, etwa
> zum Kopieren der Sätze direkt nach a99 oder so.

das waere in der Tat hilfreich, im Zusammenhang mit den Ueberlegungen
fuer -R.

Wir haben unter acon ja drei Kanaele zur Verfugung:

UPRO bzw. die ueber -x benannte Protokolldatei, deren Vollstaendigkeit
ueber -R steuerbar ist.

STDOUT  (Ausgabemenge in Anwendungen typischerweise ueber -v (Verbose) geregelt)

STDERR


Die Ausgaben sind dabei normalerweise nicht ganz disjunkt, bloss weil
etwas so wichtig ist, dass es in einer Ausgabedatei festgehalten wird,
bedeutet das nicht, dass die Angabe auf STDOUT oder STDERR verzichtbar
waere, im Gegenteil. Zu berueckichtigen ist auch, dass in kontrollierten
Kontexten STDOUT gerne in eine anwendungsbezogene Protokolldatei
umgeleitet wird, nicht alles, was theoretisch fuer irgendjemanden
von Interesse sein kann, muss zwingend nach UPRO.

viele Gruesse
Thomas Berger







Mehr Informationen über die Mailingliste Allegro