[linux-l] Re: [linux-l] Transaktionen? und Prozessesnapshots für alle und jeden und überall und jederzeit

Steffen Dettmer steffen at dett.de
Mi Aug 20 11:04:23 CEST 2003


* Jan Krueger wrote on Wed, Aug 20, 2003 at 08:30 +0200:
> On Wednesday 20 August 2003 01:58, Steffen Dettmer wrote:
> > > > Natürlich auch wieder doof,
> > > > weil nicht mehr alle Daten mit der Umwelt konsistent sein müssen
> > > > (hat man bei DBs natürlich auch, aber sieht das oft besser).
> > >
> > Schon ein kooperatives suspend-to-disk ist nicht so ganz einfach.
> 
> Also fasse man voneinander abhängige Prozesse zusammen 

Ja, plus Umwelt :)

> Der Prozeß ist für sein error-handling selbst verantwortlich.
> 
> dann ist der mensch für das errorhandling selbst verantwortlich und muß sich 
> entsprechend zurechtfinden. Das ist nun mal so wenn man snapshottet.

Wie soll man das programmieren? Nimm mal an, Du hast sowas wie

while(...) {
	accept(fd...)
	syslog(LOG_AUTHPRIV, "connection from ...")
	if ( send (fd, ...) == -1 ) {
		syslog(LOG_ERR, "send failed");
		exit (1);
	}
}

oder sowas. Geht nicht per snapshot, weil dann exit 1 gemacht
wird. Wie also den Fehler behandeln? Ich mein, es kann dann sein,
das nach einem memcpy die (im Code "eben" geholten) Daten falsch
sind! 

> Das OS könnte dann höchstens die Hilfe geben, ein signal, hallo
> prozeß du warst gesnapshottet. 

Dann muß man da ein flag setzen. Was macht man dann?
Sicherheitshalber (weil Zustand ja nicht bekannt) geht man am
besten raus, bis zurück an den Anfang auf Applikationslevel,
initialisiert alles neu, damit man sich drauf verlassen kann.

Geht auch ganz gut per exit :-)

> Also, wenn man ein Programm schreibt für ein OS, von welchem
> man weiß, daß es Prozesse einschläfern kann, 

einschläfern ist ja auch weniger das Problem, denk ich. Bloß mit
Folgefehlern (beispielsweise merkwürdigen Socketverhalten, was
normalerweise schlicht und ergreifend mit exit quitiert wird)
klarzukommen, ist vielleicht schon schwieriger...

> dann kann man auch ein entsprechendes Error-Handling dafür
> installieren, besonders wenn man ein signal bekommt: du hast
> schlafen müssen, überprüfe dich und deine Umgebung.

Stell Dir das doch mal im Code vor. Im Prinzip muß doch nach jeder
Zeile (man kann ja immer snapshoten):

if (global.flag.snapshotrestored) {
	/* alle Daten checken */
}

Ach so, da entstehen auch viele Zeilen, da muß man natürlich auch
checken :)

> So ginge es doch.

Ja, aber bleibt schwierig. Einen Prozeß einfach zu starten ist
hingegen recht einfach.

> Ähm, das Signal hat einer in weiser Vorraussicht ja schon eingebaut:
> SIGCONT   19,18,25            Continue if stopped

:-)

> snapshotted und wieder geladen ist halt dann eine
> Interpretation von stopped.

Ja, klar, könnte man machen. Fragt sich eben nur, ob das viel
Sinn macht. So ähnlich funktionierte ja so ein Perl compiler:
einfach memory dumpen (gut, sind paar MB, aber schnell ist's),
beim Start dann laden. 

> [...]
> 
> Langsam ist nicht egal.

Warum nicht? Wenn der Prozeß "hängt", und man ein paar Stunden
später einen gdb einhängt, ist doch egal, ob der 5 oder 30
Sekunden braucht? Außerdem ist der gdb nicht langsam, denke ich.
Wenn Du was ohne debugsymbole hast, ist er verdammt fix. Gut,
möchte man nicht, also muß er eben paar MB symbole laden etc.

[hängende Signalhandler]
> > Na ja, siehe eben oben! 
> Na, ohne sleep!?

häh? Dann nimmste eben select. sleep paßt aber: man möchte ja
Prozeß bleiben, aber keine Rechenzeit verbrauchen. Dieser
Prozeßstatus heißt sleep :) Paßt doch, oder?

> > Yep, geht mir genauso. Das ist das schöne an Unix: man denkt
> > lange drüber nach und kommt auf gleiche Ideen. Bei Windows
> > ist das eher anders. Dann fragt man sich eher, warum man
> > ausgerechnet *das* nicht auch noch abscheiben konnte und
> > installiert sich ein cygwin ;)
> 
> Und während der windows-Admin-Kollege sein VisualStudio started
> hat man das bash-script mit vi schon fertig geschrieben 

... und den gdb am Start :-) SNCR ...

> > > Wegen der besonderen Eigenheiten von flash-speicher welche bei
> > > direct IO nicht berücksichtigt werden.
> >
> > Woher weißt, was meine Applikation da macht?
> 
> Dös wois i net. Ich wüßte es, wenn sie kein DirectIO macht -> read() und 
> write(). 

Ja, in beiden Fällen, oder?!

// system buffered I/O
int sysfd = open("/tmp/file", 0);
write(sysfd, "some data", 10);
close(sysfd);

// raw I/O
int rawfd = open("/dev/raw/0", 0);
write(rawfd, "some data", 10); // dauert...
close(rawfd);

Ist doch genauso, nur das open ist anders, oder?

> Dies würde mir ein Gefühl der Sicherheit geben, ich könnte auf
> die Anwendung und deren IO Unix-Einfluß nehmen :) 

Geht immer, man kill :-) 

Nee, klar, wenn die ANwendung Spezialverhalten hat, muß sie ggf.
ne Configoption zum Abshclaten haben. Sprich: optionales rawIO,
hat Oracle ja auch :)

> Wenn ich mir die embedded Linux-Entwicklungen so anschaue (zb.
> eben JFFS oder JFFS2) dann nutz man auch weitestmöglich
> abstraktionen weil man sich ja damit nicht auseinandersetzen
> will, sondern man will eine anwendung schreiben.

Ja, sicherlich, ich würde auch lieber C++ schreiben, aber da ist
nun mal weniger Speicher, da kann man oft nicht "schön" arbeiten. 

SomeElement *
Utility::searchRecursive(SomeList list, SomeElement element)
{
	if (list.isEmpty()) {
		return NULL;
	}
	if (list[0] == element) {
		return list[0];
	}
	return searchRecursive(list.slice(1, list.size()), element);
}

ist bei embedded (gut, bei PCs oft auch :-)) absolut tötlich:
jeder call benötigt liste-1*element (plus Verwaltungsdaten) auf
dem Stack. Geht einfach nicht.

Wenn Du nur noch 300 byte frei hast, paßt da ein jffs sicherlich
schlecht rein ;) Und  8KB mehr speicher (bzw. dann 1MB ;))
kosten bei *jedem* Gerät, also haben die den zusätzlichen Chip
erstmal nicht.

> > Er formuliert sie auf 99.9% von 24/7 um. Bleibt über eine Minute
> > am Tag. Verfügbarkeiten von 99.9% sind meist ausreichend,
> > zumindestens für das, was ich mache, in jedem Fall.
> 
> Ja, klar. Auch bei dem was ich mache.

Yo.

> > ? Nee... Wenn jemand eine Datei liest, schreibt und nach 3
> > Stunden nochmal einen Block davon neu schreibt (also einen
> > exklusiven Lock hat), kann logischerweise 3 Stunden niemand
> > anders die Datei lesen, weil er ja nicht wissen kann, ob der
> > erste geschriebene Block commitet wird oder nicht. Man könnte
> > natürlich noch "views" dazunehmen, daß der andere dann die Daten
> > sieht, die es mal waren. Wird natürlich auch wieder teuer, weil
> > man dann alle View-Daten speichern muß (was natürlich jede
> > Datenbank  - außer vielleicht mySQL und "kleine" - kann, wo wir
> > wieder beim Thema wären ;)). Wenn beide schreiben wollen, muß auf
> > jeden Fall sequentialisiert werden, einer kann ja nur.
> 
> Eben. Diese beiden verhalten sich wie ein einziger. und der
> kann immer, weil er ja der einzige ist, halt intern doppelt.

? Jedenfalls muß der andere eben 3 Stunden einfach nur warten...

> Ok, es gibt augenscheinlich sehr komplizierte Transaktionen
> spätestens dann, wenn mehr und mehr externe Systeme eingebunden
> werden. 

Na ja, immer, wenn man auf komplexen Datenstrukturen einfach
arbeiten möchte. Da reichen schon vier Tabellen.

> Doch wenn das so kompliziert und damit schwer beherrschbar
> wird, ist vielleicht das gewählte Modell "Transaktion" das
> falsche und man hätte etwas besser geeignetes wählen sollen.

Nein, ich denke eher, wenn die Thematik so komplex ist, gibt es
eben keine noch einfachere Lösung.

> > Physiker würden sagen: "der Zustandsvektor ist superpositiv
> > und kollabiert bei commit". 
> 
> Des Bundeskanzlingers Katze :)

Genau! BTW, wie geht's ihr eigentlich?? Hab noch nicht
nachgeguckt, vielleicht stirbt sie ja dabei ;)

> > Wenn's superpositiv ist, bis zu nicht-abzählbar-unendlich viele,
> > würde ich mal raten, aber kenn ja Dein Atom nicht persönlich ;)
> 
> mein Gigabyte-Atom hat 2^(Anzahl bits) zustände ;)

Dann ist es eben nicht super-positiv :)

> + diejenigen zustände, die zutreffen wenn man gerade nicht hinschaut.
> 
> also insgesamt 3^(Anzahl bits) 
> wobei ich eben unterstelle, daß es nur diese 3 Zustände (0, 1, beides 
> gleichzeitig) gibt.

Yo, eben. Kann aber auch sein, daß es zu 25% 0 und zu 75% 1 ist.
Die Wahrscheinlichkeiten sind dann oft wieder beliebig, und damit
unendlich viele Zustände in der Superposition, und 
unendlich^(Anzahl bits) ist recht groß :)

> Das zeigt wie unvollkommen Computer heutzutage sind, weil sie
> nur 2 Zustände berücksichtigen.

Also doch Quantencomputer :)

> Ok, wir machen keine halben Sachen und verarbeiten Gigabyteatome am Stück:
> putDataWithEnourmusSpeed( /path/to/bla, data)

Meistens hast Du ja nur 100 byte zu schreiben. Außerdem wolltest
Du doch gerade keine Blöcke mehr? So muß ja jeweils ein GB
gelockt werden! Ist ja noch teurer :)

> > Versteh ich nicht. Wieso merkt die Hardware überhaupt was von
> > directIO?! Hier wird ja eben ein read oder write Kommando
> Schon, nur halt nicht das read() und nicht das write() welches man sich mit
>  man read
> oder
>  man write
> anschauen kann, weil diese eben nicht direct sind 

Weißt Du doch nicht. Kann sein, daß Du in ne Datei, ne FIFO,
einen Socket schreibst, aber auch auf ein Terminal (/dev/tty
geöffnet) oder ein Gerät (/dev/sg0) - oder eben directIO
(/dev/raw/0). Sind alles nur Files :-)

> Und genau diese implementieren wir in Hardware.

Dann merkt die Hardware trozdem nicht, wer das aufruft :)

oki,

Steffen

-- 
Dieses Schreiben wurde maschinell erstellt,
es trägt daher weder Unterschrift noch Siegel.




Mehr Informationen über die Mailingliste linux-l