{"id":98090,"date":"2020-10-24T02:42:38","date_gmt":"2020-10-24T00:42:38","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/ustojchivoe-hranenie-dannyh-i-fajlovye-api-linux"},"modified":"2020-11-18T00:58:48","modified_gmt":"2020-11-17T22:58:48","slug":"ustojchivoe-hranenie-dannyh-i-fajlovye-api-linux","status":"publish","type":"post","link":"https:\/\/prohoster.info\/sl\/blog\/administrirovanie\/ustojchivoe-hranenie-dannyh-i-fajlovye-api-linux","title":{"rendered":"Vzdr\u017eljivo shranjevanje podatkov in datote\u010dni API-ji za Linux","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Pri raziskovanju vzdr\u017eljivosti shranjevanja podatkov v obla\u010dnih sistemih sem se odlo\u010dil preizkusiti samega sebe, da se prepri\u010dam, da razumem osnovne stvari. Jaz <noindex><a rel=\"nofollow\" href=\"https:\/\/www.evanjones.ca\/durability-nvme.html\">sem za\u010del z branjem specifikacije NVMe<\/a><\/noindex> , da bi se poglobil v to, katere garancije glede vzdr\u017eljivega shranjevanja podatkov (tj. garancije, da bodo podatki dostopni po sistemskem okvari) nam nudijo diski NVMe. Ugotovil sem naslednje klju\u010dne to\u010dke: treba je \u0161teti podatke za po\u0161kodovane od trenutka, ko je izdana ukaz za zapis podatkov, do trenutka, ko se kon\u010da njihov zapis na nosilec informacij. Vendar pa se v ve\u010dini programov za zapis podatkov mirno uporabljajo sistemski klici.<\/p>\n<p>V tem gradivu raziskujem mehanizme vzdr\u017eljivega shranjevanja podatkov, ki jih nudijo datote\u010dni API-ji za Linux. Zdi se, da bi moralo biti to preprosto: program izvede ukaz <code>write()<\/code>, in po tem, ko se ta ukaz zaklju\u010di, bi morali biti podatki zanesljivo shranjeni na disku. Vendar <code>write()<\/code> samo kopira podatke aplikacije v predpomnilnik jedra, ki se nahaja v pomnilniku. Da bi prisilili sistem k zapisovanju podatkov na disk, je potrebno uporabiti nekatere dodatne mehanizme.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/524172\/\"><img decoding=\"async\" alt=\"Vzdr\u017eljivo shranjevanje podatkov in datote\u010dni API-ji za Linux\" src=\"\/wp-content\/uploads\/2020\/10\/b974dcb9fc546cae03ade4f3d8f5dc25.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p>Na splo\u0161no to gradivo predstavlja zbirko opomb o tem, kar sem se nau\u010dil o meni zanimivem podro\u010dju. \u010ce zelo kratko povem najpomembnej\u0161e, je potrebno za organizacijo vzdr\u017eljivega shranjevanja podatkov uporabiti ukaz <code>fdatasync()<\/code> ali odpirati datoteke z zastavico <code>O_DSYNC<\/code>. \u010ce vas zanima podrobno, kaj se dogaja s podatki na poti od programske kode do diska, si oglejte <noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/457667\/\">to<\/a><\/noindex> \u010dlanek.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Posebnosti uporabe funkcije write()<\/h2>\n<p>\nSistemski klic <code>write()<\/code> je definiran v standardu <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/POSIX\">IEEE POSIX<\/a><\/noindex> kot poskus zapisa podatkov v datote\u010dni opisnik. Po uspe\u0161ni izvedbi <code>write()<\/code> operacije bi morale vrniti tiste bajte, ki so bili pred tem zapisani, tudi v primeru, da se podatkom dostopa iz drugih procesov ali niti (<noindex><a rel=\"nofollow\" href=\"https:\/\/pubs.opengroup.org\/onlinepubs\/9699919799\/functions\/write.html#tag_16_685_08\">tukaj je<\/a><\/noindex> ustrezni del standarda POSIX). <noindex><a rel=\"nofollow\" href=\"https:\/\/pubs.opengroup.org\/onlinepubs\/9699919799\/functions\/V2_chap02.html#tag_15_09_07\">Tukaj<\/a><\/noindex>, v razdelu, posve\u0107enom interakciji tokova s obi\u010dnim operacijama s datotekama, postoji napomena koja govori da ako svaki od dva toka poziva te funkcije, svaki poziv treba vidjeti ili sve ozna\u010dene posljedice koje proistje\u010du iz izvr\u0161enja drugog poziva, ili uop\u0107e nijednu posljedicu. To omogu\u0107uje zaklju\u010dak da sve operacije ulaza\/izlaza s datotekama trebaju zadr\u017eati zaklju\u010davanje resursa s kojim rade.<\/p>\n<p>Zna\u010di li to da je operacija <code>write()<\/code> atomarna? Tehni\u010dki gledano \u2014 da. Operacije \u010ditanja podataka trebaju vra\u0107ati ili sve ili ni\u0161ta od onoga \u0161to je bilo zapisano pomo\u0107u <code>write()<\/code>. No, operacija <code>write()<\/code>, prema standardu, ne mora nu\u017eno zavr\u0161iti zapisivanjem svega \u0161to je ponu\u0111eno za zapisivanje. Dozvoljeno joj je da izvr\u0161i zapisivanje samo dijela podataka. Na primjer, mogu\u0107a su dva toka, svaki od kojih pridru\u017euje 1024 bajta datoteci opisanoj istim datote\u010dnim deskriptorom. S aspekta standarda, prihvatljiv rezultat bi bio kada svaka od operacija zapisivanja mo\u017ee pridru\u017eiti datoteci samo po jedan bajt. Te operacije \u0107e ostati atomske, ali nakon \u0161to zavr\u0161e, podaci zapisani njima u datoteku bit \u0107e pomije\u0161ani. <noindex><a rel=\"nofollow\" href=\"https:\/\/stackoverflow.com\/a\/42442926\/413438\">Evo<\/a><\/noindex> vrlo zanimljive diskusije o ovoj temi na Stack Overflow.<\/p>\n<h2>Funkcije fsync() i fdatasync()<\/h2>\n<p>\nNajjednostavniji na\u010din za ispu\u0161tanje podataka na disk je poziv funkcije <noindex><a rel=\"nofollow\" href=\"https:\/\/man7.org\/linux\/man-pages\/man2\/fsync.2.html\">fsync()<\/a><\/noindex>. Ova funkcija tra\u017ei od operativnog sustava da prenese sve modificirane blokove iz predmemorije na disk. Tu su uklju\u010deni i svi metapodaci datoteke (vrijeme pristupa, vrijeme izmjene datoteke i tako dalje). Smatram da je potreba za tim metapodacima rijetka, stoga, ako znate da vam nisu va\u017eni, mo\u017eete koristiti funkciju <code>fdatasync()<\/code>. U <noindex><a rel=\"nofollow\" href=\"https:\/\/man7.org\/linux\/man-pages\/man2\/fdatasync.2.html\">pom\u0107i<\/a><\/noindex> o <code>fdatasync()<\/code> stoji da tijekom rada ove funkcije dolazi do spremanja na disk onog obujma metapodataka koji je \"neophodan za ispravno izvo\u0111enje sljede\u0107ih operacija \u010ditanja podataka\". A to je upravo ono \u0161to brine ve\u0107inu aplikacija.<\/p>\n<p>Jedan od problema koji ovdje mo\u017ee nastati je to da ti mehanizmi ne jam\u010de da \u0107e se datoteka mo\u0107i otkriti nakon mogu\u0107eg kvara. Konkretno, kada se stvara nova datoteka, potrebno je pozvati <code>fsync()<\/code> za mapu, koja ga sadr\u017ei. Ina\u010de, nakon kvara mo\u017ee se dogoditi da taj fajl ne postoji. Razlog tome je u tome \u0161to u UNIX-u, zbog kori\u0161\u0107enja tvrdih linkova, fajl mo\u017ee postojati u vi\u0161e mapa. Stoga prilikom poziva <code>fsync()<\/code> fajl nema na\u010dina da sazna iz koje ta\u010dno mape tako\u0111e treba prebaciti na disk (<noindex><a rel=\"nofollow\" href=\"https:\/\/www.quora.com\/When-should-you-fsync-the-containing-directory-in-addition-to-the-file-itself\">tukaj<\/a><\/noindex> o tome se mo\u017ee vi\u0161e pro\u010ditati). \u010cini se da datote\u010dni sistem ext4 mo\u017ee <noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/799807\/\">automatski<\/a><\/noindex> primenjivati <code>fsync()<\/code> na direktorijume koji sadr\u017ee odgovaraju\u0107e fajlove, ali u slu\u010daju drugih datote\u010dnih sistema to mo\u017eda nije slu\u010daj.<\/p>\n<p>Omekani mehanizam mo\u017ee biti razli\u010dito implementiran u razli\u010ditim datote\u010dnim sistemima. Koristio sam <noindex><a rel=\"nofollow\" href=\"https:\/\/git.kernel.org\/pub\/scm\/linux\/kernel\/git\/axboe\/blktrace.git\/tree\/README\">blktrace<\/a><\/noindex> da bih saznao koje se diskovne operacije koriste u datote\u010dnim sistemima ext4 i XFS. Obe izbacuju standardne komande za upis na disk i za sadr\u017eaj fajlova i za dnevnik datote\u010dnog sistema, prebacuju ke\u0161 i zavr\u0161avaju rad, izvr\u0161avaju\u0107i FUA-upis (Force Unit Access, upis podataka direktno na disk, presko\u010div\u0161i ke\u0161) u dnevnik. Verovatno to rade upravo da bi potvrdili \u010dinjenicu izvr\u0161enja operacije. Na diskovima koji ne podr\u017eavaju FUA, to izaziva dva prebacivanja ke\u0161a. Moji eksperimenti su pokazali da <code>fdatasync()<\/code> pomalo br\u017ee <code>fsync()<\/code>. Alat <code>blktrace<\/code> ukazuje na to da <code>fdatasync()<\/code> obi\u010dno pi\u0161e na disk manje podataka (u ext4 <code>fsync()<\/code> zapisuje 20 KiB, a <code>fdatasync()<\/code> \u2014 16 KiB). Pored toga, otkrio sam da je XFS malo br\u017ei od ext4. A ovde je uz pomo\u0107 <code>blktrace<\/code> uspeo da sazna da <code>fdatasync()<\/code> prebacuje na disk manje podataka (4 KiB u XFS).<\/p>\n<h2>Nejasne situacije koje nastaju prilikom kori\u0161\u0107enja fsync()<\/h2>\n<p>\nMogu se setiti tri nejasne situacije koje se ti\u010du <code>fsync()<\/code>, s kojima sam se susreo u praksi.<\/p>\n<p>Prvi takav slu\u010daj dogodio se 2008. godine. Tada je interfejs Firefox 3 \u201ezabrzavao\u201c kada je vr\u0161ena upisivanje na disk velikog broja fajlova. Problem je bio u tome \u0161to je u implementaciji interfejsa za skladi\u0161tenje podataka o svom stanju kori\u0161\u0107ena baza podataka SQLite. Nakon svake promene koja se dogodila u interfejsu, pozivana je funkcija <code>fsync()<\/code>, \u0161to je davalo dobre garancije stabilnog skladi\u0161tenja podataka. U upotrebljenom datote\u010dnom sistemu ext3 funkcija <code>fsync()<\/code> sistemaga barcha \"iflos\" sahifalarni diskka qaytarardi, faqat tegishli faylga aloqador bo'lganlarini emas. Bu shuni anglatadiki, Firefox-da tugmani bosish diskda megabayt ma'lumotlarni yozishni boshlashi mumkin edi, bu esa ko'p soniyalarni olishi mumkin. Muammoni hal qilish, men tushunganimdek, <noindex><a rel=\"nofollow\" href=\"http:\/\/shaver.off.net\/diary\/2008\/05\/25\/fsyncers-and-curveballs\/\">tega<\/a><\/noindex> ma'lumotni asinxron fon vazifalariga ko'chirishda edi. Bu Firefox dastlab ma'lumotlarni saqlashda yanada qattiq talablarni qabul qilganligini anglatadi, buning esa aslida zaruriyati yo'q edi, va ext3 fayl tizimining xususiyatlari bu muammoni yanada kuchaytirgan.<\/p>\n<p>Ikkinchi muammo 2009 yilda yuz berdi. Shunda, tizimning muvaffaqiyatsizligi sababli, ext4 fayl tizimidan foydalanuvchilar ko'p yangi yaratilgan fayllarning nol uzunlikka ega ekanini ko'rishdi, eski ext3 fayl tizimi bilan bunday holat yuz bermadi. Oldingi bo'limda men ext3 diskga juda ko'p ma'lumotlarni qaytarganligini aytgan edim, bu esa ishlashni sekinlashtirardi. <code>fsync()<\/code>Muammolarni yaxshilash uchun ext4da diskka faqat ma'lum faylga aloqador \"iflos\" sahifalar qaytariladi. Boshqa fayllar ma'lumotlari ext3ga nisbatan ancha uzoq vaqt davomida xotirada qoladi. Bu ish samaradorligini oshirish uchun amalga oshirildi (odatda ma'lumotlar bunday holatda 30 soniya qoladi, buni <noindex><a rel=\"nofollow\" href=\"https:\/\/www.kernel.org\/doc\/Documentation\/sysctl\/vm.txt\">dirty_expire_centisecs<\/a><\/noindex>; <noindex><a rel=\"nofollow\" href=\"https:\/\/www.spinics.net\/lists\/linux-ext4\/msg68941.html\">tukaj<\/a><\/noindex> bilan o'zgartirish mumkin). Bu esa ma'lumotlar kattaroq hajmda bir necha marta yo'qolishi mumkinligini anglatadi. Ushbu muammoni hal qilish uchun <code>fsync()<\/code> ma'lumotlarni doimiy saqlash va ularni muvaffaqiyatsizliklardan maksimal darajada himoya qilish zarur bo'lgan dasturlarda qo'llaniladi. Ushbu <code>fsync()<\/code> ext4da farq qiladi ext3ga qaraganda. Bunday yondashuvning kamchiligi shundaki, bu kabi yondashuv, avvalgi kabi, ba'zi operatsiyalarni sekinlashtiradi, masalan, dasturlarni o'rnatish. Buni batafsil ko'ring <noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/322823\/\">ovde<\/a><\/noindex> in <noindex><a rel=\"nofollow\" href=\"https:\/\/thunk.org\/tytso\/blog\/2009\/03\/12\/delayed-allocation-and-the-zero-length-file-problem\/\">ovde<\/a><\/noindex>.<\/p>\n<p>Uchinchi muammo, <code>fsync()<\/code>, 2018 yilda yuz berdi. Shunda, PostgreSQL loyihasi doirasida, agar <code>fsync()<\/code> xato yuzaga kelsa, u \"iflos\" sahifalarni \"toza\" deb belgilashini aniqladi. Natijada keyingi chaqiruvlar <code>fsync()<\/code> ni\u010d s takimi stranmi ne delajo. Zaradi tega se spremenjene strani shranjujejo v pomnilniku in nikoli ne zapi\u0161ejo na disk. To je prava katastrofa, saj bo aplikacija mislila, da so nekateri podatki zapisani na disk, v resnici pa ne bodo. Tak\u0161ne napake <code>fsync()<\/code> redko pridejo do izraza, aplikacija v tak\u0161nih situacijah skoraj nima mo\u017enosti za re\u0161evanje te\u017eave. Danes, ko to pride do izraza, PostgreSQL in druge aplikacije nenadoma prenehajo delovati. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.usenix.org\/conference\/atc20\/presentation\/rebello\">Tukaj<\/a><\/noindex>, v \u010dlanku \u201eAli se aplikacije lahko obnovijo po napakah fsync?\u201c, je ta problem podrobno raziskan. Trenutno je najbolj\u0161a re\u0161itev tega problema uporaba Direct I\/O s parametrom <code>O_SYNC<\/code> ali s parametrom <code>O_DSYNC<\/code>. S takim pristopom bo sistem poro\u010dal o napakah, ki se lahko pojavijo pri izvajanju specifi\u010dnih zapisovalnih operacij, a ta pristop zahteva, da aplikacija sama upravlja z oblogami. Podrobnosti o tem preberite <noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/752063\/\">ovde<\/a><\/noindex> in <noindex><a rel=\"nofollow\" href=\"https:\/\/wiki.postgresql.org\/wiki\/Fsync_Errors\">ovde<\/a><\/noindex>.<\/p>\n<h2>Odprite datoteke z uporabo parametrov O_SYNC in O_DSYNC<\/h2>\n<p>\nVrnimo se k razpravi o mehanizmih Linuxa, ki zagotavljajo zanesljivo shranjevanje podatkov. To pomeni uporabo parametra <code>O_SYNC<\/code> ali parametra <code>O_DSYNC<\/code> pri odpiranju datotek z uporabo sistemskega klica <noindex><a rel=\"nofollow\" href=\"https:\/\/man7.org\/linux\/man-pages\/man2\/open.2.html\">open()<\/a><\/noindex>. S takim pristopom se vsaka zapisovalna operacija izvaja tako, kot da po vsaki ukaz <code>write()<\/code> sistemu daje, ustrezno, ukaze <code>fsync()<\/code> in <code>fdatasync()<\/code>. U <noindex><a rel=\"nofollow\" href=\"https:\/\/pubs.opengroup.org\/onlinepubs\/009695399\/basedefs\/xbd_chap03.html#tag_03_373\">specifikacije POSIX<\/a><\/noindex> to se imenuje \u201eSynchronized I\/O File Integrity Completion\u201c in \u201eData Integrity Completion\u201c. Glavna prednost tak\u0161nega pristopa je, da je za zagotavljanje celovitosti podatkov potrebno izvesti le en sistemski klic, ne pa dveh (na primer - <code>write()<\/code> in <code>fdatasync()<\/code>). Glavna slabost tega pristopa pa je, da bodo vse zapisovalne operacije, ki uporabljajo ustrezen opis datoteke, sinhronizirane, kar lahko omeji mo\u017enosti strukturiranja kode aplikacije.<\/p>\n<h2>Uporaba Direct I\/O s parametrom O_DIRECT<\/h2>\n<p>\nSistemski klic <code>open()<\/code> podpira parameter <code>O_DIRECT<\/code>, ki je zasnovan tako, da zaobide predpomnilnik operacijskega sistema in izvaja vhodno-izhodne operacije, ki neposredno komunicirajo z diskom. To v mnogih primerih pomeni, da se zapisni ukazi, ki jih izda program, neposredno pretvarjajo v ukaze, usmerjene na delo z diskom. A na splo\u0161no ta mehanizem ni zamenjava funkcij <code>fsync()<\/code> ili <code>fdatasync()<\/code>. Gre za to, da sam disk lahko <noindex><a rel=\"nofollow\" href=\"https:\/\/www.evanjones.ca\/durability-nvme.html\">odlo\u017eiti ili ke\u0161irati<\/a><\/noindex> odgovaraju\u0107e komande za zapis podataka. I, \u0161to je jo\u0161 gore, u nekim posebnim slu\u010dajevima operacije ulaza-izlaza, izvr\u0161ene kori\u0161\u0107enjem zastavice <code>O_DIRECT<\/code>, <noindex><a rel=\"nofollow\" href=\"https:\/\/ext4.wiki.kernel.org\/index.php\/Clarifying_Direct_IO%27s_Semantics\">se prenose<\/a><\/noindex> u tradicionalne baferisane operacije. Najlak\u0161e je re\u0161iti ovaj problem koriste\u0107i dodatnu zastavicu prilikom otvaranja fajlova <code>O_DSYNC<\/code>, \u0161to \u0107e zna\u010diti da \u0107e nakon svake operacije zapisa uslediti poziv <code>fdatasync()<\/code>.<\/p>\n<p>Ispostavilo se da je u XFS fajl sistemu nedavno dodat \"brzi put\" za <code>O_DIRECT|O_DSYNC<\/code>-zapis podataka. Ako prepisuju blok koriste\u0107i <code>O_DIRECT|O_DSYNC<\/code>, onda \u0107e XFS, umesto ispu\u0161tanja ke\u0161a, izvr\u0161iti FUA-zapis komandnog poziva ako ure\u0111aj to podr\u017eava. To sam potvrdio koriste\u0107i alat <code>blktrace<\/code> u Linuxu 5.4\/Ubuntu 20.04. Ovaj pristup bi trebao biti efikasniji, jer se pri njegovoj primeni na disk upisuje minimalna koli\u010dina podataka i koristi se jedna operacija, a ne dve (upis i ispu\u0161tanje ke\u0161a). Na\u0161ao sam link na <noindex><a rel=\"nofollow\" href=\"https:\/\/patchwork.kernel.org\/patch\/10250257\/\">zakrpu<\/a><\/noindex> jezgra iz 2018. godine, u kojem je implementiran ovaj mehanizam. Tu se vodi rasprava koja se ti\u010de primene ove optimizacije i u drugim fajl sistemima, ali koliko ja znam, XFS je za sada jedini fajl sistem koji to podr\u017eava.<\/p>\n<h2>Funkcija sync_file_range()<\/h2>\n<p>\nU Linuxu postoji sistemski poziv <noindex><a rel=\"nofollow\" href=\"https:\/\/man7.org\/linux\/man-pages\/man2\/sync_file_range.2.html\">sync_file_range()<\/a><\/noindex>, koji omogu\u0107ava ispu\u0161tanje na disk samo dela fajla, a ne celog fajla. Ovaj poziv inicira asinhrono ispu\u0161tanje podataka i ne \u010deka njegovo zavr\u0161avanje. Me\u0111utim, u uputstvu za <code>sync_file_range()<\/code> se navodi da je ova komanda \"veoma opasna\". Njena upotreba se ne preporu\u010duje. Osobine i opasnosti <code>sync_file_range()<\/code> veoma dobro su opisane u <noindex><a rel=\"nofollow\" href=\"http:\/\/yoshinorimatsunobu.blogspot.com\/2014\/03\/how-syncfilerange-really-works.html\">ovom<\/a><\/noindex> materijalu. Konkretno, o\u010digledno je da ovaj poziv koristi RocksDB za upravljanje vremenom kada jezgro ispu\u0161ta \"prljave\" podatke na disk. Ali pritom se koristi i <code>fdatasync()<\/code>. U <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/facebook\/rocksdb\/search?q=sync_file_range\">kodu<\/a><\/noindex> RocksDB postoje zanimljivi komentari o ovoj temi. Na primer, \u010dini se da poziv <code>sync_file_range()<\/code> prilikom kori\u0161\u0107enja ZFS ne dovodi do ispu\u0161tanja podataka na disk. Iskustvo mi sugerira da kod koji se retko koristi mo\u017ee sadr\u017eati gre\u0161ke. Zbog toga bih preporu\u010dio da se ovaj sistemski poziv ne koristi bez velike potrebe.<\/p>\n<h2>Sistemski pozivi koji poma\u017eu u obezbe\u0111ivanju trajnog skladi\u0161tenja podataka<\/h2>\n<p>\nPri\u0161el sem do zaklju\u010dka, da je za izvajanje vhodno\/izhodnih operacij, ki zagotavljajo trajno shranjevanje podatkov, mogo\u010de uporabiti tri pristope. Vsi zahtevajo klic funkcije <code>fsync()<\/code> za direktorij, v katerem je bila ustvarjena datoteka. Tukaj so ti pristopi:<\/p>\n<ol>\n<li>Klic funkcije <code>fdatasync()<\/code> ili <code>fsync()<\/code> po funkciji <code>write()<\/code> (bolje je uporabiti <code>fdatasync()<\/code>).<\/li>\n<li>Delo s pripomo\u010dkom za datoteke, odprtim s zastavico <code>O_DSYNC<\/code> ili <code>O_SYNC<\/code> (bolje \u2014 z zastavico <code>O_DSYNC<\/code>).<\/li>\n<li>Uporaba ukaza <code>pwritev2()<\/code> z zastavico <code>RWF_DSYNC<\/code> ili <code>RWF_SYNC<\/code> (prednostno \u2014 z zastavico <code>RWF_DSYNC<\/code>).<\/li>\n<\/ol>\n<p><\/p>\n<h2>Opombe o zmogljivosti<\/h2>\n<p>\nNisem se ukvarjal s temeljitim merjenjem zmogljivosti razli\u010dnih mehanizmov, ki sem jih raziskal. Opazne razlike v hitrosti njihovega delovanja so precej majhne. To pomeni, da bi se lahko motil, in da bi v drugih pogojih lahko isti mehanizmi pokazali druga\u010dne rezultate. Najprej bom govoril o tem, kar mo\u010dneje vpliva na zmogljivost, nato pa o tistem, kar na zmogljivost vpliva manj.<\/p>\n<ol>\n<li>Prepisovanje podatkov datoteke je hitrej\u0161e kot dodajanje podatkov k datoteki (prihranek v zmogljivosti je lahko od 2 do 100%). Dodajanje podatkov datoteki zahteva dodatne spremembe v metapodatkih datoteke, celo po sistemskem klicu <code>fallocate()<\/code>, a obseg tega u\u010dinka se lahko spreminja. Priporo\u010dam, da za zagotovitev najbolj\u0161e zmogljivosti, pokli\u010dete <code>fallocate()<\/code> za predhodno dodelitev potrebnega prostora. Nato je treba ta prostor izrecno napolniti z ni\u010dlami in poklicati <code>fsync()<\/code>. S tem bodo ustrezni bloki v datote\u010dnem sistemu ozna\u010deni kot 'dodeljeni', ne kot 'nedodeljeni'. To prina\u0161a majhno (pribli\u017eno 2%) izbolj\u0161anje zmogljivosti. Poleg tega lahko nekateri diski upo\u010dasnijo prvo operacijo dostopa do bloka v primerjavi z drugimi. To pomeni, da lahko polnjenje prostora z ni\u010dlami privede do znatnega (pribli\u017eno 100%) izbolj\u0161anja zmogljivosti. \u0160e posebej se to lahko zgodi pri diskih <noindex><a rel=\"nofollow\" href=\"https:\/\/n2ws.com\/blog\/how-to-guides\/pre-warm-ebs-volumes-on-aws\">AWS EBS<\/a><\/noindex> (to so neuradni podatki, ki jih nisem mogel potrditi). Enako velja za shrambe <noindex><a rel=\"nofollow\" href=\"https:\/\/cloud.google.com\/compute\/docs\/disks\/benchmarking-pd-performance\">GCP Persistent Disk<\/a><\/noindex> (in to so \u017ee uradne informacije, potrjene s testi). Drugi strokovnjaki so opazili enake <noindex><a rel=\"nofollow\" href=\"http:\/\/yoshinorimatsunobu.blogspot.com\/2009\/05\/overwriting-is-much-faster-than_28.html\">opazovanja<\/a><\/noindex>, ki se nana\u0161ajo na razli\u010dne diske.<\/li>\n<li>Manj kot je sistemskih klicev \u2014 vi\u0161ja je zmogljivost (prihranek zna\u0161a pribli\u017eno 5%). Zdi se, da je klic <code>open()<\/code> z zastavico <code>O_DSYNC<\/code> ali klic <code>pwritev2()<\/code> z zastavico <code>RWF_SYNC<\/code> br\u017eji klic <code>fdatasync()<\/code>. Sumim, da je razlog v tem, da pri tak\u0161nem pristopu igra vlogo to, da za re\u0161evanje iste naloge opravimo manj sistemskih klicev (en klic namesto dveh). A razlika v zmogljivosti je zelo majhna, zato se lahko nanjo povsem ne ozrete in v aplikaciji uporabite tisto, kar ne bo povzro\u010dilo zapletov v njeni logiki.<\/li>\n<\/ol>\n<p>\n\u010ce vas zanima tema trajne shrambe podatkov \u2014 tukaj je nekaj koristnih gradiv:<\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.scylladb.com\/2017\/10\/05\/io-access-methods-scylla\/\">I\/O metode dostopa<\/a><\/noindex> \u2014 pregled osnovnih mehanizmov vnosa\/izhoda.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/457667\/\">Zagotavljanje, da podatki dose\u017eejo disk<\/a><\/noindex> \u2014 pripoved o tem, kaj se zgodi s podatki na poti od aplikacije do diska.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.quora.com\/When-should-you-fsync-the-containing-directory-in-addition-to-the-file-itself\">Kdaj naj uporabite fsync v vsebniku imenika<\/a><\/noindex> \u2014 odgovor na vpra\u0161anje, kdaj je treba uporabiti <code>fsync()<\/code> za imenike. \u010ce to povzamemo v dveh besedah, lahko re\u010demo, da je treba to narediti pri ustvarjanju nove datoteke, razlog za to priporo\u010dilo pa je, da je v Linuxu lahko veliko povezav do iste datoteke.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/bobsql.com\/sql-server-on-linux-forced-unit-access-fua-internals\/\">SQL Server na Linuxu: Notranjost FUA<\/a><\/noindex> \u2014 tukaj je opisana implementacija trajne shrambe podatkov v SQL Serverju na platformi Linux. Tu so predstavljene nekatere zanimive primerjave med sistemskimi klici Windows in Linux. Skoraj sem prepri\u010dan, da sem prav preko tega gradiva izvedel za optimizacijo FUA v XFS.<\/li>\n<\/ul>\n<p>\nSte kdaj izgubili podatke, za katere ste menili, da so zanesljivo shranjeni na disku?<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"http:\/\/ruvds.com\/ru-rub?utm_source=habr&amp;utm_medium=article&amp;utm_campaign=perevod&amp;utm_content=ustojchivoe_xranenie_dannyx_i_fajlovye_api_linux#order\"><img decoding=\"async\" alt=\"Vzdr\u017eljivo shranjevanje podatkov in datote\u010dni API-ji za Linux\" src=\"\/wp-content\/uploads\/2020\/10\/8bea3fc2b65a5a683655d9c15e153c93.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"http:\/\/ruvds.com\/ru-rub\/news\/read\/123?utm_source=habr&amp;utm_medium=article&amp;utm_campaign=perevod&amp;utm_content=ustojchivoe_xranenie_dannyx_i_fajlovye_api_linux\"><img decoding=\"async\" alt=\"Vzdr\u017eljivo shranjevanje podatkov in datote\u010dni API-ji za Linux\" src=\"\/wp-content\/uploads\/2020\/10\/d9fd0b1c09eb6e40944aee2d13ee4088.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<br \/>Izvor: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/524172\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u042f, \u0438\u0441\u0441\u043b\u0435\u0434\u0443\u044f \u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445, \u0440\u0435\u0448\u0438\u043b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u0435\u0431\u044f, \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u044e \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0432\u0435\u0449\u0438. \u042f \u043d\u0430\u0447\u0430\u043b \u0441 \u0447\u0442\u0435\u043d\u0438\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 NVMe \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0441 \u0442\u0435\u043c, \u043a\u0430\u043a\u0438\u0435 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0438, \u043a\u0430\u0441\u0430\u044e\u0449\u0438\u0435\u0441\u044f \u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 (\u0442\u043e \u0435\u0441\u0442\u044c \u2014 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0438 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u043f\u043e\u0441\u043b\u0435 \u0441\u0431\u043e\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u044b), \u0434\u0430\u044e\u0442 \u043d\u0430\u043c NMVe-\u0434\u0438\u0441\u043a\u0438. \u042f \u0441\u0434\u0435\u043b\u0430\u043b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":98091,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-98090","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.4 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u042f, \u0438\u0441\u0441\u043b\u0435\u0434\u0443\u044f \u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445, \u0440\u0435\u0448\u0438\u043b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u0435\u0431\u044f, \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u044e \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0432\u0435\u0449\u0438.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/sl\/blog\/administrirovanie\/ustojchivoe-hranenie-dannyh-i-fajlovye-api-linux\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"sl_SI\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0423\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0435 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0444\u0430\u0439\u043b\u043e\u0432\u044b\u0435 API Linux | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u042f, \u0438\u0441\u0441\u043b\u0435\u0434\u0443\u044f \u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445, \u0440\u0435\u0448\u0438\u043b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u0435\u0431\u044f, \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u044e \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0432\u0435\u0449\u0438.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/sl\/blog\/administrirovanie\/ustojchivoe-hranenie-dannyh-i-fajlovye-api-linux\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-10-24T00:42:38+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-11-17T22:58:48+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Trajna shramba podatkov in datote\u010dni API-ji Linux | ProHoster","description":"Med preu\u010devanjem trajne shrambe podatkov v obla\u010dnih sistemih sem se odlo\u010dil, da se preizkusim in prepri\u010dam, da razumem osnovne stvari.","canonical_url":"https:\/\/prohoster.info\/sl\/blog\/administrirovanie\/ustojchivoe-hranenie-dannyh-i-fajlovye-api-linux","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sl_SI","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0423\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0435 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0444\u0430\u0439\u043b\u043e\u0432\u044b\u0435 API Linux | ProHoster","og:description":"\u042f, \u0438\u0441\u0441\u043b\u0435\u0434\u0443\u044f \u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445, \u0440\u0435\u0448\u0438\u043b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u0435\u0431\u044f, \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u044e \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0432\u0435\u0449\u0438.","og:url":"https:\/\/prohoster.info\/sl\/blog\/administrirovanie\/ustojchivoe-hranenie-dannyh-i-fajlovye-api-linux","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-10-24T00:42:38+00:00","article:modified_time":"2020-11-17T22:58:48+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"98090","title":null,"description":null,"keywords":null,"keyphrases":{"focus":[],"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 10:05:49","updated":"2026-08-11 12:50:05","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/posts\/98090","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/comments?post=98090"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/posts\/98090\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/media\/98091"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/media?parent=98090"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/categories?post=98090"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/tags?post=98090"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}