buforowanie w windows

0

Czy jest możliwy następujący scenariusz podczas pracy w sieci (dwa komputery):

  1. klient czyta dane z pliku na serwerze (znaczy na zdalnym dysku), modyfikuje coś tam i zapisuje z powrotem, zamyka plik.
  2. po pewnym czasie (dowolnym - może nawet natychmiast) klient otwiera znowu ten sam plik, czyta to samo, i uzyskuje starą wersję danych, czyli nie ma tego co sam zapisał poprzednio, ponieważ system czyta z lokalnych buforów, których nie zaktualizował jeszcze po ostatnim zapisie.

Zakładamy że w tym czasie nikt inny nie zapisuje do tego pliku.

Pytam o takie dziwne rzeczy, ponieważ niedawno jeden gościu sugerował, że jemu zdarza się coś takiego w pracy!

Tu coś wspominają o kontroli buforowania, ale to chyba nie ma w tym przypadku znaczenia:
http://support.microsoft.com/kb/99794

Spotkał się ktoś z czym takim?
Jeśli tak, to jak tego uniknąć?

1

To zależy od file systemu pod jakim jest zamontowany zdalny dysk a także od konfiguracji Windowsa. Przykładowo Lan Manager Windowsa używa Opportunistic Locking aby zapobiegać tego typu sytuacjom, ale można ten mechanizm wyłączyć w rejestrze.

ponieważ system czyta z lokalnych buforów, których nie zaktualizował jeszcze po ostatnim zapisie

Jakby czytał z lokalnych buforów to miałby zaktualizowaną wersję, problem pojawia się gdy czyta z pliku, który jeszcze nie został zaktualizowany (bo np. dane znajdują się w lokalnych buforach, albo jeszcze nie doszly na serwer).

1
0x200x20 napisał(a):

To zależy od file systemu pod jakim jest zamontowany zdalny dysk a także od konfiguracji Windowsa. Przykładowo Lan Manager Windowsa używa Opportunistic Locking aby zapobiegać tego typu sytuacjom, ale można ten mechanizm wyłączyć w rejestrze.

ponieważ system czyta z lokalnych buforów, których nie zaktualizował jeszcze po ostatnim zapisie

Jakby czytał z lokalnych buforów to miałby zaktualizowaną wersję, problem pojawia się gdy czyta z pliku, który jeszcze nie został zaktualizowany (bo np. dane znajdują się w lokalnych buforach, albo jeszcze nie doszly na serwer).

Zgoda, ale tu mówimy o uproszczonej sytuacji: tylko jeden klient zapisuje, ale do zdalnego dysku.

Chyba jest niemożliwe żeby system popełniał aż tak naiwne błędy.
Przecież tu niezależnie od buforowanie nie można się pomylić.

System musiałby pracować jak ślepy idiota:

  • klient zapisuje, i niech to idzie do lokalnego bufora, a dopiero potem na zdalny dysk (zapisuje tylko co jakiś czas, nie od razu)
  • klient czyta to co dopiero zapisał, a system nie sprawdza buforów, lecz bierze ze zdalnego, a tam są dane przeterminowane, ponieważ on sam jeszcze tego nie zaktualizował - w ogóle nie przesłał z buforów.
1
  • klient zapisuje, i niech to idzie do lokalnego bufora, a dopiero potem na zdalny dysk (zapisuje tylko co jakiś czas, nie od razu)
  • klient czyta to co dopiero zapisał, a system nie sprawdza buforów, lecz bierze ze zdalnego, a tam są dane przeterminowane, ponieważ on sam jeszcze tego nie zaktualizował - w ogóle nie przesłał z buforów.

Sprawdzanie lokalnych buforów rozwiązywało by problem i tak tylko w przypadku gdy klienci są na jednej maszynie. W przypadku wielu maszyn potrzebny jest protokół, który zapewnia spójność cacheów.
Generalnie jak nie masz napisane w dokumentacji czy file system zapewnia spójność cacheów na lokalnej maszynie to nie możesz zakładać, że to robi.

0
0x200x20 napisał(a):

Sprawdzanie lokalnych buforów rozwiązywało by problem i tak tylko w przypadku gdy klienci są na jednej maszynie. W przypadku wielu maszyn potrzebny jest protokół, który zapewnia spójność cacheów.
Generalnie jak nie masz napisane w dokumentacji czy file system zapewnia spójność cacheów na lokalnej maszynie to nie możesz zakładać, że to robi.

Chyba dowolny system operacyjny powinien gwarantować zgodność w takim prostym przypadku.

A może chodzi o to, że operacje odczytu i zapisu były wykonywane bez jakiegokolwiek blokowania - LockFile,
a wtedy system przyjmuje robi co chce - zakłada że klient nie wymaga jakiejkolwiek synchronizacji?

Nie, takie coś byłoby niepoważne.
Rozumiem gdyby tu inny zapisywał, ale z jednym musi być spełniony elementarny warunek: to co ostatnio zostało zapisane, będzie potem odczytywane.

1

Rozumiem gdyby tu inny zapisywał, ale z jednym musi być spełniony elementarny warunek: to co ostatnio zostało zapisane, będzie potem odczytywane.

Zakładasz globalne pojęcie czasu, które w systemach rozproszonych po prostu nie istnieje. Jeżeli ostatnio do pliku dokonała zapisu inna maszyna to tak na prawdę odczytując lokalne bufory dostajesz dane, które jeszcze nie istnieją i które są przestarzałe co może być nieporządaną sytuacją. Jeżeli chcesz upewnić się, że dane zostały sflushowane możesz wywołać FlushFileBuffers przed CloseHandle (same CloseHandle nie robi flusha).
Poza tym jak mówiłem - chcesz mieć takie gwarancje - używasz filesystemu, który ma zdokumentowane synchronizacje cacheów (czyli np samba + opportunistic locking).

1

Patrząc z odpowiedniej strony atutem jest buforowanie i brak synchronizacji - lepsza wydajność, nie zamula ci komputera. Nie odpowiada? Użyj czegoś innego.

0
0x200x20 napisał(a):

Zakładasz globalne pojęcie czasu, które w systemach rozproszonych po prostu nie istnieje. Jeżeli ostatnio do pliku dokonała zapisu inna maszyna to tak na prawdę odczytując lokalne bufory dostajesz dane, które jeszcze nie istnieją i które są przestarzałe co może być nieporządaną sytuacją. Jeżeli chcesz upewnić się, że dane zostały sflushowane możesz wywołać FlushFileBuffers przed CloseHandle (same CloseHandle nie robi flusha).
Poza tym jak mówiłem - chcesz mieć takie gwarancje - używasz filesystemu, który ma zdokumentowane synchronizacje cacheów (czyli np samba + opportunistic locking).

A jak byłoby to w praktyce realizowane po użyciu tego FlushFileBeffers?

Dane są transmitowane na serwer, i on tam nie musi zapisywać na dysk, ale tylko do buforów - w celu zwiększenia wydajności.
Teraz po obu stronach jest to samo, ale nie zupełnie:
serwer później zapisuje to na dysk, a tu bęc - jakiś błąd na dysku.

Chyba tylko w takiej sytuacji stracimy ostatnio zapisane dane.

Klient wiedziałby o tym błędzie tylko wtedy, gdyby żądał zapisu bez buforowania (FILE_FLAG_NO_BUFFERING),
wtedy czekałby (wisiałby na WriteFile) aż serwer zapisze to na dysk.

1

Teraz mylisz zapewnianie niezawodności z zapewnianiem widoczności. FlushFileBeffers może zapewnić widoczność zmian w sytuacji którą opisałeś. Natomiast nie zapewni niezawodności.

0
adf88 napisał(a):

Patrząc z odpowiedniej strony atutem jest buforowanie i brak synchronizacji - lepsza wydajność, nie zamula ci komputera. Nie odpowiada? Użyj czegoś innego.

Gdy zapisuje kilku naraz, wówczas wystarczy blokować odpowiednio - za pomocą FileLock, i to powinno wystarczyć do synchronizacji.

A jeśli system trzyma kilka kopii naraz w buforach, i jest aż tak głupi jak w powyższym przykładzie,
wtedy nie ma sensu w ogóle tego używać - rezygnujemy z buforowania po stronie klientów.
Serwer może buforować. Na jednej maszynie raczej nie powinno być problemu z synchronizacją danych.

1

@bufor lekcja na dziś: doczytaj proszę jak działa logowanie typu redo i typu undo

0

A jeśli system trzyma kilka kopii naraz w buforach, i jest aż tak głupi jak w powyższym przykładzie,
wtedy nie ma sensu w ogóle tego używać - rezygnujemy z buforowania po stronie klientów.
Serwer może buforować. Na jednej maszynie raczej nie powinno być problemu z synchronizacją danych.

Czy jest sens czy nie ma sensu to zależy od wymagań aplikacji. Tak jak mówi adf88 - jeżeli standardowe zachowanie NTFSa w przypadku zdalnych plików nie spełnia wymagań to wybierasz taki system plików, który je spełnia.

1
0x200x20 napisał(a):

Czy jest sens czy nie ma sensu to zależy od wymagań aplikacji. Tak jak mówi adf88 - jeżeli standardowe zachowanie NTFSa w przypadku zdalnych plików nie spełnia wymagań to wybierasz taki system plików, który je spełnia.

Nie ma tu aż takiej swobody.
Każdy system operacyjny musi spełniać pewnie podstawowe warunki.

I do tej pory nie uzasadniłeś jak może dochodzić do gubienia
zapisanych danych tylko dlatego, że dysk nie jest lokalny.

0
Shalom napisał(a):

@bufor lekcja na dziś: doczytaj proszę jak działa logowanie typu redo i typu undo

Logowanie do czego?

Chodzi o elementarne operacje zapisu/odczytu.

0

Nie ma tu aż takiej swobody.
Każdy system operacyjny musi spełniać pewnie podstawowe warunki.

Mylisz system operacyjny z systemem plików. Poza tym pokaż mi gdzie te wytyczne, które "system operacyjny ma spełniać" :]. Jedynymi wytycznymi, które ma spełniać Windows jest dokumentacja udostępniana przez Microsoft.

I do tej pory nie uzasadniłeś jak może dochodzić do gubienia
zapisanych danych tylko dlatego, że dysk nie jest lokalny.

Uzasadniłem kilkukrotnie - najwyraźniej nie potrafisz czytać ze zrozumieniem.

1
0x200x20 napisał(a):

Mylisz system operacyjny z systemem plików. Poza tym pokaż mi gdzie te wytyczne, które "system operacyjny ma spełniać" :]. Jedynymi wytycznymi, które ma spełniać Windows jest dokumentacja udostępniana przez Microsoft.

Obsługa sprzętu to część ze zbioru zadań systemu operacyjnego.

Znajdź w dokumentacji punkt w którym napisano, że windows nie jest systemem operacyjnym, lecz atrapą.

0x200x20 napisał(a):

I do tej pory nie uzasadniłeś jak może dochodzić do gubienia
zapisanych danych tylko dlatego, że dysk nie jest lokalny.

Uzasadniłem kilkukrotnie - najwyraźniej nie potrafisz czytać ze zrozumieniem.

Mówiłeś o zasadach blokowania, ale to nie ma tu znaczenia, ponieważ tylko jeden zapisuje.

Musiałbyś opisać pełną sekwencję - krok po kroku, która prowadzi do zgubienia zapisanych danych
(zakładamy oczywiście, że nie ma błędów sprzętowych - to nie jest problem logiki i oprogramowania).

1

Coś czuje, że dyskusja z trolem i tak nie ma sensu ale niech będzie, może się komuś jeszcze przyda:

  1. Proces otwiera plik, zapisuje dane (ktore trafiaja do cache'a systemowego), zamyka plik. Zamkniecie pliku nie powoduje automatycznego zfushowania danych na serwer, Lazy Writer Windowsa po malu je przesyla (lazy close).
  2. Ten sam proces otwiera ten sam plik odczytuje dane, ktore nie pochodza z lokalnego bufora ale z serwera (np. dlatego że bufor jest utrzymywany per połączenie a nie per zdalny plik, a nowe połączenie zostało utworzone podczas otwarcia po raz drugi pliku), wiec dostaje przestarzale dane.
1
0x200x20 napisał(a):

Coś czuje, że dyskusja z trolem i tak nie ma sensu ale niech będzie, może się komuś jeszcze przyda:

  1. Proces otwiera plik, zapisuje dane (ktore trafiaja do cache'a systemowego), zamyka plik. Zamkniecie pliku nie powoduje automatycznego zfushowania danych na serwer, Lazy Writer Windowsa po malu je przesyla (lazy close).
  2. Ten sam proces otwiera ten sam plik odczytuje dane, ktore nie pochodza z lokalnego bufora ale z serwera (np. dlatego że bufor jest utrzymywany per połączenie a nie per zdalny plik), wiec dostaje przestarzale dane.

Takie coś nie ma sensu - po co system buforuje lokalnie, jeśli potem i tak czyta zawsze wprost z serwera?

Takie coś to zwyczajny błąd - wada systemu operacyjnego,
którą każdy szanujący się producent wyeliminowałby niezwłocznie.

Mikrosoft to dziady:
http://blog.mischel.com/2011/06/07/windows-file-copy-bug-revisited/

0

Mam jeszcze jedno trudne pytanie natury technicznej, odnośnie tego oportunistycznego blokowania.

Czy ustawienia tego blokowania ma jakikolwiek wpływ na działanie aplikacji roboczych (z punktu widzenia programisty)?

Działanie funkcji do operacji na plikach typu: CreateFile, WriteFile, LockFileEx,
jest przecież jednoznacznie udokumentowane i tam nie ma mowy o zależności
od ustawień serwera, strategii buforowania na danej maszynie, konfiguracji sieci, itp.

1 użytkowników online, w tym zalogowanych: 0, gości: 1