{"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\/pl\/blog\/administrirovanie\/ustojchivoe-hranenie-dannyh-i-fajlovye-api-linux","title":{"rendered":"Trwa\u0142e przechowywanie danych i interfejsy API plik\u00f3w w systemie Linux","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Badaj\u0105c niezawodno\u015b\u0107 przechowywania danych w systemach chmurowych, postanowi\u0142em sprawdzi\u0107 swoje umiej\u0119tno\u015bci i upewni\u0107 si\u0119, \u017ce rozumiem podstawowe zagadnienia. Ja <noindex><a rel=\"nofollow\" href=\"https:\/\/www.evanjones.ca\/durability-nvme.html\">zacz\u0105\u0142em od przeczytania specyfikacji NVMe<\/a><\/noindex> aby zrozumie\u0107, jakie gwarancje dotycz\u0105ce niezawodnego przechowywania danych (to znaczy \u2014 gwarancje, \u017ce dane b\u0119d\u0105 dost\u0119pne po awarii systemu) oferuj\u0105 nam dyski NVMe. Oto moje g\u0142\u00f3wne wnioski: nale\u017cy uzna\u0107 dane za uszkodzone w momencie, gdy zostanie wydane polecenie zapisania danych, a\u017c do momentu, gdy zako\u0144czony zostanie zapis na no\u015bniku informacji. Jednak w wi\u0119kszo\u015bci program\u00f3w do zapisu danych bez obaw u\u017cywa si\u0119 wywo\u0142a\u0144 systemowych.<\/p>\n<p>W tym artykule badam mechanizmy niezawodnego przechowywania danych oferowane przez API plik\u00f3w w systemie Linux. Wydaje si\u0119, \u017ce wszystko powinno by\u0107 proste: program wywo\u0142uje polecenie <code>write()<\/code>, a po zako\u0144czeniu dzia\u0142ania tej komendy, dane powinny by\u0107 niezawodnie zapisane na dysku. Ale <code>write()<\/code> jedynie kopiuje dane aplikacji do cache'u j\u0105dra znajduj\u0105cego si\u0119 w pami\u0119ci operacyjnej. Aby wymusi\u0107 na systemie zapis danych na dysku, nale\u017cy u\u017cy\u0107 dodatkowych mechanizm\u00f3w.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/524172\/\"><img decoding=\"async\" alt=\"Trwa\u0142e przechowywanie danych i interfejsy API plik\u00f3w w systemie Linux\" src=\"\/wp-content\/uploads\/2020\/10\/b974dcb9fc546cae03ade4f3d8f5dc25.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p>Og\u00f3lnie rzecz bior\u0105c, ten materia\u0142 stanowi zbi\u00f3r notatek na temat tego, co dowiedzia\u0142em si\u0119 w interesuj\u0105cej mnie dziedzinie. Je\u015bli bardzo skr\u00f3towo opisa\u0107 najwa\u017cniejsze informacje, to okazuje si\u0119, \u017ce do organizacji niezawodnego przechowywania danych nale\u017cy u\u017cywa\u0107 komendy <code>fdatasync()<\/code> lub otwiera\u0107 pliki z flag\u0105 <code>O_DSYNC<\/code>. Je\u015bli chcesz szczeg\u00f3\u0142owo dowiedzie\u0107 si\u0119, co si\u0119 dzieje z danymi w trakcie ich drogi od kodu programu do dysku, zerknij na <noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/457667\/\">tego<\/a><\/noindex> artyku\u0142.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Cechy u\u017cycia funkcji write()<\/h2>\n<p>\nWywo\u0142anie systemowe <code>write()<\/code> jest zdefiniowane w standardzie <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/POSIX\">IEEE POSIX<\/a><\/noindex> jako pr\u00f3ba zapisu danych do deskryptora pliku. Po pomy\u015blnym zako\u0144czeniu operacji <code>write()<\/code> operacje odczytu danych powinny zwraca\u0107 dok\u0142adnie te bajty, kt\u00f3re wcze\u015bniej zosta\u0142y zapisane, nawet w przypadku, gdy do danych uzyskuj\u0105 dost\u0119p inne procesy lub w\u0105tki (<noindex><a rel=\"nofollow\" href=\"https:\/\/pubs.opengroup.org\/onlinepubs\/9699919799\/functions\/write.html#tag_16_685_08\">oto<\/a><\/noindex> odpowiedni rozdzia\u0142 standardu POSIX). <noindex><a rel=\"nofollow\" href=\"https:\/\/pubs.opengroup.org\/onlinepubs\/9699919799\/functions\/V2_chap02.html#tag_15_09_07\">Tutaj<\/a><\/noindex>, w sekcji po\u015bwi\u0119conej interakcji strumieni z typowymi operacjami plikowymi, znajduje si\u0119 uwaga, kt\u00f3ra wskazuje, \u017ce je\u015bli ka\u017cdy z dw\u00f3ch strumieni wywo\u0142uje te funkcje, to ka\u017cde wywo\u0142anie powinno widzie\u0107 albo wszystkie okre\u015blone konsekwencje wynikaj\u0105ce z wykonania innego wywo\u0142ania, albo w og\u00f3le \u017cadnych konsekwencji. To pozwala wyci\u0105gn\u0105\u0107 wniosek, \u017ce wszystkie operacje plikowe wej\u015bcia\/wyj\u015bcia musz\u0105 utrzymywa\u0107 blokad\u0119 zasobu, z kt\u00f3rym pracuj\u0105.<\/p>\n<p>Czy oznacza to, \u017ce operacja <code>write()<\/code> jest atomowa? Technicznie \u2014 tak. Operacje odczytu danych powinny zwraca\u0107 albo wszystko, albo nic z tego, co zosta\u0142o zapisane za pomoc\u0105 <code>write()<\/code>. Jednak operacja <code>write()<\/code>, zgodnie ze standardem, nie musi koniecznie ko\u0144czy\u0107 si\u0119 zapisaniem wszystkiego, co zosta\u0142a poproszona o zapisanie. Mo\u017ce wykona\u0107 zapis tylko cz\u0119\u015bci danych. Na przyk\u0142ad, mamy dwa strumienie, z kt\u00f3rych ka\u017cdy do\u0142\u0105cza 1024 bajty do pliku opisanego tym samym deskryptorem pliku. Z punktu widzenia standardu akceptowalnym wynikiem b\u0119dzie sytuacja, w kt\u00f3rej ka\u017cda z operacji zapisu mo\u017ce do\u0142\u0105czy\u0107 do pliku tylko po jednym bajcie. Operacje te pozostan\u0105 atomowe, ale po ich zako\u0144czeniu dane zapisane przez nie w pliku b\u0119d\u0105 pomieszane. <noindex><a rel=\"nofollow\" href=\"https:\/\/stackoverflow.com\/a\/42442926\/413438\">Oto<\/a><\/noindex> bardzo interesuj\u0105ca dyskusja na ten temat na Stack Overflow.<\/p>\n<h2>Funkcje fsync() i fdatasync()<\/h2>\n<p>\nNajprostszym sposobem na zrzut danych na dysk jest wywo\u0142anie funkcji <noindex><a rel=\"nofollow\" href=\"https:\/\/man7.org\/linux\/man-pages\/man2\/fsync.2.html\">fsync()<\/a><\/noindex>. Ta funkcja \u017c\u0105da od systemu operacyjnego przeniesienia wszystkich zmodyfikowanych blok\u00f3w z cache na dysk. Obejmuje to tak\u017ce wszystkie metadane pliku (czas dost\u0119pu, czas modyfikacji pliku itd.). Uwa\u017cam, \u017ce potrzeba tych metadanych wyst\u0119puje rzadko, wi\u0119c je\u015bli wiesz, \u017ce nie s\u0105 dla ciebie istotne, mo\u017cesz korzysta\u0107 z funkcji <code>fdatasync()<\/code>. W <noindex><a rel=\"nofollow\" href=\"https:\/\/man7.org\/linux\/man-pages\/man2\/fdatasync.2.html\">pomocy<\/a><\/noindex> w <code>fdatasync()<\/code> , m\u00f3wi si\u0119, \u017ce w trakcie pracy tej funkcji zapisywany jest na dysk taki wolumen metadanych, kt\u00f3ry \u201ejest niezb\u0119dny do poprawnego wykonania nast\u0119pnych operacji odczytu danych\u201d. A to jest dok\u0142adnie to, co interesuje wi\u0119kszo\u015b\u0107 aplikacji.<\/p>\n<p>Jednym z problem\u00f3w, kt\u00f3ry mo\u017ce si\u0119 pojawi\u0107, jest to, \u017ce te mechanizmy nie gwarantuj\u0105, \u017ce plik b\u0119dzie mo\u017cliwy do odnalezienia po ewentualnej awarii. W szczeg\u00f3lno\u015bci, gdy tworzy si\u0119 nowy plik, nale\u017cy wywo\u0142a\u0107 <code>fsync()<\/code> dla katalogu, kt\u00f3ry go zawiera. W przeciwnym razie po awarii mo\u017ce okaza\u0107 si\u0119, \u017ce ten plik nie istnieje. Pow\u00f3d tego tkwi w tym, \u017ce w UNIX-ie, z powodu stosowania twardych dowi\u0105za\u0144, plik mo\u017ce istnie\u0107 w kilku katalogach. Dlatego przy wywo\u0142aniu <code>fsync()<\/code> dla pliku nie ma sposobu, aby dowiedzie\u0107 si\u0119, jakie dok\u0142adnie dane z tego katalogu r\u00f3wnie\u017c nale\u017cy zrzuci\u0107 na dysk (<noindex><a rel=\"nofollow\" href=\"https:\/\/www.quora.com\/When-should-you-fsync-the-containing-directory-in-addition-to-the-file-itself\">tutaj<\/a><\/noindex> mo\u017cna o tym poczyta\u0107 wi\u0119cej). Wydaje si\u0119, \u017ce system plik\u00f3w ext4 jest w stanie <noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/799807\/\">automatycznie<\/a><\/noindex> stosowa\u0107 <code>fsync()<\/code> do katalog\u00f3w, kt\u00f3re zawieraj\u0105 odpowiednie pliki, ale w przypadku innych system\u00f3w plik\u00f3w mo\u017ce by\u0107 inaczej.<\/p>\n<p>Ten mechanizm mo\u017ce by\u0107 r\u00f3\u017cnie wdra\u017cany w r\u00f3\u017cnych systemach plik\u00f3w. U\u017cy\u0142em <noindex><a rel=\"nofollow\" href=\"https:\/\/git.kernel.org\/pub\/scm\/linux\/kernel\/git\/axboe\/blktrace.git\/tree\/README\">blktrace<\/a><\/noindex> aby dowiedzie\u0107 si\u0119, jakie operacje dyskowe s\u0105 stosowane w systemach plik\u00f3w ext4 i XFS. Oba systemy wydaj\u0105 standardowe polecenia zapisu na dysk zar\u00f3wno dla zawarto\u015bci plik\u00f3w, jak i dla dziennika systemu plik\u00f3w, zrzucaj\u0105 pami\u0119\u0107 podr\u0119czn\u0105 i ko\u0144cz\u0105 dzia\u0142anie, wykonuj\u0105c zapis FUA (Force Unit Access, zapis danych bezpo\u015brednio na dysk, pomijaj\u0105c pami\u0119\u0107 podr\u0119czn\u0105) w dzienniku. Prawdopodobnie robi\u0105 to, aby potwierdzi\u0107 wykonanie operacji. Na dyskach, kt\u00f3re nie wspieraj\u0105 FUA, powoduje to dwa zrzuty pami\u0119ci podr\u0119cznej. Moje eksperymenty wykaza\u0142y, \u017ce <code>fdatasync()<\/code> nieco szybciej <code>fsync()<\/code>. Narz\u0119dzie <code>blktrace<\/code> wskazuje, \u017ce <code>fdatasync()<\/code> zwykle zapisuje na dysk mniej danych (w ext4 <code>fsync()<\/code> zapisuje 20 KiB, a <code>fdatasync()<\/code> \u2014 16 KiB). Ponadto ustali\u0142em, \u017ce XFS jest nieco szybszy ni\u017c ext4. A tu z pomoc\u0105 <code>blktrace<\/code> uda\u0142o si\u0119 dowiedzie\u0107, \u017ce <code>fdatasync()<\/code> zrzuca na dysk mniej danych (4 KiB w XFS).<\/p>\n<h2>Niejednoznaczne sytuacje zwi\u0105zane z u\u017cywaniem fsync()<\/h2>\n<p>\nMog\u0119 przypomnie\u0107 sobie trzy niejednoznaczne sytuacje dotycz\u0105ce <code>fsync()<\/code>, z kt\u00f3rymi spotka\u0142em si\u0119 w praktyce.<\/p>\n<p>Pierwszy taki przypadek zdarzy\u0142 si\u0119 w 2008 roku. Wtedy interfejs Firefox 3 'zawiesza\u0142 si\u0119', gdy wykonywano zapis na dysk du\u017cej liczby plik\u00f3w. Problem polega\u0142 na tym, \u017ce w implementacji interfejsu do przechowywania informacji o jego stanie u\u017cywano bazy danych SQLite. Po ka\u017cdej zmianie, kt\u00f3ra mia\u0142a miejsce w interfejsie, wywo\u0142ywana by\u0142a funkcja <code>fsync()<\/code>, co dawa\u0142o dobre gwarancje trwa\u0142ego przechowywania danych. W u\u017cywanym w\u00f3wczas systemie plik\u00f3w ext3 funkcja <code>fsync()<\/code> zrzuca\u0142a na dysk wszystkie \"brudne\" strony w systemie, a nie tylko te, kt\u00f3re mia\u0142y zwi\u0105zek z danym plikiem. Oznacza\u0142o to, \u017ce klikni\u0119cie przycisku w Firefoxie mog\u0142o wywo\u0142a\u0107 zapis megabajt\u00f3w danych na dysk magnetyczny, co mog\u0142o zaj\u0105\u0107 wiele sekund. Rozwi\u0105zanie problemu, jak zrozumia\u0142em z <noindex><a rel=\"nofollow\" href=\"http:\/\/shaver.off.net\/diary\/2008\/05\/25\/fsyncers-and-curveballs\/\">tego<\/a><\/noindex> materia\u0142u, polega\u0142o na przeniesieniu pracy z baz\u0105 danych do asynchronicznych zada\u0144 w tle. Oznacza to, \u017ce wcze\u015bniej w Firefoxie wprowadzono bardziej rygorystyczne wymagania dotycz\u0105ce trwa\u0142o\u015bci przechowywania danych, ni\u017c by\u0142o to rzeczywi\u015bcie potrzebne, a cechy systemu plik\u00f3w ext3 tylko pog\u0142\u0119bi\u0142y ten problem.<\/p>\n<p>Drugie rozbie\u017cno\u015b\u0107 mia\u0142a miejsce w 2009 roku. Po awarii systemu u\u017cytkownicy nowego systemu plik\u00f3w ext4 napotkali problem, \u017ce wiele niedawno utworzonych plik\u00f3w ma zerow\u0105 d\u0142ugo\u015b\u0107, podczas gdy w przypadku starszego systemu plik\u00f3w ext3 co\u015b takiego nie mia\u0142o miejsca. W poprzednim akapicie m\u00f3wi\u0142em o tym, \u017ce ext3 zrzuca\u0142a na dysk zbyt wiele danych, co znacznie spowalnia\u0142o dzia\u0142anie <code>fsync()<\/code>. Aby poprawi\u0107 sytuacj\u0119, w ext4 na dysk zrzucane s\u0105 tylko te \"brudne\" strony, kt\u00f3re maj\u0105 zwi\u0105zek z konkretnym plikiem. A dane innych plik\u00f3w pozostaj\u0105 w pami\u0119ci przez znacznie d\u0142u\u017cszy czas ni\u017c w przypadku stosowania ext3. Zrobiono to w celu poprawy wydajno\u015bci (domy\u015blnie dane pozostaj\u0105 w tym stanie przez 30 sekund, mo\u017cna to dostosowa\u0107 za pomoc\u0105 <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\">tutaj<\/a><\/noindex> , mo\u017cna znale\u017a\u0107 dodatkowe materia\u0142y na ten temat). Oznacza to, \u017ce du\u017ca ilo\u015b\u0107 danych mo\u017ce zosta\u0107 bezpowrotnie utracona po awarii. Rozwi\u0105zaniem tego problemu jest stosowanie <code>fsync()<\/code> w aplikacjach, kt\u00f3re musz\u0105 zapewni\u0107 trwa\u0142e przechowywanie danych i maksymalnie zabezpieczy\u0107 je przed skutkami awarii. Funkcja <code>fsync()<\/code> dzia\u0142a przy wykorzystaniu ext4 znacznie efektywniej ni\u017c przy u\u017cyciu ext3. Wada tego podej\u015bcia polega na tym, \u017ce jego zastosowanie, jak dawniej, spowalnia wykonanie niekt\u00f3rych operacji, takich jak instalacja program\u00f3w. Szczeg\u00f3\u0142y na ten temat znajdziesz <noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/322823\/\">tutaj<\/a><\/noindex> i <noindex><a rel=\"nofollow\" href=\"https:\/\/thunk.org\/tytso\/blog\/2009\/03\/12\/delayed-allocation-and-the-zero-length-file-problem\/\">tutaj<\/a><\/noindex>.<\/p>\n<p>Trzecia problem, dotycz\u0105cy <code>fsync()<\/code>, pojawi\u0142 si\u0119 w 2018 roku. W\u00f3wczas w ramach projektu PostgreSQL ustalono, \u017ce je\u015bli funkcja <code>fsync()<\/code> napotyka b\u0142\u0105d, oznacza \"brudne\" strony jako \"czyste\". W rezultacie kolejne wywo\u0142ania <code>fsync()<\/code> nic nie robi si\u0119 z takimi stronami. Z tego powodu zmodyfikowane strony s\u0105 przechowywane w pami\u0119ci i nigdy nie s\u0105 zapisywane na dysku. To jest prawdziwa katastrofa, poniewa\u017c aplikacja uzna, \u017ce jakie\u015b dane zosta\u0142y zapisane na dysku, podczas gdy w rzeczywisto\u015bci tak nie jest. Takie awarie <code>fsync()<\/code> zdarzaj\u0105 si\u0119 rzadko, aplikacja w takich sytuacjach prawie nic nie mo\u017ce zrobi\u0107, aby stawi\u0107 czo\u0142a problemowi. W dzisiejszych czasach, gdy to si\u0119 zdarza, PostgreSQL i inne aplikacje ko\u0144cz\u0105 dzia\u0142anie awaryjnie. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.usenix.org\/conference\/atc20\/presentation\/rebello\">Tutaj<\/a><\/noindex>, w materiale \u201eCzy aplikacje mog\u0105 odzyska\u0107 si\u0119 z b\u0142\u0119d\u00f3w fsync?\u201d, problem ten jest badany w pe\u0142nych szczeg\u00f3\u0142ach. Obecnie najlepszym rozwi\u0105zaniem tego problemu jest u\u017cycie Direct I\/O z flag\u0105 <code>O_SYNC<\/code> lub z flag\u0105 <code>O_DSYNC<\/code>. Przy takim podej\u015bciu system zg\u0142osi b\u0142\u0119dy, kt\u00f3re mog\u0105 wyst\u0105pi\u0107 podczas wykonywania konkretnych operacji zapisu danych, ale to podej\u015bcie wymaga, aby aplikacja zarz\u0105dza\u0142a buforami samodzielnie. Szczeg\u00f3\u0142y na ten temat mo\u017cna znale\u017a\u0107 w <noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/752063\/\">tutaj<\/a><\/noindex> i <noindex><a rel=\"nofollow\" href=\"https:\/\/wiki.postgresql.org\/wiki\/Fsync_Errors\">tutaj<\/a><\/noindex>.<\/p>\n<h2>Otwieranie plik\u00f3w przy u\u017cyciu flag O_SYNC i O_DSYNC<\/h2>\n<p>\nWr\u00f3\u0107my do om\u00f3wienia mechanizm\u00f3w Linux, kt\u00f3re zapewniaj\u0105 trwa\u0142e przechowywanie danych. A mianowicie m\u00f3wimy tu o u\u017cyciu flagi <code>O_SYNC<\/code> lub flagi <code>O_DSYNC<\/code> przy otwieraniu plik\u00f3w za pomoc\u0105 wywo\u0142ania systemowego <noindex><a rel=\"nofollow\" href=\"https:\/\/man7.org\/linux\/man-pages\/man2\/open.2.html\">open()<\/a><\/noindex>. Przy tym podej\u015bciu ka\u017cda operacja zapisu danych jest wykonywana tak, jakby po ka\u017cdym poleceniu <code>write()<\/code> systemowi s\u0105 wydawane odpowiednio polecenia <code>fsync()<\/code> i <code>fdatasync()<\/code>. W <noindex><a rel=\"nofollow\" href=\"https:\/\/pubs.opengroup.org\/onlinepubs\/009695399\/basedefs\/xbd_chap03.html#tag_03_373\">specyfikacji POSIX<\/a><\/noindex> nazywa si\u0119 to \u201eZako\u0144czeniem integracji pliku zatwierdzonego I\/O\u201d i \u201eZako\u0144czeniem integralno\u015bci danych\u201d. G\u0142\u00f3wn\u0105 zalet\u0105 tego podej\u015bcia jest to, \u017ce w celu zapewnienia integralno\u015bci danych wystarczy wykona\u0107 jedno wywo\u0142anie systemowe, a nie dwa (na przyk\u0142ad \u2014 <code>write()<\/code> i <code>fdatasync()<\/code>). G\u0142\u00f3wn\u0105 wad\u0105 tego podej\u015bcia jest to, \u017ce wszystkie operacje zapisu korzystaj\u0105ce z odpowiedniego deskryptora pliku b\u0119d\u0105 synchronizowane, co mo\u017ce ogranicza\u0107 mo\u017cliwo\u015bci strukturyzacji kodu aplikacji.<\/p>\n<h2>U\u017cycie Direct I\/O z flag\u0105 O_DIRECT<\/h2>\n<p>\nWywo\u0142anie systemowe <code>open()<\/code> wspiera flag\u0119 <code>O_DIRECT<\/code>, kt\u00f3ra ma na celu, omijaj\u0105c pami\u0119\u0107 podr\u0119czn\u0105 systemu operacyjnego, wykonywanie operacji wej\u015bcia\/wyj\u015bcia, wsp\u00f3\u0142pracuj\u0105c bezpo\u015brednio z dyskiem. Oznacza to, \u017ce w wielu przypadkach polecenia zapisu wydawane przez program b\u0119d\u0105 bezpo\u015brednio przekszta\u0142cane w polecenia dotycz\u0105ce pracy z dyskiem. Jednak w og\u00f3lnym przypadku ten mechanizm nie jest zast\u0105pieniem funkcji <code>fsync()<\/code> lub <code>fdatasync()<\/code>. Chodzi o to, \u017ce sam dysk mo\u017ce <noindex><a rel=\"nofollow\" href=\"https:\/\/www.evanjones.ca\/durability-nvme.html\">od\u0142o\u017cy\u0107 lub buforowa\u0107<\/a><\/noindex> odpowiednie komendy zapisu danych. Co gorsza, w niekt\u00f3rych szczeg\u00f3lnych przypadkach operacje we\/wy wykonywane przy u\u017cyciu flagi <code>O_DIRECT<\/code>, <noindex><a rel=\"nofollow\" href=\"https:\/\/ext4.wiki.kernel.org\/index.php\/Clarifying_Direct_IO%27s_Semantics\">s\u0105 przesy\u0142ane<\/a><\/noindex> do tradycyjnych operacji buforowanych. Naj\u0142atwiej rozwi\u0105za\u0107 ten problem, u\u017cywaj\u0105c w otwieraniu plik\u00f3w tak\u017ce flagi <code>O_DSYNC<\/code>, co oznacza, \u017ce ka\u017cda operacja zapisu b\u0119dzie mia\u0142a wywo\u0142anie <code>fdatasync()<\/code>.<\/p>\n<p>Okaza\u0142o si\u0119, \u017ce w systemie plik\u00f3w XFS niedawno dodano \u201eszybk\u0105 \u015bcie\u017ck\u0119\u201d dla <code>O_DIRECT|O_DSYNC<\/code>-zapisu danych. Je\u015bli blok jest nadpisywany za pomoc\u0105 <code>O_DIRECT|O_DSYNC<\/code>, to XFS, zamiast zrzuci\u0107 bufor, wykona polecenie FUA-zapisu, je\u015bli urz\u0105dzenie to obs\u0142uguje. Uda\u0142o mi si\u0119 to potwierdzi\u0107, korzystaj\u0105c z narz\u0119dzia <code>blktrace<\/code> w systemie Linux 5.4\/Ubuntu 20.04. Takie podej\u015bcie powinno by\u0107 bardziej efektywne, poniewa\u017c przy jego u\u017cyciu na dysk zapisywana jest minimalna ilo\u015b\u0107 danych i stosowana jest jedna operacja, a nie dwie (zapis i zrzut bufora). Znalaz\u0142em odniesienie do <noindex><a rel=\"nofollow\" href=\"https:\/\/patchwork.kernel.org\/patch\/10250257\/\">\u0142atk\u0119<\/a><\/noindex> j\u0105dra z 2018 roku, w kt\u00f3rym zrealizowano ten mechanizm. Jest tam dyskusja dotycz\u0105ca zastosowania tej optymalizacji w innych systemach plik\u00f3w, ale o ile mi wiadomo, XFS to jak na razie jedyny system plik\u00f3w, kt\u00f3ry to obs\u0142uguje.<\/p>\n<h2>Funkcja sync_file_range()<\/h2>\n<p>\nW systemie Linux istnieje wywo\u0142anie systemowe <noindex><a rel=\"nofollow\" href=\"https:\/\/man7.org\/linux\/man-pages\/man2\/sync_file_range.2.html\">sync_file_range()<\/a><\/noindex>, kt\u00f3re umo\u017cliwia zrzucenie na dysk tylko cz\u0119\u015bci pliku, a nie ca\u0142ego pliku. To wywo\u0142anie inicjuje asynchroniczny zrzut danych i nie czeka na jego zako\u0144czenie. Jednak w dokumentacji do <code>sync_file_range()<\/code> m\u00f3wi si\u0119, \u017ce ta komenda jest \u201ebardzo niebezpieczna\u201d. Nie zaleca si\u0119 jej u\u017cywania. Cechy i niebezpiecze\u0144stwa <code>sync_file_range()<\/code> s\u0105 bardzo dobrze opisane w <noindex><a rel=\"nofollow\" href=\"http:\/\/yoshinorimatsunobu.blogspot.com\/2014\/03\/how-syncfilerange-really-works.html\">tym<\/a><\/noindex> materiale. W szczeg\u00f3lno\u015bci, wygl\u0105da na to, \u017ce to wywo\u0142anie u\u017cywa RocksDB do zarz\u0105dzania tym, kiedy j\u0105dro zrzuca \u201ebrudne\u201d dane na dysk. Ale przy tym, dla zapewnienia trwa\u0142ego przechowywania danych, u\u017cywane jest tak\u017ce <code>fdatasync()<\/code>. W <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/facebook\/rocksdb\/search?q=sync_file_range\">kodzie<\/a><\/noindex> RocksDB s\u0105 interesuj\u0105ce komentarze na ten temat. Na przyk\u0142ad, wydaje si\u0119, \u017ce wywo\u0142anie <code>sync_file_range()<\/code> przy u\u017cyciu ZFS nie prowadzi do zrzutu danych na dysk. Do\u015bwiadczenie podpowiada mi, \u017ce kod, kt\u00f3ry u\u017cywany jest rzadko, mo\u017ce zawiera\u0107 b\u0142\u0119dy. Dlatego doradzi\u0142bym, aby nie korzysta\u0107 z tego wywo\u0142ania systemowego bez powa\u017cnej potrzeby.<\/p>\n<h2>Wywo\u0142ania systemowe, kt\u00f3re pomagaj\u0105 zapewni\u0107 trwa\u0142e przechowywanie danych<\/h2>\n<p>\nDoszed\u0142em do wniosku, \u017ce do wykonywania operacji wej\u015bcia\/wyj\u015bcia, zapewniaj\u0105cych trwa\u0142e przechowywanie danych, mo\u017cna stosowa\u0107 trzy podej\u015bcia. Wszystkie one wymagaj\u0105 wywo\u0142ania funkcji <code>fsync()<\/code> dla katalogu, w kt\u00f3rym utworzono plik. Oto te podej\u015bcia:<\/p>\n<ol>\n<li>Wywo\u0142anie funkcji <code>fdatasync()<\/code> lub <code>fsync()<\/code> po funkcji <code>write()<\/code> (lepiej u\u017cywa\u0107 <code>fdatasync()<\/code>).<\/li>\n<li>Praca z deskryptorem pliku otwartym z flag\u0105 <code>O_DSYNC<\/code> lub <code>O_SYNC<\/code> (lepiej \u2014 z flag\u0105 <code>O_DSYNC<\/code>).<\/li>\n<li>U\u017cycie polecenia <code>pwritev2()<\/code> z flag\u0105 <code>RWF_DSYNC<\/code> lub <code>RWF_SYNC<\/code> (lepiej \u2014 z flag\u0105 <code>RWF_DSYNC<\/code>).<\/li>\n<\/ol>\n<p><\/p>\n<h2>Notatki na temat wydajno\u015bci<\/h2>\n<p>\nNie przeprowadza\u0142em dok\u0142adnych pomiar\u00f3w wydajno\u015bci r\u00f3\u017cnych mechanizm\u00f3w, kt\u00f3re zbada\u0142em. Zauwa\u017cone przeze mnie r\u00f3\u017cnice w szybko\u015bci ich dzia\u0142ania s\u0105 do\u015b\u0107 niewielkie. Oznacza to, \u017ce mog\u0119 si\u0119 myli\u0107, a przy innych warunkach to samo mo\u017ce da\u0107 inne wyniki. Najpierw opowiem o tym, co bardziej wp\u0142ywa na wydajno\u015b\u0107, a potem o tym, co wp\u0142ywa na ni\u0105 mniej.<\/p>\n<ol>\n<li>Nadpisywanie danych pliku jest szybsze ni\u017c do\u0142\u0105czanie danych do pliku (wzrost wydajno\u015bci mo\u017ce wynosi\u0107 od 2 do 100%). Do\u0142\u0105czanie danych do pliku wymaga dokonania dodatkowych zmian w metadanych pliku, nawet po wywo\u0142aniu systemowym <code>fallocate()<\/code>, ale skala tego efektu mo\u017ce si\u0119 zmienia\u0107. Zalecam wywo\u0142a\u0107 <code>fallocate()<\/code> w celu wst\u0119pnego przydzielenia wymaganego miejsca. Nast\u0119pnie to miejsce nale\u017cy jawnie wype\u0142ni\u0107 zerami i wywo\u0142a\u0107 <code>fsync()<\/code>. Dzi\u0119ki temu odpowiednie bloki w systemie plik\u00f3w b\u0119d\u0105 oznaczone jako 'przydzielone', a nie 'nieprzydzielone'. Daje to niewielk\u0105 (oko\u0142o 2%) popraw\u0119 wydajno\u015bci. Ponadto, w przypadku niekt\u00f3rych dysk\u00f3w pierwsza operacja dost\u0119pu do bloku mo\u017ce by\u0107 wolniejsza od innych. Oznacza to, \u017ce wype\u0142nienie miejsca zerami mo\u017ce prowadzi\u0107 do znacznej (oko\u0142o 100%) poprawy wydajno\u015bci. W szczeg\u00f3lno\u015bci mo\u017ce to wyst\u0105pi\u0107 w przypadku dysk\u00f3w <noindex><a rel=\"nofollow\" href=\"https:\/\/n2ws.com\/blog\/how-to-guides\/pre-warm-ebs-volumes-on-aws\">AWS EBS<\/a><\/noindex> (to \u2014 dane nieoficjalne, nie mog\u0142em ich potwierdzi\u0107). To samo dotyczy pami\u0119ci <noindex><a rel=\"nofollow\" href=\"https:\/\/cloud.google.com\/compute\/docs\/disks\/benchmarking-pd-performance\">GCP Persistent Disk<\/a><\/noindex> (a to \u2014 ju\u017c oficjalne informacj\u0119, potwierdzone testami). Inni specjali\u015bci dokonali takich samych <noindex><a rel=\"nofollow\" href=\"http:\/\/yoshinorimatsunobu.blogspot.com\/2009\/05\/overwriting-is-much-faster-than_28.html\">obserwacji<\/a><\/noindex>, dotycz\u0105cych r\u00f3\u017cnych dysk\u00f3w.<\/li>\n<li>Im mniej wywo\u0142a\u0144 systemowych \u2014 tym wy\u017csza wydajno\u015b\u0107 (wzrost mo\u017ce wynosi\u0107 oko\u0142o 5%). Wydaje si\u0119, \u017ce wywo\u0142anie <code>open()<\/code> z flag\u0105 <code>O_DSYNC<\/code> lub wywo\u0142anie <code>pwritev2()<\/code> z flag\u0105 <code>RWF_SYNC<\/code> szybsze wywo\u0142anie <code>fdatasync()<\/code>. Podejrzewam, \u017ce to dlatego, \u017ce przy takim podej\u015bciu kluczowe jest to, \u017ce do rozwi\u0105zania tego samego zadania konieczne jest wykonanie mniejszej liczby wywo\u0142a\u0144 systemowych (jedno wywo\u0142anie zamiast dw\u00f3ch). Ale r\u00f3\u017cnica w wydajno\u015bci jest bardzo ma\u0142a, wi\u0119c mo\u017cesz ca\u0142kowicie zignorowa\u0107 ten aspekt i u\u017cywa\u0107 w aplikacji tego, co nie skomplikuje jej logiki.<\/li>\n<\/ol>\n<p>\nJe\u015bli interesuje Ci\u0119 temat trwa\u0142ego przechowywania danych \u2014 oto kilka przydatnych materia\u0142\u00f3w:<\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.scylladb.com\/2017\/10\/05\/io-access-methods-scylla\/\">Metody dost\u0119pu I\/O<\/a><\/noindex> \u2014 przegl\u0105d podstawowych mechanizm\u00f3w wej\u015bcia\/wyj\u015bcia.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/457667\/\">Zagwarantowanie, \u017ce dane dotr\u0105 na dysk<\/a><\/noindex> \u2014 opowie\u015b\u0107 o tym, co dzieje si\u0119 z danymi na drodze od aplikacji do dysku.<\/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\">Kiedy powiniene\u015b u\u017cywa\u0107 fsync dla zawieraj\u0105cego katalogu<\/a><\/noindex> \u2014 odpowied\u017a na pytanie, kiedy nale\u017cy stosowa\u0107 <code>fsync()<\/code> dla katalog\u00f3w. M\u00f3wi\u0105c w skr\u00f3cie, nale\u017cy to zrobi\u0107 przy tworzeniu nowego pliku, a pow\u00f3d tej rekomendacji polega na tym, \u017ce w Linuksie mo\u017ce by\u0107 wiele dowi\u0105za\u0144 do tego samego pliku.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/bobsql.com\/sql-server-on-linux-forced-unit-access-fua-internals\/\">SQL Server na Linuksie: Wewn\u0105trz FUA<\/a><\/noindex> \u2014 tutaj znajduje si\u0119 opis tego, jak trwa\u0142e przechowywanie danych jest realizowane w SQL Server na platformie Linux. Znajdziesz tu kilka interesuj\u0105cych por\u00f3wna\u0144 mi\u0119dzy wywo\u0142aniami systemowymi Windows i Linux. Prawie jestem pewien, \u017ce to dzi\u0119ki temu materia\u0142owi dowiedzia\u0142em si\u0119 o optymalizacji FUA w XFS.<\/li>\n<\/ul>\n<p>\nCzy kiedykolwiek utraci\u0142e\u015b dane, kt\u00f3re uwa\u017ca\u0142e\u015b za trwale zapisywane na dysku?<\/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=\"Trwa\u0142e przechowywanie danych i interfejsy API plik\u00f3w w systemie 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=\"Trwa\u0142e przechowywanie danych i interfejsy API plik\u00f3w w systemie Linux\" src=\"\/wp-content\/uploads\/2020\/10\/d9fd0b1c09eb6e40944aee2d13ee4088.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<br \/>\u0179r\u00f3d\u0142o: <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.1.1 - 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\/pl\/blog\/administrirovanie\/ustojchivoe-hranenie-dannyh-i-fajlovye-api-linux\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\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\/pl\/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\udd47Trwa\u0142e przechowywanie danych i API plikowe Linux | ProHoster","description":"Badaj\u0105c trwa\u0142o\u015b\u0107 przechowywania danych w systemach chmurowych, postanowi\u0142em sprawdzi\u0107 siebie, upewni\u0107 si\u0119, \u017ce rozumiem podstawowe rzeczy.","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/ustojchivoe-hranenie-dannyh-i-fajlovye-api-linux","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","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\/pl\/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\/pl\/wp-json\/wp\/v2\/posts\/98090","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=98090"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/98090\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/98091"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=98090"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=98090"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=98090"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}