UNIX में फ़ाइल परिशिष्ट परमाणु है?


106

सामान्य तौर पर, जब हम कई प्रक्रियाओं से UNIX में एक फ़ाइल के लिए संलग्न होते हैं, तो हम क्या कर सकते हैं? क्या डेटा खोना संभव है (एक प्रक्रिया दूसरे के बदलावों को अधिलेखित करना)? क्या डेटा को मंगवाना संभव है? (उदाहरण के लिए, प्रत्येक प्रक्रिया लॉग फ़ाइल में प्रति पंक्ति एक परिशिष्ट जोड़ रही है, क्या यह संभव है कि दो पंक्तियाँ उलझ जाएँ?) यदि उपर्युक्त अर्थों में परिशिष्ट परमाणु नहीं है, तो पारस्परिक बहिष्कार सुनिश्चित करने का सबसे अच्छा तरीका क्या है?

जवाबों:


65

'PIPE_BUF' के आकार के अंतर्गत आने वाला लेखन परमाणु माना जाता है। यह कम से कम 512 बाइट्स होना चाहिए, हालांकि यह आसानी से बड़ा हो सकता है (लगता है कि यह 4096 पर सेट है)।

यह मान लें कि आप पूरी तरह से POSIX- अनुरूप घटकों से बात कर रहे हैं। उदाहरण के लिए, यह एनएफएस पर सच नहीं है।

लेकिन यह मानते हुए कि आपने 'O_APPEND' मोड में खोली गई एक लॉग फ़ाइल को लिखा है और 'PIPE_BUF' बाइट्स के तहत अपनी लाइनें (newline सहित) लंबी रखें, आपको बिना किसी भ्रष्टाचार के समस्या के लॉग फ़ाइल में कई लेखक होने चाहिए। कोई भी व्यवधान लिखने से पहले या बाद में आएगा, बीच में नहीं। यदि आप रिबूट को जीवित करने के लिए फ़ाइल अखंडता चाहते हैं, तो आपको fsync(2)हर लिखने के बाद भी कॉल करना होगा , लेकिन यह प्रदर्शन के लिए भयानक है।

स्पष्टीकरण : टिप्पणियों और ओज़ सोलोमन के उत्तर को पढ़ें । मुझे यकीन नहीं है कि O_APPENDमाना जाता है कि उस PIPE_BUFआकार की परमाणुता है। यह पूरी तरह से संभव है कि यह लिनक्स कैसे लागू किया गया है write(), या यह अंतर्निहित फाइल सिस्टम के ब्लॉक आकारों के कारण हो सकता है।


11
समझदार फाइलसिस्टम पर, fsync(2)उतनी ही गारंटी देता sync(2)है, जितना कि प्रदर्शन पर बड़े-हथौड़े का उतना असर नहीं होता।
इफिशिएंट

4
क्या अापको उस बारे में पूर्ण विशवास है? क्या आप उस व्यवहार के बारे में कुछ लिंक प्रदान कर सकते हैं? मुझे यह पुष्टि मिली कि यदि डिस्क्रिप्टर एक पाइप है, लेकिन मुझे इस बात का सबूत नहीं मिला कि यह किसी भी फ़ाइल के लिए काम करता है । सामान्य, गैर-एनएफएस फ़ाइल ऑब्जेक्ट सहित।
एलन फ्रांजोनी

6
वास्तव में कहाँ ... / write.html? O_APPEND के लिए, मुझे PIPE_BUF का कोई उल्लेख नहीं दिखता है, और मुझे वादा दिखाई देता है कि " फ़ाइल ऑफ़सेट और राइट ऑपरेशन को बदलने के बीच कोई हस्तक्षेप करने वाला फ़ाइल संशोधन ऑपरेशन नहीं होगा " , लेकिन मुझे यकीन नहीं है कि अगर इसका मतलब यह है कि लेखन स्वयं है निर्बाध ...
एकवैल

6
जैसा कि यह उत्तर बताता है, PIPE_BUFउस पृष्ठ के बारे में बयान केवल पाइप और एफआईएफओ पर लागू होता है, न कि नियमित फाइलों पर।
ग्रेग इनोज़ेत्सेव

3
संकेतों के आने से यह और भी खराब हो सकता है: Bugzilla.kernel.org/show_bug.cgi?id=55651 । यह भी एक जवाब के रूप में चिह्नित क्यों है? PIPE_BUF का फ़ाइलों से कोई लेना-देना नहीं है।
पतला

35

संपादित करें: नवीनतम विंडोज परिणामों के साथ अगस्त 2017 को अपडेट किया गया।

मैं आपको प्रस्तावित Boost.AFIO के लेखक के रूप में परीक्षण कोड और परिणामों के लिंक के साथ एक उत्तर देने जा रहा हूं, जो एक अतुल्यकालिक फाइल सिस्टम को लागू करता है और i / o C ++ लाइब्रेरी को फाइल करता है।

सबसे पहले, विंडोज पर O_APPEND या समकक्ष FILE_APPEND_DATA का अर्थ है कि समवर्ती लेखक के अंतर्गत अधिकतम फ़ाइल सीमा (फ़ाइल "लंबाई") की वृद्धि परमाणु है । यह POSIX द्वारा गारंटी है, और लिनक्स, FreeBSD, OS X और विंडोज सभी इसे सही तरीके से लागू करते हैं। सांबा भी इसे सही तरीके से लागू करता है, v5 से पहले एनएफएस नहीं करता है क्योंकि इसमें परमाणु रूप से संलग्न करने के लिए तार प्रारूप क्षमता का अभाव है। इसलिए यदि आप अपनी फ़ाइल को केवल परिशिष्ट के साथ खोलते हैं, तो समवर्ती लेखन किसी भी प्रमुख ओएस पर एक दूसरे के संबंध में आंसू नहीं बहाएगा जब तक कि एनएफएस शामिल नहीं होता है।

हालाँकि समवर्ती परमाणु परमाणुओं को पढ़ता है , ओएस, फाइलिंग सिस्टम के आधार पर फटे हुए लेखन को देख सकता है, और आपने फाइल को किस झंडे के साथ खोला है - अधिकतम फ़ाइल सीमा का वेतन वृद्धि परमाणु है, लेकिन रीड के संबंध में लेखन की दृश्यता हो सकती है या नहीं परमाणु होना। यहाँ झंडे, OS और फाइलिंग सिस्टम द्वारा एक त्वरित सारांश दिया गया है:


कोई O_DIRECT / FILE_FLAG_NO_BUFFERING:

Microsoft Windows 10 NTFS के साथ: atomicity = 1 बाइट तक अद्यतन करें और 10.0.10240 सहित, 10.0.14393 से कम से कम 1Mb, शायद अनंत (*)।

एक्स्टे 4 के साथ लिनक्स 4.2.6: अपडेट एटोमिसिटी = 1 बाइट

फ्रीबीएसडी 10.2 जेडएफएस के साथ: अद्यतन परमाणु = कम से कम 1 एमबी, शायद अनंत (*)

O_DIRECT / FILE_FLAG_NO_BUFFERING:

Microsoft Windows 10 NTFS के साथ: atomicity = अद्यतन करें और जब तक कि पृष्ठ संरेखित नहीं किया जाता है, तब तक केवल 10.096 बाइट्स 4096 बाइट्स सहित, अन्यथा 512 बाइट्स यदि FILE_FLAG_WRITE_THROUGH बंद हों, तो 64 बाइट्स। ध्यान दें कि यह परमाणुता संभवत: PCIe DMA की एक विशेषता है जिसे डिज़ाइन किया गया है। 10.0.14393 के बाद से, कम से कम 1Mb, शायद अनंत (*)।

एक्स्ट्रीम 4 के साथ लिनक्स 4.2.6: एटमॉसिटी = कम से कम 1Mb, शायद अनंत (*) को अपडेट करें। ध्यान दें कि ext4 के साथ पहले लिनक्स निश्चित रूप से 4096 बाइट्स से अधिक नहीं था, एक्सएफएस निश्चित रूप से कस्टम लॉकिंग का उपयोग करता था लेकिन ऐसा लगता है कि हाल ही में लिनक्स ने इसे ठीक कर दिया है।

फ्रीबीएसडी 10.2 जेडएफएस के साथ: अद्यतन परमाणु = कम से कम 1 एमबी, शायद अनंत (*)


आप कच्चे अनुभवजन्य परीक्षा परिणाम https://github.com/ned14/afio/tree/master/programs/fs-probe पर देख सकते हैं । ध्यान दें कि हम फटे हुए ऑफ़सेट के लिए केवल 512 बाइट गुणकों पर परीक्षण करते हैं, इसलिए मैं यह नहीं कह सकता कि यदि 512 बाइट सेक्टर का आंशिक अद्यतन रीड-मॉडिफाई-राइट साइकिल के दौरान आंसू बहाएगा।

इसलिए, ओपी के प्रश्न का उत्तर देने के लिए, O_APPEND लिखते हैं, एक दूसरे के साथ हस्तक्षेप नहीं करेंगे, लेकिन O_APPEND के समवर्ती को पढ़ता है, संभवतः लिनक्स पर फटे हुए लेखन को ext4 के साथ देखेगा जब तक कि O_DIRECT चालू नहीं होता है, जहां आपके O_APPEND लिखते से सेक्टर आकार बहु ​​होने की आवश्यकता होगी।


(*) "संभवतः अनंत" POSIX कल्पना में इन खंडों से उपजा है:

निम्नलिखित सभी कार्य POSIX.1-2008 में निर्दिष्ट प्रभावों में एक दूसरे के संबंध में परमाणु होंगे जब वे नियमित फ़ाइलों या प्रतीकात्मक लिंक पर काम करते हैं ... [कई कार्य] ... पढ़ें () ... लिखें ) ... यदि दो थ्रेड्स इनमें से किसी एक फ़ंक्शन को कॉल करते हैं, तो प्रत्येक कॉल या तो अन्य कॉल के निर्दिष्ट प्रभावों को देखेगा, या उनमें से कोई भी नहीं। [स्रोत]

तथा

राइट्स को अन्य रीड और राइट के संबंध में क्रमबद्ध किया जा सकता है। यदि डेटा के एक रीड () किसी भी (किसी भी माध्यम से) डेटा के लिखने () के बाद होने के लिए सिद्ध किया जा सकता है, तो उसे उस लिखना () को प्रतिबिंबित करना चाहिए, भले ही कॉल विभिन्न प्रक्रियाओं द्वारा किए गए हों। [स्रोत]

लेकिन इसके विपरीत:

POSIX.1-2008 की यह मात्रा कई प्रक्रियाओं से एक फ़ाइल के समवर्ती लिखने का व्यवहार निर्दिष्ट नहीं करती है। एप्लिकेशन को समसामयिक नियंत्रण के कुछ रूप का उपयोग करना चाहिए। [स्रोत]

आप इस उत्तर में इनके अर्थ के बारे में अधिक पढ़ सकते हैं


29

मैंने अधिकतम परमाणु परिशिष्ट के आकार का अनुभव करने के लिए एक स्क्रिप्ट लिखी। स्क्रिप्ट, जो बैश में लिखी गई है, कई कार्यकर्ता प्रक्रियाओं को जन्म देती है जो सभी कार्यकर्ता-विशिष्ट हस्ताक्षर एक ही फाइल पर लिखते हैं। यह फ़ाइल को पढ़ता है, अतिव्यापी या दूषित हस्ताक्षरों की तलाश करता है। आप इस ब्लॉग पोस्ट पर स्क्रिप्ट के लिए स्रोत देख सकते हैं ।

वास्तविक अधिकतम परमाणु परिशिष्ट का आकार न केवल ओएस, बल्कि फाइलसिस्टम द्वारा भिन्न होता है।

Linux + ext3 पर आकार 4096 है, और Windows + NTFS पर आकार 1024 है। अधिक आकारों के लिए नीचे टिप्पणी देखें।


लिनक्स पर आपने किस फाइलसिस्टम के साथ परीक्षण किया? मैं सोच रहा था कि शायद यह फाइलसिस्टम ब्लॉक आकारों पर आधारित है।
फ़्रीहिट

@freiheit मेरा मानना ​​है कि जब मैंने ext3 पर इसका परीक्षण किया था। यदि आप इसे दूसरे एफएस पर चलाते हैं और एक अलग परिणाम प्राप्त करते हैं, तो कृपया एक टिप्पणी पोस्ट करें।
ओजोम सुलैमान

3
@OzSolomon, मैंने आपकी स्क्रिप्ट का उपयोग डेबियन 7.8 पर किया, और मैं केवल अपने ext4 विभाजन और एक tmpfs माउंट पर 1008 बाइट्स (1024 - 16 बाइट्स ऑफ़ ओवरहेड) सहित परमाणु लिख पाने में सक्षम था। इससे परे कुछ भी हुआ, जिसके परिणामस्वरूप हर बार भ्रष्टाचार हुआ।
एरिक प्रिट

6
आपके परीक्षण से लगता है कि आकार की परवाह किए बिना echo $line >> $OUTPUT_FILEएक ही कॉल में परिणाम होगा । write$line
टॉमस

16

यहाँ क्या मानक का कहना है: http://www.opengroup.org/onlinepubs/009695399/functions/pwrite.html

यदि O_APPENDफ़ाइल स्थिति ध्वज का ध्वज सेट किया गया है, तो फ़ाइल ऑफ़सेट प्रत्येक लिखने से पहले फ़ाइल के अंत में सेट किया जाएगा और फ़ाइल ऑफ़सेट और लेखन ऑपरेशन को बदलने के बीच कोई हस्तक्षेप फ़ाइल संशोधन ऑपरेशन नहीं होगा।


20
"के बीच" - लेकिन लेखन के दौरान हस्तक्षेप के बारे में क्या , जो मेरी समझ के लिए "बीच" के बाद होता है? (यानी: <change_offset_action> ... "the_between_period" ... <write_action>) - क्या मुझे समझ में आएगा कि इसके बारे में कोई गारंटी नहीं है?
अंचल

@ हवेल राजी हो गया; इसकी कोई गारंटी नहीं है कि लेखन स्वयं परमाणु है। लेकिन मैं भ्रमित हूं: आपकी बोली में प्रदान की गई गारंटी के आधार पर, ऐसा लगता है कि हम यह निष्कर्ष निकाल सकते हैं कि एक ही फाइल को जोड़ने वाला एक मल्टीथ्रेडेड ऐप विभिन्न लिखित रिकॉर्ड के कुछ हिस्सों को नहीं मिलाएगा। हालाँकि, OzSolomon द्वारा बताए गए प्रयोगों से, हम देखते हैं कि यहां तक ​​कि धारणा का उल्लंघन किया जाता है। क्यों?
अधिकतम

@ माफ करना, मुझे डर है कि मैं आपका सवाल नहीं उठाऊंगा: सबसे पहले, OzSolomon का प्रयोग मल्टी- प्रोसेस है , न कि मल्टी- थ्रेडेड (एकल प्रक्रिया) ऐप; दूसरी बात, मुझे समझ में नहीं आता कि आप कैसे निष्कर्ष निकालते हैं कि "एक मल्टीथ्रेडेड ऐप [...] मिक्स नहीं होगा" - यह वही है जो मैं बस्तियन के उद्धरण द्वारा गारंटीकृत नहीं देखता हूं, जैसा कि मैंने अपनी टिप्पणी में उल्लेख किया है। क्या आप अपना प्रश्न स्पष्ट कर सकते हैं?
आंवल

2
हम्म मैं उस टिप्पणी को लिखने के समय अपने स्वयं के तर्क को फिर से संगठित नहीं कर सकता ... हाँ, यदि आपकी व्याख्या सही है, तो निश्चित रूप से विभिन्न रिकॉर्ड मिश्रित हो सकते हैं। लेकिन अब जब मैं बैस्टियन के उद्धरण को पुन: प्रस्तुत कर रहा हूं, तो मुझे लगता है कि इसका मतलब यह होना चाहिए कि कोई भी "लेखन के दौरान" को बाधित नहीं कर सकता है - अन्यथा मानक में संपूर्ण पैराग्राफ बेकार होगा, बशर्ते वास्तव में कोई गारंटी नहीं है (यह भी नहीं कि लिखना होगा अंत में, के रूप में "लिखने" कदम निष्पादित isbeing के बाद से किसी और somone ऑफसेट ले सकता है।
अधिकतम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.