Երկարատև տվյալների պահպանման և Linux ֆայլերի API-ներ

Ամպային համակարգերում տվյալների պահպանման կայունությունը ուսումնասիրելիս ես որոշեցի ինքս ինձ փորձարկել՝ համոզվելու համար, որ հասկանում եմ հիմնական բաները: Ի սկսվեց կարդալով NVMe բնութագրերը որպեսզի հասկանանք, թե ինչ երաշխիքներ են տալիս տվյալների կայուն պահպանման վերաբերյալ (այսինքն՝ երաշխիքներ, որ տվյալները հասանելի կլինեն համակարգի խափանումից հետո) մեզ տալիս են NMVe սկավառակներ: Ես արեցի հետևյալ հիմնական եզրակացությունները՝ տվյալները պետք է վնասված համարվեն տվյալների գրելու հրամանի տրվելու պահից մինչև այն պահը, երբ դրանք գրվում են պահեստային միջավայրում։ Այնուամենայնիվ, ծրագրերի մեծ մասը հաճույքով օգտագործում է համակարգային զանգեր տվյալների ձայնագրման համար:

Այս գրառման մեջ ես ուսումնասիրում եմ Linux ֆայլերի API-ների կողմից տրամադրված մշտական ​​պահպանման մեխանիզմները: Թվում է, թե այստեղ ամեն ինչ պետք է պարզ լինի. ծրագիրը կանչում է հրամանը write(), և այս հրամանի ավարտից հետո տվյալները ապահով կերպով կպահվեն սկավառակի վրա: Բայց write() միայն պատճենում է հավելվածի տվյալները RAM-ում տեղակայված միջուկի քեշին: Համակարգին ստիպելու համար գրել տվյալներ սկավառակի վրա, դուք պետք է օգտագործեք լրացուցիչ մեխանիզմներ:

Երկարատև տվյալների պահպանման և Linux ֆայլերի API-ներ

Ընդհանուր առմամբ, այս նյութը նշումների հավաքածու է, որը վերաբերում է այն ամենին, ինչ ես սովորել եմ ինձ հետաքրքրող թեմայի վերաբերյալ: Եթե ​​շատ հակիրճ խոսենք ամենակարևոր բանի մասին, ապա պարզվում է, որ տվյալների կայուն պահեստավորում կազմակերպելու համար անհրաժեշտ է օգտագործել հրամանը. fdatasync() կամ բացել ֆայլերը դրոշով O_DSYNC. Եթե ​​դուք հետաքրքրված եք ավելին իմանալու մասին, թե ինչ է տեղի ունենում տվյալների հետ կոդից սկավառակ ճանապարհին, նայեք սա է հոդված.

Write() ֆունկցիայի օգտագործման առանձնահատկությունները

Համակարգային զանգ write() սահմանված ստանդարտում IEEE POSIX որպես ֆայլի նկարագրիչի վրա տվյալներ գրելու փորձ: Հաջող ավարտից հետո write() Տվյալների ընթերցման գործողությունները պետք է վերադարձնեն հենց այն բայթերը, որոնք նախկինում գրվել են, դա անելով նույնիսկ այն դեպքում, եթե տվյալները հասանելի են այլ գործընթացներից կամ թելերից (այստեղ POSIX ստանդարտի համապատասխան բաժինը): Այստեղ, այն բաժնում, թե ինչպես են շղթաները փոխազդում ֆայլի սովորական գործողությունների հետ, կա նշում, որն ասում է, որ եթե երկու շղթաներից յուրաքանչյուրը կանչում է այս գործառույթները, ապա յուրաքանչյուր զանգ պետք է տեսնի կամ մյուս զանգի բոլոր նշանակված հետևանքները, կամ ընդհանրապես ոչ մեկը: հետեւանքները. Սա հանգեցնում է այն եզրակացության, որ ֆայլի մուտքի/ելքի բոլոր գործողությունները պետք է կողպված լինեն ռեսուրսի վրա, որի վրա նրանք աշխատում են:

Արդյո՞ք սա նշանակում է, որ վիրահատությունը write() ատոմային է? Տեխնիկական տեսանկյունից՝ այո։ Տվյալների ընթերցման գործողությունները պետք է վերադարձնեն կամ ամբողջը կամ ոչինչ, ինչով գրված է write(). Բայց վիրահատությունը write()Ըստ ստանդարտի, պարտադիր չէ, որ ավարտվի այն ամենը, ինչ պահանջվել է գրել: Նրան թույլատրվում է գրել տվյալների միայն մի մասը: Օրինակ, մենք կարող ենք ունենալ երկու շղթա, որոնցից յուրաքանչյուրը 1024 բայթ ավելացնում է նույն ֆայլի նկարագրությամբ նկարագրված ֆայլին: Ստանդարտի տեսանկյունից ընդունելի արդյունք կլինի, երբ գրելու յուրաքանչյուր գործողություն կարող է ֆայլին ավելացնել միայն մեկ բայթ: Այս գործողությունները կմնան ատոմային, բայց դրանք ավարտվելուց հետո այն տվյալները, որոնք նրանք գրել են ֆայլում, կխառնվեն: Այստեղ շատ հետաքրքիր քննարկում այս թեմայի շուրջ Stack Overflow-ում:

fsync() և fdatasync() ֆունկցիաները

Տվյալները սկավառակի վրա լցնելու ամենահեշտ ձևը ֆունկցիան կանչելն է fsync (). Այս գործառույթը խնդրում է օպերացիոն համակարգին փոխանցել բոլոր փոփոխված բլոկները քեշից սկավառակ: Սա ներառում է ֆայլի բոլոր մետատվյալները (մուտքի ժամանակը, ֆայլի փոփոխման ժամանակը և այլն): Կարծում եմ, որ այս մետատվյալները հազվադեպ են անհրաժեշտ, այնպես որ, եթե գիտեք, որ դա ձեզ համար կարևոր չէ, կարող եք օգտագործել գործառույթը fdatasync(): Մեջ Օգնություն մասին fdatasync() Ասվում է, որ այս ֆունկցիայի գործարկման ժամանակ սկավառակի վրա պահվում է մետատվյալների այնպիսի քանակություն, որը «անհրաժեշտ է տվյալների ընթերցման հետևյալ գործողությունների ճիշտ կատարման համար»։ Եվ սա հենց այն է, ինչի մասին հոգ է տանում հավելվածների մեծ մասը:

Խնդիրներից մեկը, որը կարող է առաջանալ այստեղ, այն է, որ այս մեխանիզմները չեն երաշխավորում, որ ֆայլը հայտնաբերելի կլինի հնարավոր ձախողումից հետո: Մասնավորապես, նոր ֆայլ ստեղծելիս պետք է զանգահարել fsync() այն պարունակող գրացուցակի համար: Հակառակ դեպքում, ձախողումից հետո կարող է պարզվել, որ այս ֆայլը գոյություն չունի: Սրա պատճառն այն է, որ UNIX-ում, կոշտ հղումների օգտագործման պատճառով, ֆայլը կարող է գոյություն ունենալ բազմաթիվ գրացուցակներում: Հետեւաբար, զանգահարելիս fsync() ոչ մի կերպ ֆայլը չի ​​կարող իմանալ, թե որ գրացուցակի տվյալները նույնպես պետք է լցվեն սկավառակի վրա (այստեղ Այս մասին կարող եք կարդալ ավելին): Կարծես թե ext4 ֆայլային համակարգը ունակ է ավտոմատ դիմել fsync() համապատասխան ֆայլեր պարունակող դիրեկտորիաներին, սակայն այլ ֆայլային համակարգերի դեպքում դա չի կարող լինել:

Այս մեխանիզմը կարող է տարբեր կերպ կիրառվել տարբեր ֆայլային համակարգերում: ես օգտագործել եմ blktrace իմանալ, թե սկավառակի ինչ գործառնություններ են օգտագործվում ext4 և XFS ֆայլային համակարգերում: Երկուսն էլ թողարկում են սկավառակի վրա կանոնավոր գրելու հրամաններ և՛ ֆայլի բովանդակության, և՛ ֆայլային համակարգի ամսագրի համար, մաքրում են քեշը և դուրս են գալիս՝ կատարելով FUA (Force Unit Access, տվյալներ անմիջապես սկավառակի վրա գրելը, քեշը շրջանցելով) գրել ամսագրում: Հավանաբար դա անում են, որպեսզի հաստատեն, որ գործարքը կայացել է։ Սկավառակների վրա, որոնք չեն աջակցում FUA-ին, դա առաջացնում է քեշի երկու ողողում: Իմ փորձերը դա ցույց տվեցին fdatasync() մի քիչ ավելի արագ fsync(). Կոմունալ blktrace ցույց է տալիս, որ fdatasync() սովորաբար ավելի քիչ տվյալներ է գրում սկավառակի վրա (ext4 fsync() գրում է 20 KiB, իսկ fdatasync() - 16 ԿԲ): Բացի այդ, ես պարզեցի, որ XFS-ը մի փոքր ավելի արագ է, քան ext4-ը: Եվ ահա՝ օգնությամբ blktrace հաջողվել է պարզել դա fdatasync() ավելի քիչ տվյալներ է փոխանցում սկավառակի վրա (4 KiB XFS-ում):

Ոչ միանշանակ իրավիճակներ, որոնք առաջանում են fsync() օգտագործելիս

Ես կարող եմ մտածել երեք ոչ միանշանակ իրավիճակի մասին fsync()որին ես հանդիպեցի գործնականում։

Առաջին նման դեպքը տեղի է ունեցել 2008թ. Այնուհետև Firefox 3-ի ինտերֆեյսը կսառչի, եթե մեծ թվով ֆայլեր գրվեին սկավառակի վրա: Խնդիրն այն էր, որ ինտերֆեյսի իրականացումը օգտագործում էր SQLite տվյալների բազա՝ իր վիճակի մասին տեղեկատվությունը պահելու համար: Ինտերֆեյսում տեղի ունեցած յուրաքանչյուր փոփոխությունից հետո ֆունկցիան կանչվում էր fsync(), որը տվել է տվյալների կայուն պահպանման լավ երաշխիքներ։ Այնուհետև օգտագործված ext3 ֆայլային համակարգում գործառույթը fsync() Համակարգի բոլոր «կեղտոտ» էջերը գցեց սկավառակի վրա, և ոչ միայն նրանք, որոնք կապված էին համապատասխան ֆայլի հետ: Սա նշանակում էր, որ Firefox-ում կոճակի վրա սեղմելը կարող է հրահրել մագնիսական սկավառակի վրա մեգաբայթ տվյալներ գրելու համար, ինչը կարող է տևել շատ վայրկյաններ: Խնդրի լուծումը, որքան հասկանում եմ այն նյութը տվյալների բազայի հետ աշխատանքը փոխանցելու էր ասինխրոն ֆոնային առաջադրանքներին: Սա նշանակում է, որ Firefox-ը նախկինում ավելի խիստ պահանջներ էր կիրառել, քան իրականում անհրաժեշտ էր, և ext3 ֆայլային համակարգի առանձնահատկությունները միայն խորացրին այս խնդիրը:

Երկրորդ խնդիրն առաջացել է 2009թ. Այնուհետև, համակարգի խափանումից հետո, նոր ext4 ֆայլային համակարգի օգտագործողները բախվեցին այն փաստի հետ, որ նոր ստեղծված շատ ֆայլեր ունեին զրոյական երկարություն, բայց դա տեղի չունեցավ հին ext3 ֆայլային համակարգի հետ: Նախորդ պարբերությունում ես խոսեցի այն մասին, թե ինչպես է ext3-ը չափից շատ տվյալներ հավաքում սկավառակի վրա, ինչը շատ դանդաղեցրեց իրերի արագությունը: fsync(). Իրավիճակը բարելավելու համար ext4-ում միայն այն կեղտոտ էջերը, որոնք առնչվում են որոշակի ֆայլին, լցվում են սկավառակի վրա: Իսկ այլ ֆայլերի տվյալները շատ ավելի երկար են մնում հիշողության մեջ, քան ext3-ի դեպքում: Սա արվել է արդյունավետությունը բարելավելու համար (լռելյայն, տվյալները մնում են այս վիճակում 30 վայրկյան, դուք կարող եք կարգավորել դա՝ օգտագործելով dirty_expire_centisecs; այստեղ Այս մասին կարող եք գտնել լրացուցիչ նյութեր): Սա նշանակում է, որ մեծ քանակությամբ տվյալներ կարող են անդառնալիորեն կորցնել ձախողումից հետո: Այս խնդրի լուծումը օգտագործելն է fsync() հավելվածներում, որոնք պետք է ապահովեն տվյալների կայուն պահպանում և հնարավորինս պաշտպանեն դրանք խափանումների հետևանքներից: Գործառույթ fsync() ext4-ն օգտագործելիս շատ ավելի արդյունավետ է աշխատում, քան ext3-ը: Այս մոտեցման թերությունն այն է, որ դրա օգտագործումը, ինչպես նախկինում, դանդաղեցնում է որոշ գործողությունների կատարումը, օրինակ՝ ծրագրերի տեղադրումը։ Տես մանրամասներ այս մասին այստեղ и այստեղ.

Երրորդ խնդիրը վերաբերում է fsync(), ծագել է 2018թ. Այնուհետեւ PostgreSQL նախագծի շրջանակներում պարզվել է, որ եթե ֆունկցիան fsync() բախվում է սխալի, այն նշում է «կեղտոտ» էջերը որպես «մաքուր»: Արդյունքում հետեւյալ կոչերը fsync() Նրանք ոչինչ չեն անում նման էջերի հետ: Դրա պատճառով փոփոխված էջերը պահվում են հիշողության մեջ և երբեք չեն գրվում սկավառակի վրա: Սա իսկական աղետ է, քանի որ հավելվածը կմտածի, որ որոշ տվյալներ գրված են սկավառակի վրա, բայց իրականում այդպես չի լինի: Նման ձախողումներ fsync() հազվադեպ են, նման իրավիճակներում կիրառումը գրեթե ոչինչ չի կարող անել խնդրի դեմ պայքարելու համար: Այս օրերին, երբ դա տեղի է ունենում, PostgreSQL-ը և այլ հավելվածները խափանում են: Այստեղ, «Կարո՞ղ են հավելվածները վերականգնել fsync-ի ձախողումներից» նյութում այս խնդիրը մանրամասն ուսումնասիրված է: Ներկայումս այս խնդրի լավագույն լուծումը դրոշակով Direct I/O-ի օգտագործումն է O_SYNC կամ դրոշակով O_DSYNC. Այս մոտեցմամբ համակարգը կզեկուցի սխալների մասին, որոնք կարող են առաջանալ գրելու հատուկ գործողությունների ժամանակ, սակայն այս մոտեցումը պահանջում է, որ հավելվածն ինքը կառավարի բուֆերները: Կարդացեք ավելին այս մասին այստեղ и այստեղ.

Ֆայլերի բացում՝ օգտագործելով O_SYNC և O_DSYNC դրոշները

Վերադառնանք Linux մեխանիզմների քննարկմանը, որոնք ապահովում են տվյալների կայուն պահպանում։ Խոսքը, մասնավորապես, դրոշն օգտագործելու մասին է O_SYNC կամ դրոշ O_DSYNC համակարգային զանգի միջոցով ֆայլեր բացելիս բաց (). Այս մոտեցմամբ տվյալների գրման յուրաքանչյուր գործողություն կատարվում է այնպես, կարծես յուրաքանչյուր հրամանից հետո write() Համակարգին համապատասխան հրամաններ են տրվում fsync() и fdatasync(): Մեջ POSIX բնութագրերը սա կոչվում է «Synchronized I/O File Integrity Completion» և «Data Integrity Completion»: Այս մոտեցման հիմնական առավելությունն այն է, որ տվյալների ամբողջականությունն ապահովելու համար անհրաժեշտ է կատարել միայն մեկ համակարգային զանգ, այլ ոչ թե երկու (օրինակ՝ write() и fdatasync()). Այս մոտեցման հիմնական թերությունն այն է, որ համապատասխան ֆայլի նկարագրիչ օգտագործող բոլոր գրությունները կհամաժամանակացվեն, ինչը կարող է սահմանափակել հավելվածի կոդը կառուցվածքավորելու հնարավորությունը:

Օգտագործելով Direct I/O O_DIRECT դրոշակով

Համակարգային զանգ open() աջակցում է դրոշը O_DIRECT, որը նախատեսված է օպերացիոն համակարգի քեշը շրջանցելու համար՝ I/O գործողություններ կատարելու համար՝ ուղղակիորեն սկավառակի հետ փոխազդելով։ Սա շատ դեպքերում նշանակում է, որ ծրագրի կողմից թողարկված գրելու հրամաններն ուղղակիորեն կվերածվեն սկավառակի հետ աշխատելուն ուղղված հրամանների: Բայց, ընդհանուր առմամբ, այս մեխանիզմը ֆունկցիաներին փոխարինող չէ fsync() կամ fdatasync(). Փաստն այն է, որ սկավառակն ինքնին կարող է հետաձգել կամ քեշ համապատասխան տվյալների գրման հրամաններ: Եվ ավելի վատ, որոշ հատուկ դեպքերում I/O գործողությունները կատարվում են դրոշն օգտագործելիս O_DIRECT, հեռարձակում ավանդական բուֆերային գործողությունների մեջ: Այս խնդիրը լուծելու ամենահեշտ ձևը ֆայլեր բացելու համար դրոշի օգտագործումն է O_DSYNC, ինչը կնշանակի, որ յուրաքանչյուր գրելու գործողությանը կհետևի զանգ fdatasync().

Պարզվեց, որ XFS ֆայլային համակարգը վերջերս ավելացրել է «արագ ուղի»: O_DIRECT|O_DSYNC- տվյալների գրանցում. Եթե ​​բլոկը վերագրվում է օգտագործելով O_DIRECT|O_DSYNC, ապա XFS-ը, քեշը լվանալու փոխարեն, կկատարի FUA գրելու հրամանը, եթե սարքն աջակցում է դրան: Ես դա ստուգեցի՝ օգտագործելով կոմունալ ծրագիրը blktrace Linux 5.4/Ubuntu 20.04 համակարգի վրա: Այս մոտեցումը պետք է ավելի արդյունավետ լինի, քանի որ երբ օգտագործվում է, նվազագույն քանակությամբ տվյալներ են գրվում սկավառակի վրա և օգտագործվում է մեկ գործողություն, այլ ոչ թե երկու (քեշը գրելը և մաքրելը): Ես գտա հղումը դեպի patch 2018 միջուկը, որն իրականացնում է այս մեխանիզմը։ Այնտեղ որոշակի քննարկում կա այս օպտիմիզացումը այլ ֆայլային համակարգերի վրա նույնպես կիրառելու վերաբերյալ, բայց որքան ես գիտեմ, XFS-ը միակ ֆայլային համակարգն է, որն աջակցում է մինչ այժմ:

sync_file_range() ֆունկցիան

Linux-ն ունի համակարգային զանգ sync_file_range (), որը թույլ է տալիս ֆայլի միայն մի մասը տեղադրել սկավառակի վրա, այլ ոչ թե ամբողջ ֆայլը: Այս զանգը սկսում է տվյալների ասինխրոն մաքրում և չի սպասում դրա ավարտին: Բայց վկայականում sync_file_range() Ասում են, որ թիմը «շատ վտանգավոր է»: Խորհուրդ չի տրվում օգտագործել այն։ Առանձնահատկություններ և վտանգներ sync_file_range() շատ լավ նկարագրված է սա է նյութական. Մասնավորապես, այս զանգը, կարծես, օգտագործում է RocksDB-ն՝ վերահսկելու, երբ միջուկը կեղտոտ տվյալներ է թափում սկավառակի վրա: Բայց միևնույն ժամանակ տվյալների կայուն պահպանումն ապահովելու համար այն նաև օգտագործվում է fdatasync(): Մեջ կոդը RocksDB-ն այս թեմայի վերաբերյալ մի քանի հետաքրքիր մեկնաբանություն ունի: Օրինակ, թվում է, որ զանգը sync_file_range() ZFS-ն օգտագործելիս այն չի տեղափոխում տվյալները սկավառակի վրա: Փորձն ինձ ասում է, որ հազվադեպ օգտագործվող կոդը, հավանաբար, պարունակում է սխալներ: Հետևաբար, ես խորհուրդ կտայի չօգտագործել այս համակարգային զանգը, եթե խիստ անհրաժեշտություն չկա:

Համակարգային զանգեր, որոնք օգնում են ապահովել տվյալների կայունությունը

Ես եկել եմ այն ​​եզրակացության, որ կան երեք մոտեցումներ, որոնք կարող են օգտագործվել I/O գործողություններ կատարելու համար, որոնք ապահովում են տվյալների կայունությունը: Նրանք բոլորը պահանջում են ֆունկցիայի կանչ fsync() գրացուցակի համար, որտեղ ստեղծվել է ֆայլը: Սրանք են մոտեցումները.

  1. Գործառույթ կանչելը fdatasync() կամ fsync() գործառույթից հետո write() (ավելի լավ է օգտագործել fdatasync()).
  2. Դրոշակով բացված ֆայլի նկարագրիչի հետ աշխատելը O_DSYNC կամ O_SYNC (ավելի լավ - դրոշով O_DSYNC).
  3. Օգտագործելով հրամանը pwritev2() դրոշով RWF_DSYNC կամ RWF_SYNC (ցանկալի է դրոշակով RWF_DSYNC).

Կատարման նշումներ

Ես ուշադիր չեմ չափել իմ ուսումնասիրած տարբեր մեխանիզմների կատարումը: Նրանց աշխատանքի արագության մեջ ես նկատեցի տարբերությունները շատ փոքր են։ Սա նշանակում է, որ ես կարող եմ սխալվել, և որ տարբեր պայմաններում նույն բանը կարող է տարբեր արդյունքներ տալ։ Նախ, ես կխոսեմ այն ​​մասին, թե ինչն է ավելի շատ ազդում կատարման վրա, իսկ հետո ինչն է ավելի քիչ ազդում կատարման վրա:

  1. Ֆայլի տվյալների վերագրանցումն ավելի արագ է, քան տվյալների ֆայլին կցելը (գործողության առավելությունը կարող է լինել 2-100%): Ֆայլին տվյալների ավելացումը պահանջում է լրացուցիչ փոփոխություններ ֆայլի մետատվյալներում, նույնիսկ համակարգային զանգից հետո fallocate(), բայց այս ազդեցության մեծությունը կարող է տարբեր լինել: Լավագույն կատարման համար խորհուրդ եմ տալիս զանգահարել fallocate() նախապես հատկացնել անհրաժեշտ տարածքը. Այնուհետև այս տարածքը պետք է բացահայտորեն լրացվի զրոներով և կոչվի fsync(). Սա կապահովի, որ ֆայլային համակարգում համապատասխան բլոկները նշվեն որպես «հատկացված», այլ ոչ թե «չբաշխված»: Սա թույլ է տալիս փոքր (մոտ 2%) կատարողականի բարելավում: Բացի այդ, որոշ սկավառակներ կարող են ավելի դանդաղ մուտք գործել բլոկ, քան մյուսները: Սա նշանակում է, որ տարածքը զրոներով լրացնելը կարող է հանգեցնել կատարողականի զգալի (մոտ 100%) բարելավմանը: Մասնավորապես, դա կարող է տեղի ունենալ սկավառակների հետ AWS EBS (սա ոչ պաշտոնական տվյալ է, ես չկարողացա հաստատել): Նույնը վերաբերում է պահեստավորմանը GCP մշտական ​​սկավառակ (իսկ սա արդեն պաշտոնական տեղեկություն է՝ հաստատված թեստերով)։ Նույնն արել են նաև այլ փորձագետներ դիտարկումները, կապված տարբեր սկավառակների հետ։
  2. Որքան քիչ համակարգային զանգեր, այնքան բարձր կատարողականություն (շահույթը կարող է լինել մոտ 5%): Կարծես մարտահրավեր է open() դրոշով O_DSYNC կամ զանգահարեք pwritev2() դրոշով RWF_SYNC ավելի արագ, քան զանգը fdatasync(). Ես կասկածում եմ, որ խնդիրն այստեղ այն է, որ այս մոտեցումը դեր է խաղում այն ​​փաստի մեջ, որ ավելի քիչ համակարգային զանգեր պետք է կատարվեն նույն խնդիրը լուծելու համար (մեկ զանգ երկուսի փոխարեն): Բայց կատարողականի տարբերությունը շատ փոքր է, այնպես որ դուք կարող եք ամբողջովին անտեսել այն և հավելվածում օգտագործել այնպիսի բան, որը չի բարդացնի դրա տրամաբանությունը:

Եթե ​​ձեզ հետաքրքրում է տվյալների կայուն պահպանման թեման, ապա այստեղ կան մի քանի օգտակար նյութեր.

  • I/O մուտքի մեթոդներ — մուտքային/ելքային մեխանիզմների հիմունքների ակնարկ:
  • Ապահովել, որ տվյալները հասնում են սկավառակի — պատմություն այն մասին, թե ինչ է տեղի ունենում տվյալների հետ հավելվածից դեպի սկավառակ ճանապարհին:
  • Ե՞րբ պետք է համաժամացնեք պարունակող գրացուցակը - հարցի պատասխանը, երբ օգտագործել fsync() գրացուցակների համար: Սա կարճ ասած, պարզվում է, որ դուք պետք է դա անեք նոր ֆայլ ստեղծելիս, և այս առաջարկության պատճառն այն է, որ Linux-ում կարող են լինել բազմաթիվ հղումներ նույն ֆայլին:
  • SQL Server Linux-ում. FUA Internals — ահա նկարագրությունը, թե ինչպես է մշտական ​​տվյալների պահպանումն իրականացվում SQL Server-ում Linux հարթակում: Այստեղ կան մի քանի հետաքրքիր համեմատություններ Windows-ի և Linux-ի համակարգային զանգերի միջև: Ես գրեթե համոզված եմ, որ հենց այս նյութի շնորհիվ է, որ ես իմացա XFS-ի FUA օպտիմալացման մասին:

Դուք կորցրե՞լ եք տվյալները, որոնք կարծում էիք, որ ապահով կերպով պահված են սկավառակի վրա:

Երկարատև տվյալների պահպանման և Linux ֆայլերի API-ներ

Երկարատև տվյալների պահպանման և Linux ֆայլերի API-ներ

Source: www.habr.com