[Allegro] o-invent.flx

Thomas Berger ThB at Gymel.com
Mo Feb 9 09:55:58 CET 2009


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Lieber Herr Eversberg,

>> Datenbanken koennen im Allegemeinen gut zaehlen, und sie werden
>> dann eingefuehrt, wenn die Verwaltung von Einzeldateien nicht
>> mehr praktikabel ist.
> Dieser überaus grundsätzliche Einwand verblaßt bei der hier
> in Rede stehenden Sache aber gänzlich neben dem pragmatisch-
> praktisch-robusten Appeal der Lösung mit der Mini-Zählerdatei.
> Die Vorgänge, um die es geht, kommen ja nicht alle paar
> Zehntelsekunden vor! Für sowas soll man keine ins Undurchschaubare
> abdriftenden Perfektionismen anstreben.

Lassen Sie uns doch einmal einen Moment grundsaetzlich bleiben:

Greifen mehrere Prozesse auf gemeinsame Ressourcen zu, dabei
mindestens einer tendenziell schreibend, so muessen diese
Prozesse (z.B. ueber die von ihnen genutzten Datenbank-API's)
sich abstimmen, letztendlich wird dabei stets die Unterstuetzung
des Betriebssystems benoetigt (etwa ueber Semaphore, Shared Memory
oder - hier interessant - Locking-Features des Dateisystems).

Normalerweise ist das Paradigma dabei: Mehrere Leser / ein Schreiber,
wobei das " / " als ausschliessliches oder zu verstehen ist: Waehrend
der Schreiber schreibt, darf kein Leser lesen. Taete er es dennoch,
muesste er mit Crashes rechnen, weil die Konsistenz der Datenbank
zu diesem Zeitpunkt nicht gewaehrleistet werden kann.

allegro hat da einen anderen Ansatz, maximal ein Schreiber ist
gleichzeitig erlaubt, Leser duerfen immer lesen. Die daraus
resultierenden Probleme (schliesslich ist keine der von allegro
genutzten Systemkomponenten auf diesen Ansatz eingerichtet) sind
bekannt, das interessiert diesmal aber nicht.

Die dieser Synchronisation unterliegenden Objekte sind einerseits
"die Datenbank" repraesentiert durch ein Flag ein einem bestimmten
Bereich der .TBL-Datei, und andererseits jeder einzelne Datensatz
(repraesentiert durch ein beim Datensatz gespeichertes Statusbyte
in den .cLD-Dateien). Dazu gibt es noch die .sgf-Datei, die aber
nur den Start der Module verhindert, und moeglicherweise noch
ein feiner granuliertes Locking, das von der den Index realisierenden
Tree-API genutzt wird.

Der "bestimmte Bereich in der .TBL-Datei" und das "Statusbyte in den
.cLD-Dateien" sind dabei auch Objekte im Dateisystem und hier wird
mit Unterstuetzung des Betriebssytems darauf geachtet, dass diese
zuverlaessig gelesen und geschrieben werden: Zumindest bei der
Datenbank-Sperre wird zunaechst ein exclusives Lock vom Betriebssystem
angefordert, dann der existierende Wert zuverlaessig ausgelesen
und ggfls. modifiziert, abschliessend das Betriebssytem-Lock freigeben
und die anderen allegro-Module akzeptieren die Semantik des
Betriebbsystems, kalkulieren also ein, dass wegen evtl. existierender
Locks auch das Lesen des Bereichs nicht moeglich ist, was hier dann
kein "Augen zu und durch" erlaubt. Betreffend der Sperre einzelner
Datensaetze waere es wirklich interessant zu wissen, ob allegro hier
aehnliche Mechanismen nutzt.

Beim Speichern eines Datensatzes ist die a) Log-Datei, b) ein oder zwei
(beim Umspeichern) .cLD-Dateien, ggfls. die .TBL-Datei (wiederum
beim Umspeichern) und an c) unklar vielen Stellen die Indexdatei
betroffen, sowohl lesend (fuer das Auswerten von v14-Ersetzungen und
Nachladungen und bei der Berechnung des "vorher"- und des
"nachher"-Stands der Ausfuehrung der Indexparameter) als auch schreibend
beim Austragen entfallener und Eintragen neuer Schluessel oder beim
Verschieben ganzer Indexbereiche aufgrund veraenderter
- ->Pseudoschluessel.

Separate Locks fuer a), b) und c) koennten Speichervorgaenge effizienter
machen, zu beachten sind allerdings auch die Programmierte Validierung,
und die Identnummernvergabe, die im Zusammenhang mit dem Speichern den
Datensatz noch einmal veraendern koennen, insofern muss also schon vor
a) exklusiver Schreibzugriff auf den Index bestehen (damit niemand
anderer ihn bekommt). Ausserdem wird beim Umspeichern der Index
konsultiert. Sperren "der Datenbank" mag also etwas uebertrieben
anmuten, benoetigt wird aber ueber weite Strecken parallel die Sperre
"des Index", die Auswirkungen (wartende Parallelprozesse) sind damit
dieselben. Die Anzahl der Schreibvorgaenge in den Index haengt vom
Datensatz und den Parametern ab, die Anzahl der Lesevorgaenge ebenfalls,
das ist durch "allegro" wenig beeinflussbar, einzig die
Leersatzverwaltung koennte (und sollte) optimiert werden, es gibt aber
den Schalter -N0 um deren stoerende Einfluesse auszuschliessen.

Lage der Dateien und die Existenz weiterer auf die Dateien zugreifenden
Prozesse haben einen drastischen (jeweils ca. Faktor 5) Effekt auf den
Zeitbedarf beim Speichern, hier schlaegt sich wohl nieder, dass das
Betriebssystem "Schreiben" dann doch als wesentlich exklusiveren
Betriebsmodus versteht als das laxe allegro.

Alles in allem muss man stets darauf achten, die Zeiten mit gesperrter
Datenbank zu minimieren:

1. Datensaetze nicht oefter zu speichern als noetig (das betrifft
  /nicht/ die menschlichen Bearbeiter, sondern Flexe). Letztendlich
  aendern sich zwar in etwa genau so viele Schluessel, die u.U.
  nennenswert vielen lesenden Indexzugriffe bei gesperrter Datenbank
  finden dann aber haeufiger statt. Ausserdem ist ja bereits das
  Erlangen des Locks eine zeitaufwendige Operation.

  Fuer aus dem Index abgeleitete Zaehler (Identnummer, Zugangsnummern,
  Bestellnummern, ...) ist die praktische Konsequenz, dass diese erst
  beim Abspeichern des jeweiligen Datensatzes generiert werden sollten
  (das wird man ja nicht los, und Nummernvergabe kann da en passant
  erledigt werden). Inwieweit das praktikabel ist (weil etwa Bearbeiter
  erwarten, bereits beim /Anstossen/ der Funktion "Nachinventarisierung"
  die relevante Zugangsnummer gezeigt zu bekommen), weiss ich nicht.

2. Nach Loesungen zu suchen, die (zumindest in Teilen) nicht die
  gesamte Datenbank sperren muessen: Wenn ich etwa Zaehler in
  Generatorsaetzen habe (die ihren Inhalt typischerweise nicht in den
  Index setzen) *und* eine effiziente und saubere Methode, gezielt
  den Generatorsatz zu sperren, dann kann ich recht gemaechlich den
  Zaehler manipulieren und mir das Ergebnis merken, das eigentliche
  Rueckspeichern des Generatorsatzes erfordert zwar dann wieder die
  Sperre der gesamten Datenbank, ist aber wenig belastend
  (Umspeicherungen, zu lesende Schluessel und v.a. veraenderte
  Indexeintraege koennen ausgeschlossen werden, d.h. es erfolgt trotz
  Datenbanksperre keine Beeintraechtigung lesender Prozesse)


3. Loesungen vermeiden, die die Datenbank sperren um datenbankfremde
  Operationen (wie etwa externe Zaehlerdateien, deren Manipulationen
  landen auch nicht in der Logdatei der Datenbank, nicht zuletzt daher
  koennen sie einfach nicht empfohlen werden!) durchzufuehren, Ausnahme:
  Backups der Datenbank.

4. Loesungen suchen fuer Faelle, wo die Datenbank eigentlich gesperrt
  werden muesste, es aber nicht wird: Etwa Kontingentberechnnungen des
  neuen Order: Hier erfolgt eine Selektion vieler Datensaetze zwecks
  Summenberechnung, also eine wegen der Menge der zu lesenden Saetze
  eher zeitaufwendige Operation, die m.E. ziemlich empflindlich auch
  zwischenzeitlich erfolgende Schreibzugriffe in der Datenbank
  reagieren kann.


>> Die Auslagerung auch der Datensaetze in
>> Einzelfiles hatten Sie allerdings schon vor Jahren fuer eine
>> der naechsten Versionen angekuendigt.
>>
> Richtig, aber Onkel Bill ist mit der dafür nötigen Version
> (Codename "Rattlesnake") noch nicht übergekommen.
> 
>> Bei allegro ist es allerdings tatsaechlich so, dass das Locking
>> in der Datenbank tatsaechlich teurer ist als das im Dateisystem,
> Relativ! Interessant wären hier erst einmal reale, absolute Meßwerte.
> 
>> insofern ergibt sich die paradoxe Situation, dass die Arbeit
>> umso effizienter wird, je weniger man allegro einsetzt.
>>
> Hier fehlt ein klärendes  ;-)  (Auf das ich freilich ebenfalls
> in aller Regel - allzuoft? - verzichte.)

Nein, das ";-)" fehlte allenfalls weiter oben :-(

viele Gruesse
Thomas Berger

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3-nr1 (Windows XP)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iQCVAwUBSY/vnWITJZieluOzAQI8OwP+KAhGRUODw9moQ6sM70FlOpCt7PcIT1Jq
rBmxiVXVtHIgMPPcLDOpUz3FRAnuAZAD1fSLrqtc1zwoaOoUJrmfGB07hdr8sLZO
Exqj2DiJRz+07Z9tbnf55jWolhk6Jp+ShvMgvldKLfdcNKgzmXbWcKSnBVmocy3u
K6IHpfFlDxE=
=igCP
-----END PGP SIGNATURE-----



Mehr Informationen über die Mailingliste Allegro