Sync, fsync, fdatasync, díváte se na jednu trojici z mnoha zel, které na linuxu občas potkávám. Tyto příkazy obecně mají zaručovat programu, že všechny data která do souboru zapsal, budou fyzicky zapsána na disk. A teď by se mohlo diskutovat o tom, jestli vůbec má uživatelská aplikace (čili program běžící v userspace) právo takto přímo manipulovat s HW daného počítače. Ano, všechny tři příkazy nařizují operačnímu systému, aby syncnul cache s diskem, zpravidla aby vysypal obsah dirty stránek v cache na disk a to okamžitě, bez ohledu na to, co zrovna operační system dělá.
Nebudete mi věřit, ale už jsem se setkal s filesystemem, který častý fsync dokonale položí. Ne, nezhroutí se, ale stane se nepoužitelným. Je to btrfs, který používám zejména kvůli schopnosti vytvářet subvolumy a také kvůli kompresi, což se zejména pro SSD disky zasouvané do USBčka (flash disky), celkem hodí. Ony ty flashky nejsou nějak extra rychlé, ale se zapnutou kompresí se s tím dá celkem bez problému žít.
Nechci otvírat diskuzi, zda fsync ano, nebo ne. Já si myslím, že ne, že aplikace nemá co kecat do nastavení operačního systému a jeho politiky práce s diskem. Diskové cache jsou pro aplikaci transparentní a to i ve vztahu s jinými aplikacemi, takže i bez explicitního syncování by měl být obsah souborů koherentní.
Jak tedy vypnout fsync na linuxu? A jde to vůbec? Nebudu k tomu potřebovat nějaké speciální dovednosti, jako například schopnost kompilovat jádro? Naštěstí to není tak těžké. Na níže uvedený postup jsem narazil, když jsem hledal důvod, proč dpkg je na btrfs tak pomalé. Postupně jsem vygooglil několik návodů, všechny založené na knihovně, kterou budeme načítat pomocí LD_PRELOAD. Knihovnu si lze jednoduše vyrobit.
libnosync.c
#include <unistd.h> void sync (void) { } int syncfs (int fd) { return 0; } int fsync (int fd) { return 0; } int fdatasync (int fd) { return 0; }
Kód přeložíme příkazem:
gcc -O2 -s -Wall -fPIC -shared -o libnosync.so libnosync.c
A jako root si jej nakopírujeme například do /usr/local/lib/libnosync.so
Aplikace, kterým chceme zakázat používání fsync a spol, budeme spouštět přes nastavenou proměnnou LD_PRELOAD
LD_PRELOAD=/usr/local/lib/libnosync.so apt-get install ubuntu-desktop
(mimochodem, bez libnosync se ubunu-desktop na btrfs instaluje klidně i několik hodin, po zapnutí libnosync to zvládne za několik minut).
Zkusil jsem s tím experimentovat a takto jsem si pustil Firefox. A vida, najednou je Firefox svižný i na flashce, a vůbec se mi nestává, že by na několik desítek sekund tuhnul (s vysokým I/O) při přecházení mezi stránkami, nebo pouštění videa. Po menší upravě (zvětšení) limitů dirty_pages a spol. (viz /proc/sys/vm/…), už ani nepoznám, že jedu přes flashku.
Šlo by tuhle knihovnu vnutit každému spuštěnému programu tak, abych se explicitního syncování zbavil nadobro…?
Teď stop! Určitě někoho napadla otázka, zda takový zásah nebude mít vliv na stabilitu celého systému. Je nutné si uvědomit, že vypnutí explicitního syncování pomocí knihovny nebylo syncování zrušeno nadobro. Pořád má operační systém možnost syncovat při uzavírání souborů, při otevření souboru se zapnutým O_SYNC a samozřejmě, že explicitně syncovat může i jádro (umount, atd). Takže si nemyslím, že by to mohlo ohrozit stabilitu systému. Maximálně tak stabilitu některých aplikací – i když, takový rozbitý dpkg není žádný terno.
Napadla mě spousta šíleností, například rvát LD_PRELOAD do .bashrc, dále do .xinitrc… do /etc/profile nebo /etc/environment. Všude to nefungovalo úplně dobře, zpravidla se zrychlilo jen něco, ale například dpkg spouštěný přes synaptic spuštěný přes sudo dál jel svou šnečí rychlosti. Nakonec jsem v man ld.so objevil zmínku o souboru /etc/ld.so.preload. Nyní již máte dostatek indicií, abyste přišli na to, co s tím dál.
Tenhle soubor ve standardní instalaci nenajdete. Ale přes strace zjistíte, že se hledá. Pokud jej vytvoříte a vložíte do něj cestu na knihovnu „so“, bude se poctivě načítat pro každý spuštěný proces. To si lze také ověřit přes strace.
Hlavní důvod, proč je synaptic tak příšerně pomalý, spočívá především v paskvilu jménem apt-xapian-index - odinstalovat! Ten sync za to může částečně taky, ale shora uvedená příšernost má na svědomí několikaminutové chroustání disku při každém spuštění synapticu, při němž je počítač prakticky nepoužitelný. Jinak celý synaptic je taky zralý na přepsání "from scratch".
[2,3] což IMHO nemůže, protože podle dokumentace ani sync, ani fsync, ani jiný sync nemůže zajistit, že data budou skutečně zapsána. Dokonce dokumentace naznačuje, že zápisy se mohou provést na pozadí, bez toho, aby funkce čekala na dokončení. Takže v tomto duchu lze chápat volání sync i tak, že se sice zápisy provedou, ale kdo říká, že musí hned, třeba až za 10 minut :-)
[4] Asi nejsem jediný, kdo to neznal, protože mi to při pátrání po řešení nikde nevyskočilo. Kdo by to taky hledal pod tímto názvem. Složitý to podle mě není. Každopádně díky za diskuzi, člověk se zase něco dozví.
Jen dodám pro ty, kteří jsou opatrní, že pokud máte notebook/UPS, tak se výpadku proudu bát nemusíte. Pokud ale spadne něco klíčového (třeba Xka), vypadá to, že jste namydlení. Ale nemusíte být, pokud znáte Magic SysRq kombinaci Ctrl+Alt+SysRq+S :-)
Btw. pokud padne jádro, tak vám to samozřejmě nepomůže. Ale pokud padne jádro, tak vám nepomůže už vůbec nic.
Ach boze ne uz zase! Kdyby nekdo mohl smazat tenhle priserny clanek svet by byl zase o neco bezpecnejsi. Tahle kravina s "obchazenim" fsyncu se vzdycky jednou za cas vynori. Fsync ma svuj vyznam a bez nej budou aplikace prichazet o sva data v tech nejmene ocekavanych situacich. To ze btrfs ma priserny vykon pri fsync workloadu je znama vec, a jiz existuji optimalizace primo v kodu (log tree) a dale se na tom bude pracovat, rozhodne to neni neco proc by lidi meli "obchazet" fsync. Mimochodem pokud clovek pouziva tak mlady souborovy system jako je btrfs tak holt s nekterymi problemy musi pocitat.
Navic pokud aplikace fsyncuji jak o dusi bez zjevneho duvodu tak je taky neco spatne, ale opet to neni duvod "obchazet" sync, ale spis opravit dane aplikace.
Takze tenhle hruzny postup doporucuju pouzit jenom v pripade ze je vasim cilem prijit o data. jinak rozhodne ne!!
[9] Mohu jen otázku? Jak může člověk na notebooku s baterkou, která nějakou tu hodinku ještě vydrží, přijít o data? Viz komentář stena [8].
Zakázany fsync se dá ještě zabezpečit pomocí krátkého "dirty_writeback_centisecs", takže důležité zápisy budou zpožděny o sekundu, ale to stačí, pokud to zabrání provést několik desítek synců za sekundu. Stejně Vám to nedává žádnou jistotu, že Vás výpadek proudu nepostihne těsně po zápisu a těsně před tím, než aplikace zavolá fsync.
Pěkně se tady hádáte :-) Mně by se nejvíc líbilo, kdyby fsync neukládal hned a měl 2 parametry navíc: jak moc rychle chce chce aplikace data fyzicky zapsat (jen takové doporučení pro OS) a callback, který se zavolá, až bude opravdu zapsáno. A kdyby bylo třeba něco jako /etc/fsync.conf, kde by šlo chování OS nastavit. Pro nás, blbé pak klikací třeba q/g/x/kfsyncconfig. Jinak si matně vzpomínám, že fsync mi úplně zahryzlo aplikaci na Androidu se sqlite (voláno z C++, ne přes javu), ale naštěstí to šlo přeložit i bez volání fsync. Ano, fsync je rozhodně nebezpečný nástroj. Nicméně spíš než zakazovat by se měl programátorům vysvětlovat. Aby ho nevolali kvůli každé kravině.
doporucuju libeatmydata: http://www.flamingspork.com/projects/libeatmydata/. Dokonce je to i v nekterych distrech zabalickovane :).
[9] fsync() sice ma svuj vyznam, ale tak 95 % aplikaci jeho semantiku nepotrebuje a pokud v nich je, tak jenom proto, ze neni bezne dostupne slabsi synchronizacni primitivum, ktere by zajistilo to, co aplikace potrebuji. Viz treba navrhy pro fbarrier() syscall.
AFAIK priserny vykon nema jenom Btrfs, ale i ext3, kde je (AFAIK) fsync() v podstate degradovan na sync().
[15] Chápu to tak, že od fbarrier se očekává serializační (nebo přesnějí: seřazovací) operaci, kdy data zapsaná před fbarrier se i fyzicky zapíšou před daty, které byly zapsány po fbarrier, včetně aktualizace metadat. Požadavek na vykonání ihned tam není, tedy operační systém má stále možnost optimalizovat buffery a provádět zápisy na pozadí, když nejsou žádné prioritní I/O požadavky (zpravidla čtecí).
Otázka je, zda to u btrfs pořád neznamená nutnost uzavřít před takovou operací transakci, jak jsem pochopil, commit transakce je pomalý, bez ohledu na množství zapsaných dat. Uzavírat transakci s pár bajty v bufferu tedy není nic moc optimálního. Ale i tak, pokud by se tak dělo na pozadí, možná by to pomohlo.
[18] Ondrovo řešení je sice čuňárna, ale to nic nemění na tom, že článek je to zajímavý a poučný (měli by si ho přečíst hlavně tvůrci programů volajících fsync!) a konec konců i čuňárny mohou být užitečné ze studijních důvodů. Navíc mi přijde že jako řešení např. zakusujícího se firefoxu na nějakém desktopu, kde nejsou žádná cenná nezálohovaná data (např. můj firemní notebook - zdrojáku mám v gitu na serveru, vývojové prostředí se dá zadarmo stáhnout, ... a jinak tam nic moc víc není) se i tahle čuňárna dá použít. Problém by byl, kdyby to někdo začal cpát třeba na server nebo nedej bože do distribucí... Takže mně se čánek líbil.
Nechapu proc se tak hadate kvuli integrite dat, kdyz v dnesnich prostredich stejne nemate uplnou zaruku ze po tom co opusti sbernici tak budou zapsana. Od OS k realnemu disku to muze byt hardwarove totiz docela daleko a za mnoha krabicemi,kabely a cachemi. Vzdycky je tu riziko ze se data nekde ztrati.
Za 99,99% fyzicky provedeny zapis se plati vykonem a penezi. Nutno vsude povypinat write cache a otestovat jestli storage neignoruje flush cache command.
Proto nechapu kterej nouma tam implementoval explicitni (f)sync. Je to takovy danajsky dar. Holt kdyz mi masina slitne pri instalaci, tak univerzalni cesta fs fix,pkg db fix,pkg remove, pkg install. +- na vetsine unixovych pkg systemu tohle zabere. V produkcnim prostredi se mi i stalo ze masina uhnila pri instalaci, ale abych kvuli tomu musel zpomalit vsem instalaci baliku, tak to radeji risknu poskozeni databaze baliku a neuplnou instalaci. Narozdil od dat zakazniku toto neni kriticka vec kde musim zarucovat konzistenci.
[11] Člověk s baterkou zakázaný fsync() přežije, ale mnoho počítačů baterku/UPS nemá. A mnoho počítačů je má, ale nechtějí riskovat selhání baterky/UPSky.
Výpadek proudu před ani po fsync() nevadí. Zapisovaná data se samozřejmě ztratí, ale software ví, která data nejsou zapsaná, resp. jsou zapsaná částečně, a může se tedy zotavit. (Ano, průměrný program takové zotavování neimplementuje, ale databáze ano, zejmnéna u balíčkovačů.)
Připomínám že fsync() a spol nezapíší data ihned - v informatice nelze udělat něco ihned u ničeho. Volání fsync() způsobí, že po návratu budou data zapsaná, ale to volání může trvat klidně sekundy.
Možná mají aplikace volat jinou synchronizační operaci, možná mají používat transakce (ale i tam bývá potřeba čekat na dokončení). Možná má být dokumentace fsync() lepší. Některé aplikace používají fsync() příliš nebo zbytečně.
[21] O write cache se postará kernel, za běžného provozu se bude používat.
[22] software se těžko něco bez proudu dozví. Jediný, na co lze "možná" spolehnout je pořadí. Tedy při obnovení lze podle množství zapsaných dat a známého pořadí rozhodnout, co bylo a nebylo zapsáno. fsync se používá pro oddělení dvou zápisů, zápisy před fsync a zápisy po fsync, nestane se pak, že by data po fsync byly zapsána před těmy, které byly zapsána před fsync. Díky cache to možné je, protože ty se nevyprazdňují v tom pořadí, v jakém byly plněny, ale tak jak se operačnímu systému hodi.
Proto jsem říkal, že kdyby fsync fungoval jako seřazovací funkce, pak bych jeho použití nezakazoval. Seřazovací funkce nemusí nutně čekat na dokončení, musí jen aplikaci dát jistotu, že některá data se zapíší až po zapsání jiných dat.
Jinak výpadky proudu řeší žurnály, a to ať již na straně filesystému, nebo si aplikace sama musí vést žurnály pro data. Tam chápu, že uzavření transakce v žurnálu může vyžadovat fsync, jenže opět, není potřeba, aby se na něj čekalo. Jen by operační systém měl zaručit, že data zapsaná po fsync nebudou na disk přepsána před daty,které byly zapsané před fsync.
No, nechci tady vyvolávat flame, ale názor "aplikace nemá co kecat do nastavení operačního systému a jeho politiky práce s diskem" mi přijde poměrně svérázný (či padlý na hlavu, mám-li být otevřený). Kdo jiný než aplikace je schopna rozhodnout co je nutno splnit pro konzistenci dat? To je aplikační záležitost a jádro o závislostech mezi jednotlivými zápisy vůbec nic neví a vědět nemůže.
To že SATA disky sprostě lžou a potvrzují zápis ještě než se data skutečně dostanou na médium je známý fakt. Serverové disky tohle samozřejmě nedělají (navíc většinou mají řadič s cache s baterkou) a rozumné SSD disky mají vlastní baterku pro cache.
Částečně to jde "opravit" pomocí barriers, které zajišťují pořadí zápisů ale nevynucují je, nicméně transakční systémy vesměs potřebují při commitu fsync provést, aby zajistily ACID. A není to jenom o databázích - jinak by se například mohlo stát že sice instalace proběhne v pořádku ale někdy potom se vám ten systém vypne a jste v háji protože ztratíte netriviální množství dat. A pokud nepoužijete "barriers" tak se nemůžete spolehnout vůbec na nic.
BTW pokud aplikace zbytečně zapisuje dočasné soubory na disk, není nic jednoduššího než je umístit do tmpfs. Pokud to spadne tak vás jejich ztráta stejně netrápí a rozhodně je to čistější než vypínat fsync přes preload ...
Tommy, proč si myslím, že aplikace nemá co kecat do nastavení operačního systému a jeho práce s diskem? Operační systém je tu od toho, aby izoloval aplikace od HW. Pokud tedy operační systém je schopen zajistit aplikaci to co požaduje, tedy zápis dat na disk, tak skutečně aplikace nemá nárok na to vyžadovat po operačním systému fyzické vykonání. Už proto, že tenhle nárok není možné zaručit.
To co OS musí aplikaci zajistit je, aby data byla koherentní, tedy aby zápis v jednom procesu se pak projevil při čtení v jiném procesu. Pokud má aplikace k dispozici funkci flush, tak jen proto, aby zajistila, že interní vyrovnávací paměti se přepíší do vyrovnávacích pamětí OS, které zajišťují koherenci. OS by měl aplikaci zajistit pořadí, aspoň na kritických místech, rozhodně ale nemusí zaručovat aplikaci fyzický zápis. Může to být taky proto, že cílové médium není zrovna k dispozici, je vytížené, nebo OS jednoduše ví, že zápisy lze pozdržet, nebo sloučit do jednoho balíku, protože OS má tradičně větší přehled o stavu systému, než samotná aplikace. Co když se ukáže, že aplikace zapisuje data pro jiný proces,který je následně načte a soubor smaže. OS tohle může lépe podchytit a ušetřit spoustu výkonu.
Pokud by fsync v btrfs zajišťoval pouze funkci seřazení, bez nutnosti provádět fyzický zápis, pak ať tam ta funkce zůstane. Ale zatím to je výkonnostní problém.
No, a já s tím nesouhlasím a tvrdím že aplikace by tuto možnost (vynutit zápis na médium) mít měly. Samozřejmě to neznamená že to potřebuje dělat každá aplikace - to určitě ne. Ale např. ACID-compliant transakční systémy jsou typ aplikace která toto vyžaduje.
Pokud se bavíme o tom že toto prováději i aplikace které to jinak nepotřebují a že se s tím některé filesystémy neumí rozumně vyrovnat, tak to bohužel pláčete na nesprávném hrobě. To prostě není relevantní důvod sebrat aplikacím možnost provádět fsync.
A prostě není pravda že zavolání fsync nezaručí zápis na médium. Jistě, consumer-level SATA disky lžou, ale 100% SAS disků (tj. standardní serverové) nebo i kvalitnější SSD disky tímto neduhem netrpí. Takže tvrzení že "tenhle nárok není možné zaručit" je jednoduše nepravda - standardní hw to zajistit umí.
Nechápu argumentaci že fsync by měl zajišťovat jenom pořadí - k tomu jsou barriers, účelem fsync je zajistit zapsání dat na médium pokud to aplikace potřebuje.
To že OS může zápisy při nahromadění optimalizovat, o tom není sporu a aplikace které zapisují větší množství dat do jednoho souboru toho samozřejmě využívají - pokud potřebují zajistit propsání až na médium tak prostě zavolají fsync až na konci a OS ať si to seřadí dle libosti. Pokud aplikace volá fsync průběžně tak k tomu asi má nějaký důvod ...
Řeknu asi šílený, ale zřejmě naprosto relevantní argument. Co když je cílovým mediem magnetofonová páska? Pokud by OS měl zaručit fyzické zapsání, tak tím totálně zlikviduje výkon systému, protože by to znamenalo přetočit pásku na určité místo a provést zápis, ať již to zařízení zrovna vykonává cokoliv.
Obecně mám za to, že zápisy jsou vždy pomalejší, než čtení a navíc by zápisy měly býti méně prioritní, než čtení (přednost mají ti, co odchází z disku, pak teprve ti, co na disk vstupují). Protože při čtení se musí čekat, zatímco při zápisu většinou ne. Jakékoliv nucení zápisů ze strany aplikace znamená, že aplikace neadekvátně zasahuje do priorit nastavené pro optimální výkon. A to jen pro případ události, která nastane výjimečně. U zabezpečených systému se stejně předpokládá UPSka a signál, který syncne disky při výpadku proudu před tím, než v UPSce dojde baterka
Pro integritu dat přitom není rozhodující, zda se zápis provedl fyzicky. Rozhodující je správné pořadí zápisu. Drtivá většina žurnálovacích systémů je na tom založena. A žurnály jsou jedinou ochranou před vytváření nekonzistentních stavů při výpadcích. Fsync je tedy nejen nevhodná, ale i zbytečná. (k pořadí stačí, jak píšete, barriers, ačkoliv nevím, kde to v tom linuxu najdu),
Sledujte prosím tok mých myšlenek:
1) Jsou aplikace které potřebují (resp. je to po nich požadováno) ACID vlastnosti, což mimo jiné vyžaduje v daném okamžiku vynucení zápisu dat na médium.
2) OS toto sám o sobě zajistit nemůže, neví jak a do kdy data zapsat. Toto musí v konečném důsledku řídit aplikace.
3) Existují situace kdy ani UPS nepomůže - může se pokazit samotná UPS, může dojít k vyčerpání její kapacity, může se pokazit zdroj v systému, nebo například může dojít ke kernel panic. To vše bez fsync vede k nekonzistenci zapsaných dat.
To že nižší priorita zápisů by nějak vedla k vyššímu výkonu je absurdní - možná by to platilo pro nějaký váš konkrétní aplikační problém ale rozhodně ne univerzálně. Když nic jiného tak aplikace většinou dělají mix čtení a zápisů a dá se jaksi čekat že když zvýším prioritu čtení na úkor zápisů tak si ve výsledku asi moc nepomůžu. A pokud se bavíme o rotačních discích tak tam většinou nebývá problém v sekvenčních operacích ale v IOPS, a tam čtení/zápis vychází nastejno (je jedno jestli seekujete abyste četl nebo zapsal).
Tvrzení že pro integritu dat není rozhodující zda se zápis fyzicky provedl ponechávám bez komentáře, resp. viz. body (1) a (3) výše. I když samozřejmě záleží na tom co rozumíte konzistencí - pokud to že fsck na daném svazku proběhne OK tak možná ano. Pokud chcete aby se ACID aplikace chovaly ACID tak je to nesmysl.
Tommy, sledujte tok mých myšlenek.
1) Aplikace, které vyžadují vlastnost, že po potvrzení zápisu je skutečně zapsáno, těch by se dalo na prstech spočítat, a rozhodně do nich nepatří žádná aplikace pro desktopové uživatele. Ani jedna prosím. Málokterý uživatel dokáze postihnout to, zda stihnul zmáčknout control+s před výpadkem, nebo až po výpadku.
2) OS má naprostý přehled o tom, které data zapsal. Nezná pouze jejich interpretaci. A tomu to může být fuk. OS musí zajistit konzistenci dat a nejde jen o fsck. Měl by umožnit vytvářet žurnály aplikací, nebo jim v tom pomoci právě třeba pomocí bariér. Opakuji, že desktopový user (99% nasazení výpočetní techniky), neocení fyzický zápis na disk, ale negativně ocení pomalou odezvu systému.
3) Čili jmenujete případy, které jsou ještě méně časté, než klasický výpadek proudu. Bravo.
Pomalost zápisů pramění z toho, že na čtení je většinou třeba čekat. Malokterá aplikace si umí data "přednačíst do paměti", zpravidla to za ni řeší OS, pokud odhadne, zda aplikace bude číst sekvenčně nebo náhodně. U zápisů je to jednodušší. Právě pokud aplikace nepotřebuje mít utvrzeno, že zápis skutečně proběhl, nemusí na zápis čekat, To může zařídit OS v době, kdy nemá disk co na práci. Tahle optimalizace je velice účinná právě u SSD disků, kde jsou zápisy navíc velice pomalé.
Ano, mávejte si tu nějakými zkratkami a normami, ale je lepší se vrátit zpátky na zem. Právě vám píšu s takto upravením OS v mém notebooku a zatím mi několikrát dceruška vytrhla flashku za běhu, jednou se mi kousnu kernel (nesouvisí s fsync) a několikrát se neprobudil (stávalo se i před úpravou) a o data jsem zatím nepřišel.
Třeba jednou přijdu o těch 10 sekund práce, kdy se to neuložilo, neb mám zápisy na disk vynucený do 10 sekund po posledním zápisu do cache. Mimochodem i to je řešení pro příliš paranoidní uživatele. Zkrátit expiraci cache na sekundu. Furt je to lepší, než X krát zavolaný (f)sync za sekundu z aplikace, která pouze kopíruje nějaké soubory.
1) Řeč byla obecně o uživatelských aplikacích, tj. procesech běžících v userspace. Vy v postu tvrdíte že tyto aplikace nemají co kecat do toho kdy se má fsyncovat, já tvrdím že toto právo mít mají protože prostě některé aplikace to prostě vyžadují. Pokud nějaká aplikace provádí dle vašeho názoru fsync zbytečně tak si stěžujte vývojářům té aplikace, ne na fsync.
2) Ale jistě - pokud uživatel preferuje rychlost před nějakou úrovní zaručené konzistence dat v případě výpadku a je si vědom důsledků, nechť si to třeba všechno hodí do paměti a fsync pro něj nebude problém vůbec. Ono to ale většinou bývá tak že uživatel toto přestane oceňovat přesně do okamžiku prvního pádu kdy přijde o nějaká data (i kdyby jenom musel fixovat dpkg databázi).
Ale znovu opakuji že prostě není pravda že OS může všechno udělat za aplikace - i kdyby se objevila možnost vytvářet barriers, tak nezanedbatelné množství aplikací pro konzistenci dat potřebuje volat fsync.
3) To že je něco méně časté než výpadek proudu (o čemž by se dalo polemizovat) přeci neznamená že to nejsou relevantní rizika.
Ad pomalost zápisů - no ale ono to takhle dneska funguje, ne? Aplikace zapisuje do page cache (pokud nepoužívá O_DIRECT) a OS to na pozadí flushuje na médium. Samozřejmě pokud aplikace z nějakého (předpokládejme že dobrého) důvodu neusoudí že potřebuje zavolat fsync, čímž se zápis vynucuje.
Každopádně on aplikaci nikdo nenutí zapisovat synchronně, ne? Ono totiž prosté write žádný fsync neprovádí, no a pokud ho aplikace zavolá tak to asi dělá z dobrého důvodu ... Když už, aplikace nechce dělat asynchronní I/O tak existuje možnost volat asynchronně alespoň fsync - samozřejmě to ale vyžaduje nějaké programátorské úsilí.
Průser s vypnutím fsync je v tom že vy nepřijdete jen o těch posledních 10 vteřin - vy si pak totiž nemůžete být jist vůbec ničím protože některé z těch nových zápisů už mohou být na médiu zapsána protože OS se je tak prostě rozhodl přeuspořádat v rámci optimalizace. Takže vy tam máte neznámý mix starých a nových dat a nejste schopen rozlišit co je co a můžete to celé zahodit.
Ad pomalost zápisů na SSD - to samozřejmě platí jen pokud používáte fs bez TRIM a většina bloků je "plných".
Oč jednodušší by byl život, kdyby se linux na nějaký fsync vykašlal a zařídil by právě tu serializaci zápisů. Dneska vám negarantuje ani procesor pořadí zápisů do paměti a doba, kdy vám negarantuje zápisy ani vlastní disk je za dveřmi (nebo stojíme ve dveřích). Takže opravdu fsync je zastaralá věc, která nemá v moderním světě co dělat. Naopak serializace (seřazení) zápisů v linuxu (jako mnoho dalších věcí) citelně chybí.
Ohánět se tím, že na vlastním desktopu nemám (to bych chtěl opravdu vidět), programy, které nepotřebují mít konzistentní zápis na disk, není argument. A to, že jsi ještě nepřišel o data na fsyncless systému považuj za štestí. Možná přišel, jen o tom ještě nevíš (silent data corruption).
Každý program, který pracuje s daty, fsync nutně potřebuje. Ať jsou to databáze (kterých mohou být na desktopu desítky, vždyť jen kolik jich má takové Chrome nebo FF), nebo třeba i takový obyčejný maildir.
Jsou programy, které NUTNĚ vyžadují zápis na disk, protože jsou na tom závislé další kroky, které nemusejí být na daném počítači (takže ani seřazené operace nepomohou). Synchronizované replikace databází. Databáze samotná na jednom hostu musí vrátit potvrzení commitu klientovi až po úspěsném zapsání dat na disk.
Jak už tu psalo mnoho lidí předemnou. To že existuje fsync neznamená, že jej všechny app musejí povinně používat. Existuje jako možnost. Stejně tak, jako volby otevření souboru. Je pouze na programátorovi, jakou si vybere.
Ad šílený argument s magnetofonovou páskou. Ano, OS musí skutečně zapsat data na médium, přesně to app po něm vyžaduje a přesně tak je navržena. A jestli administrátor daného HW připojil pásku jako blokové zařízení, tak nejspíše ví co dělá a je to přesně to, co chce.
S HW, který cíleně lže o zápisu na medium, se snad ani nemá smysl bavit. Na takovém nemůže být konzistentní nic, nebo by musela být detekce posledního konzistetního stavu.
Píšeš, že OS ví, které zápisy lze pozdržet a grupovat. Ale to OS už hodně dlouho dělá. IO Schedulery (elevator; lze si vybrat) se přesně o tohle snaží, grupovat požadavky k sobě tak, aby se co nejefektivněji zapsaly na dané medium s minimem latence).
Btrfs je stále ve vývoji a o pomalém fsync se ví. Je jisté, že to bude předmětem optimalizací. I na straně programů.
[33]: No tak to moment. Pri procesore mam predsa moznost si vynutit zapis premennej do pamate - potrebujem to najma na viacproseorovych masinach kde je nejaka premenna 'chranena' mutexom, je v kritickej oblasti. Ak by som nemal garantovane, ze ak som v kritickej oblasti, zapisem do premennej hodnotu tak sa tento bude propagovat do operacnej pamate, tak druhy procesor z ineho socketu (pretoze v ramci jedneho socketu mame mechanizmy na detekciu tohoto pripadu) po vstupeni do kritickej oblasti precita staru hodnotu a vlastne celu synchronizaciu tak mozem zahodit.
Nemylit si Out-of-order spracovanie s vynucovanim zapisu!
Ale spat k teme, samozrejme zakazovanie fsync je blbost rovnako ako jeho zneuzivanie. Argumentovat vymyslenou aplikaciou ktora vola fsync niekolko krat za sekundu v prospech zakazania fsyncu je uplne mimo misu. Taku aplikaciu treba prepisat alebo nepouzivat. Nemoze pre jedneho blbca trpiet cela spolocnost.
[35] Škoda, že taková aplikace je dpkg.
- k první části nebudu reagovat, protože je to úplně jinak než píšete a vydalo by to na samostatný článek.
[34] Btrfs se takto opravuje už několik let. Blogpost je návod, jak si lze fsync vypnout. Máte naprostou svobodu můj návod nečíst, nebo si z něj vzít jen některé myšlenky.
Trvám na tom, že fsync je zastaralý a mnohem víc se užije seřazování. Příklad replikace databáze je nesmysl, už proto, že jde o replikaci (mj záloha dat). Replikace nezaručuje, že data poslaná po síti budou zapsaná ihned na cílovém stroji. Proč bych tedy měl vyžadovat data zapsaná na disku? On z toho disku čte ještě někdo další? (který nejde přes OS?). Při výpadku proud vám nikdo nemůže zaručit, že odeslaná data tam budou nebo nebudou (co když při výpadku proudu odejde celý filesystem?). Měl by vám ale zaručit, že data budou konzistentní. Což lze bez fsyncu za použití seřazovacích technik.
Opakuju, že BFUčko nepozná, kdy mu vypadl proud, jestli před tím, než vydal příkaz, nebo až potom. Kolikrát ani neví, kdy aplikace výsledek příkazu skutečně zaznamenala trvale na disk.
Silent data corruption jsem opravdu neobjevil. fsck nic nehlásí, všechno funguje jak má, filesystém je žurnálový (mimochodem, v žurnálu fsync vypnutý není a taky to z userspace nejde)
> Jsou programy, které NUTNĚ vyžadují zápis na disk, protože jsou na tom závislé další kroky, které nemusejí být na daném počítači.
Ano, to jsou programy, ktere pro dodrzeni nejakeho protokolu opravdu sync potrebuji (typicky priklad je treba mailserver, ktery by mel potvrdit prijeti mailu az pote, co ho doruci).
Problem je v tom, ze takovych programu je minimum (alespon v 'uzivatelske metrice') vzhledem k tem, ktere tohle nepotrebuji a presto fsync() uzivaji.
Typicke priklady jsou uzivatelske aplikace jako textove editory ci webove prohlizece, kterym opravdu staci pouze to, aby po vypadku byl disk v starem nebo novem konzistentnim stavu, ale vynucovat novy stav rozhodne nepotrebuji.
[36] Nemáte pravdu. Databáze u synchronní replikace vzátí řízení klientovi (příkaz commit skončí bez chyby) až po té, co jsou data zapsaná na všech replikačních uzlech. Funguje to tedy zcela stejně, jako u jednoho lokální db démona (s tím, že zde se čeká na toho nejpomalejšího vzdáleného).
Při výpadku je jasné, co se commitlo (spolehlivě na všechny uzly) a co ne.
Mě je zcela jedno, co BFU pozná a co nepozná. Uživatelé si stěžovali, že se jim na ext4 ztrácí data v případě crashe OS. Mohlo za to jednak delayed allocation (novinka v ext4 proti 3) a také to, že programy využívaly sémantiku, která byla zcela náhodná a nečekaná (díky ordered journal, commit=5), tedy, že se data fsyncla před metadaty a jakákoliv změna metadat tak nechtěně zaručila i spolehlivý zápis dat (tyhle vadné programy to řešili nějak přes přejmenování). Tohle fungovalo pouze na ext3 v určitém konkrétním nastavení a přes to změna na ext4 způsobila poměrně silnou bouří. Právě od těch BFU.
Zastaralý. Pokud ordered zápisy budou vracet protvzení o svém provedení (protože to je skutečně potřeba) potom ok. Jenže potvrzený zápis je vlastně fsync. Takže trochu kruh, že ano.
[38] Největší problém je v tom, že kdejaká databáze se dnes nachází v jakékoliv aplikaci. I ten naprosto hloupý firefox používá databáze k ukládání koláčků a preferencí. Pokud je fsync v každé takové databázi, tak není divu, že výkon takového systému jde do "kytek". Podle mě fsync (a podobní) by měly podléhat minimálně nějakým limitům, fsync by měl právo udělat proces běžící jako root, případně pod účtem, který má tuto funkci povolenou. V ostatních případech by měl fsync fungovat jen jako hint pro operační systém, třeba pro seřazení zápisů, což by zajišťovalo konzistenci dat (umožnilo by to tvořit žurnály pro data), ale nezajišťoval by, že data zapsaná sekundu před výpadkem by byla zaručeně zapsaná.
Z druhého odstavce mám pocit, že spoustu dnešních hacků v aplikacích řeší chyby v extX filesystémech. A výsledkem je pak to, že v jiných filesystémech to nefunguje dobře.
Největší problém jsou zde priority, jednak se ukazuje, že zápisy zejména na ssd disky opravdu jsou pomalejší a budou pomalejší a linux tohle neumí řešit. Dalé chybí režim "zapiš data, jakmile to bude možné". V tuto chvíli mohu sice nastavit jak často se spouští pdflush a jak rychle zastarávají data v cache, ale efektem je jen to, že se zápis pozdrží, ale pak se zapíše, bez ohledu na to, co OS zrovna dělá. Běda jestli třeba zrovna provádí čtení souboru s filmem. Jinak totiž nedokážu pochopit, jak je možní, že drobný zápis na BTRFS na médium s přenosovou rychlostí 10MB/s přeruší na 10 sekund přehrávání filmů, který má přenosovou rychlost 500kB/s. Kdyby existovali priority, muselo by flushování cache probíhat per-partes s respektem na čtení, které má mít přednost a nemělo by docházet k vyhladovění čtení jen proto, že pdflush zrovna dosáhl nastaveného limitu expirace.
Fsync v režimu "zapiš data, jakmile to je možné" by tedy byl méně prioritní zápis prováděný okamžitě, pakliže není nic ke čtení. I v tomto případě je možné zapisující proces pozdržet, dokud se zápis neuskuteční. Nicméně nesmí tento proces shodit výkon celého OS, a o tom to celé je. Dá se na tom postavit solidní DoS útok. Doufám, že tuhle obavu se mnou sdílíte.
Ano, BTRFS je ve vývoji a vypadá to, že ještě nějaké století bude. Mám na výběr. Buď ho nepoužívat, používat a trpět, nebo to nějak obejít. Tohle je jedna možnost. Schválně zkusím to médium provozovat na ext4, uvidíme, jak tam budou rychlé zápisy a jak budou zdržovat celý OS.
[39]
Prioritizace IO operací v jádře již nějaký ten pátek je. To co popisujete s pdflush je spíše na optimalizaci schedulerů, na čemž se, nepřekvapivě, též kontinuálně pracuje.
Ad hacky aplikací, zpožděný zápis apod. Však ta app má všechny prostředky, co k tomu potřebuje. Může si vynutit fsync hned, může to nechat na OS, může afaik vynutit pořadí pomocí barier (zde si nejsem jist, jestli to není jen VFS a userspace se k tomu nedostane). A pokud si potřebuje řídit, tak na to může mít spešl thread pro asynchronní (není-li nutný synchronní) zápis dat z hlavního vlákna a uživatelské prostředí nemusí na nic čekat. Všechno jde. App, které to ojebávají jinak (než je dokumentovaná vlastnost) jsou vadné. Tuhle jsem se díval na možnost běhu DB na NFS. V dokumentaci DB bylo, že pro NFS žádné spešl věci nedělají a nejsou třeba, protože to NFS se má chovat jako kterýkoliv jiný FS (a taky se tak chová, pokud si to někdo nenastaví podle Štraucha).
Ad hloupý FF. Kdyby to nedělal, tak si zase budou uživatelé stěžovat, že po crashi (výpadku proudu) přišli o záložky a zapamatovaná hesla. Zkrátka něco za něco.
Ad obava. Obavu nesdílím, někdy je prioritní čtení, jindy zápis. Já dělám DB. Tam se dá také lecos ojebat. A řeknu vám, že je daleko lepší se smířit (ono totiž ani nic jiného nezbyde), že klasický 7200rpm disk nedá víc jak 120 fsync (commitů) za sekundu. Můžu si hrát na to, že to není pravda a vypnout sync na disk, můžu to různě ojebat. Potom se to vymstí. Je daleko lepší vnímat realitu. Pokud 120 transakcí(zápisových) nestačí, musím koupit sas disky. Nebo serverové SSD. Nebo řadič s pořádně velkou write cache a baterkou. A nebo víte co? Použít jiný produkt. key-value in memory také existují a mají miliony operací za sekundu. K disposici mi to je.
[40] Těžko si budou uživatelé FF stěžovat, že přišli o záložky, protože by se to mělo týkat jen věcí změněných bezprostředně před výpadkem. A je mi líto, pokud výpadek způsobí, že se poškodí již (kdysi dávno) uložená data, pak mi nepomůže ani fsync, protože... co když vypadne proud zrovna v půlce fsyncu? Žurnálovací FS nemusí nutně žurnálovat data. Já třeba všechny soubory ukládám stylem "ulož vedle a pak přejmenuj" a přejmenování se už žurnáluje po dokončení zápisu těch dat (takže buď se nic neuloží, nebo se uloží vedle, nebo se uloží správně, nic mezi tím).
120 commitů za sekundu je sakra málo. Ale opravdu sakra málo! Pokud těch 120 commitů nevyrobí jeden proces v jednom vlákně, tak bych si dokázal představit, že je bude OS groupovat a třeba jednomu procesu dovolí udělat 10 commitů za sekundu (1 fsync za 100ms) a pokud to přešvihne, pozdrží ho tak, aby se s tím svězl fsync z jiného procesu / threadu. Ono tím pozdržením lze řešit i situace, kdy je potřeba druhou stranu informovat, že zápis skutečně proběhl. Tohle by se dalo realizovat upravou výše představené knihovny (která by měřila čatnost sycnů a zdžovala by požadavky podle nastaveného plánu)
Jenže to neřeší dpkg, který tedy na jednu stranu přestane zvyšovat load operačního systému, ale jeho činnost se nijak nezrychlí.
pdflush a jeho řízení je kapitola samam pro sebe. Krásný je parametr dirty_ratio, které říká, že pokud dirty cache dosáhné této velikosti, veškeré IO se zablokuje, dokud se dirty cache neflushne na disk. Co to je za dementní pravidlo? Ať to spíš zablokuje tu aplikaci, dokud není HW dostatečně volný, aby mohl začít dirty stránky zapisovat na disk. Zase další způsob, jak sestřelit Linux DoS útokem pomoci aplikace spuštěné běžným uživatelem.
Čtení musí být prioritní,protože zatímco na čtená data někdo čeká, na zápis není třeba čekat, dokud někdo netrvá na syncu, případně pokud nedojde prostor v cache. A i tam to většinou je o jednom dvou kusech, zatímco na čtení může čekat stovky procesů.
Cituju (napr. http://pubs.opengroup.org/onlinepubs/7908799/xsh/fsync.html)
The fsync() function can be used by an application to indicate that all data for the open file description named by fildes is to be transferred to the storage device associated with the file described by fildes in an implementation-dependent manner. The fsync() function does not return until the system has completed that action or until an error is detected.
The fsync() function forces all currently queued I/O operations associated with the file indicated by file descriptor fildes to the synchronised I/O completion state. All I/O operations are completed as defined for synchronised I/O file integrity completion.
Nevim, jestli k tomuhle je potreba neco dodavat. Podle mne je uplne jasne receno, co je fsync a k cemu slouzi :)
Pokud píšu např. zdrojový text v TeXu, tak potřebuji, aby bezprostředně po uložení v editoru byly nejnovější verze textu k dispozici pro překladač TeXu. Ne jako ve Windows, kdy je nutno čekat až několik minut, případně je nutno vypnout a znovu zapnout textový editor, aby byla na disku k dispozici nejnovější verze psaného textu.
To k názoru, že "99% uživatelů na desktopu nepotřebuje synchronizovat data".
[43] To je s dovolením nesmysl. (f)sync se týká dirty stránek cache, kterou spravuje operační systém (linux). Cache využívá jak pro zápis, tak pro čtení. Zápis se tedy děje přes cache, ze které pak může číst i jiný proces. Z hlediska procesů se tedy cache chová transparentně a z toho pohledu se zdá, že data jsou fyzicky zapsána. Cache je vlastně takový ramdisk, který replikuje obsah disku, tedy aspoň jeho část. Čili i bez (f)sync vám překladač přeloží TeX uložený v editoru. Vězte, že já takhle vyvíjím už několik měsíců, píšu v C++ a používám automatický překlad v Eclipse po uložení (po uložení se to hned na pozadí přeloží, takže se mi označí chyby).
Není prostě technicky možný, že by jeden proces uložil soubor, ten zůstal v cache a druhý proces otevřel soubor "čtený přímo z disku". Dokonce i při použití O_SYNC se podle mě bude číst z cache, pokud tam ty data jsou a při zápisu se bude stejně zapisovat do cache, pouze s tím, že po každém zápisu se provede implicitní (f)sync.
To co máte na mysli by nastalo v okamžiku, kdy by k jednomu disku měly přístup dva operační systémy současně se svými cache. Takové uspořádání jsem ale zatím nikde neviděl.
[43] PS: Ani ve Windows to není tak jak popisujete. Cachování ve Windows funguje velmi podobně. Je tam pár zajímavých vychytávek, jako třeba, že lze soubor otevřít s příznakem TEMPORARY, čímž Windowsům dávám hint, že přepis souboru na disk má nejnižší prioritu. Pokud takový soubor smažu před tím, než je zapsán, na disk fyzicky vůbec nedoputuje. Tím se dost eliminují zápisy na disk, pokud se pracuje s dočasnými soubory. Přijde mi, že Windowsovský cache manager je výkonově na tom o trochu líp, než pdflush. Hodně se snaží využívat zápisy v pozadí, i když taky to ještě není ideální (třeba když nechám uspat WmPlayer s 2GB paměti, stane se PC na delší čas nepoužitelné kvůli témuž problému, jakým trpí pdflush - příliš mnoho dirty stránek zablokuje veškeré I/O)
Intenzivně se zabývám programováním zejména v jazyce C++. Vyvíjím vlastní knihovny, vzory, techniky, používám šablony, to vše proto, aby se mi usnadnil život při návrhu aplikací. Pracoval jsem jako programátor ve společnosti Seznam.cz. Nyní jsem se usadil v jednom startupu, kde vyvíjím serverové komponenty a informační systémy v C++
Přečteno 51 190×
Přečteno 24 017×
Přečteno 22 904×
Přečteno 21 069×
Přečteno 17 807×