लिनक्स पर लिखने के कारण आई / ओ त्रुटियों का सामना करने के लिए प्रोग्राम लिखना


138

TL; DR: यदि लिनक्स कर्नेल एक आई / ओ लिखता है , तो क्या यह पता लगाने के लिए आवेदन का कोई तरीका है?

मुझे पता है कि आपके पास fsync()स्थायित्व के लिए फ़ाइल (और इसकी मूल निर्देशिका) है । सवाल यह है कि यदि कर्नेल गंदे बफ़र्स को खो देता है जो कि I / O त्रुटि के कारण लंबित हैं , तो एप्लिकेशन इसे कैसे पता लगा सकता है और पुनर्प्राप्त या निरस्त कर सकता है?

डेटाबेस एप्लिकेशन आदि के बारे में सोचें, जहां लिखने और स्थायित्व लिखने का क्रम महत्वपूर्ण हो सकता है।

खोया लिखा? कैसे?

लिनक्स कर्नेल की ब्लॉक लेयर कुछ परिस्थितियों में आई / ओ अनुरोधों को खो देती है जो त्रुटि के साथ सफलतापूर्वक सबमिट किए जाते हैं write(), pwrite()आदि:

Buffer I/O error on device dm-0, logical block 12345
lost page write due to I/O error on dm-0

(देखें end_buffer_write_sync(...)और end_buffer_async_write(...)मेंfs/buffer.c )।

नए कर्नेल पर त्रुटि के बजाय "खोया async पेज लिखना" होगा , जैसे:

Buffer I/O error on dev dm-0, logical block 12345, lost async page write

चूंकि एप्लिकेशन की write()त्रुटि के बिना पहले ही वापस आ चुका है, इसलिए आवेदन में त्रुटि की रिपोर्ट करने का कोई तरीका नहीं है।

उनका पता लगा रहे हैं?

मैं कर्नेल स्रोतों से परिचित नहीं हूं, लेकिन मुझे लगता है कि यह AS_EIOबफर पर सेट होता है जो कि लिखने में विफल रहा है, अगर यह एक async लेखन कर रहा है:

    set_bit(AS_EIO, &page->mapping->flags);
    set_buffer_write_io_error(bh);
    clear_buffer_uptodate(bh);
    SetPageError(page);

लेकिन यह मेरे लिए अस्पष्ट है कि क्या या कैसे इस बारे में एप्लिकेशन को पता चल सकता है जब उसने बाद में fsync()डिस्क पर इसकी पुष्टि करने के लिए फाइल की है।

ऐसा लग रहा है wait_on_page_writeback_range(...)मेंmm/filemap.c से हो सकता है do_sync_mapping_range(...)मेंfs/sync.c है जिसके द्वारा कहा जाता है बारी है sys_sync_file_range(...)-EIOयदि एक या अधिक बफ़र्स नहीं लिखे जा सकते हैं तो यह वापस आ जाता है।

यदि, जैसा कि मैं अनुमान लगा रहा हूं, यह fsync()परिणाम के लिए प्रचारित करता है , तो अगर ऐप पैन करता है और बाहर निकलता है अगर इसे I / O त्रुटि मिलती है fsync()और फिर से शुरू होने पर अपने काम को फिर से करने का तरीका जानता है, तो यह पर्याप्त सुरक्षा होना चाहिए?

वहाँ शायद के लिए ऐप को जानने का कोई तरीका नहीं है जो बाइट ऑफसेट खो पृष्ठों के लिए एक फ़ाइल के अनुरूप अगर यह जानता है कि कैसे, लेकिन तो यह उन्हें फिर से लिखने सकते में ऐप्स को पिछली बार सफल के बाद से सभी अपने लंबित काम को दोहराता है, तो fsync()फ़ाइल की, और कहा कि पुनर्लेखन किसी भी गंदे कर्नेल बफ़र्स को फाइल के खिलाफ लिखने के लिए खो दिया गया है, जो कि खोए गए पृष्ठों पर किसी भी I / O त्रुटि झंडे को साफ करना चाहिए और अगले fsync()को पूरा करने की अनुमति देना चाहिए - सही है?

क्या तब कोई अन्य, हानिरहित, परिस्थितियां ऐसी fsync()हो सकती हैं, -EIOजहां से बाहर निकलना और काम को फिर से करना बहुत अधिक कठोर होगा?

क्यों?

बेशक ऐसी त्रुटियां नहीं होनी चाहिए। इस मामले में त्रुटि dm-multipathड्राइवर की चूक के बीच एक दुर्भाग्यपूर्ण बातचीत से उत्पन्न हुई और सैन द्वारा उपयोग किए जाने वाले अर्थ कोड पतले-प्रावधान वाले भंडारण को आवंटित करने में विफलता की रिपोर्ट करने के लिए। लेकिन यह एकमात्र परिस्थिति नहीं है जहां वे हो सकते हैं - मैंने इसके लिए पतली प्रावधानित LVM से रिपोर्ट भी देखी है, उदाहरण के लिए, libvirt, Docker, और बहुत कुछ। एक डेटाबेस की तरह एक महत्वपूर्ण एप्लिकेशन को इस तरह की त्रुटियों से निपटने की कोशिश करनी चाहिए, बजाय आँख बंद करके ले जाने के जैसे कि सब ठीक है।

यदि कर्नेल को लगता है कि कर्नेल घबराहट के साथ मरने के बिना लिखना खोना ठीक है, तो अनुप्रयोगों को सामना करने का एक तरीका खोजना होगा।

व्यावहारिक प्रभाव यह है कि मुझे एक ऐसा मामला मिला जहां एक SAN के साथ एक बहुपथ समस्या का कारण खो गया जो लिखता है कि डेटाबेस भ्रष्टाचार के कारण उतरा क्योंकि DBMS को पता नहीं था कि उसके लेखन विफल हो गए थे। मज़ा नहीं।


1
मुझे डर है कि इन त्रुटि स्थितियों को संग्रहीत करने और याद रखने के लिए SystemFileTable में अतिरिक्त फ़ील्ड की आवश्यकता होगी। और उपयोगकर्ताओं को बाद में कॉल करने पर उन्हें प्राप्त करने या निरीक्षण करने की एक संभावना है। (do fsync () और क्लोज़ () इस तरह की ऐतिहासिक जानकारी
लौटाते हैं

@ लूप थैंक्स। मैंने अभी एक उत्तर पोस्ट किया है जो मुझे लगता है कि चल रहा है, मन में एक विवेक-जांच हो रही है क्योंकि आपको लगता है कि उन लोगों की तुलना में क्या हो रहा है जो "लिखने () (या बंद) या fsync () की जरूरत है ) स्थायित्व के लिए "प्रश्न को पढ़े बिना?
क्रेग रिंगर

BTW: मुझे लगता है कि आपको वास्तव में कर्नेल स्रोतों में तल्लीन करना चाहिए। पत्रिकाओं के फाइल सिस्टम शायद एक ही तरह की समस्याओं से ग्रस्त होंगे। स्वैप विभाजन हैंडलिंग का उल्लेख नहीं है। चूंकि ये कर्नेल स्पेस में रहते हैं, इसलिए इन परिस्थितियों से निपटना शायद थोड़ा अधिक कठोर होगा। राइटवे (), जो कि यूजरस्पेस से दिखाई देता है, भी देखने के लिए एक जगह की तरह लगता है। [क्रेग में: हाँ क्योंकि मैं तुम्हारा नाम जानता हूँ, और मैं जानता हूँ कि तुम एक पूर्ण मूर्ख नहीं हो; -]
१४

1
मैं मानता हूं, मैं इतना निष्पक्ष नहीं था। काश आपका जवाब बहुत संतोषजनक नहीं होता, मेरा मतलब है कि कोई आसान उपाय (आश्चर्य?) नहीं है।
जीन-बैप्टिस्ट यूनेस

1
@ जीन-बैपटिस्टयूनस ट्रू। DBMS के लिए मैं साथ काम कर रहा हूं, "दुर्घटना और फिर से दर्ज करें" स्वीकार्य है। अधिकांश ऐप्स के लिए यह एक विकल्प नहीं है और उन्हें तुल्यकालिक I / O के भयावह प्रदर्शन को सहन करना पड़ सकता है या I / O त्रुटियों पर खराब परिभाषित व्यवहार और भ्रष्टाचार को स्वीकार कर सकता है।
क्रेग रिंगर

जवाबों:


91

fsync()रिटर्न -EIOअगर कर्नेल एक लेखन खो दिया है

(नोट: प्रारंभिक भाग पुरानी गुठली का संदर्भ है; आधुनिक गुठली को प्रतिबिंबित करने के लिए नीचे अद्यतन)

ऐसा लगता है कि विफलताओं में async बफर राइट-आउट फ़ाइल के लिए विफल गंदे बफर पृष्ठ पर end_buffer_async_write(...)एक -EIOध्वज सेट करता है :

set_bit(AS_EIO, &page->mapping->flags);
set_buffer_write_io_error(bh);
clear_buffer_uptodate(bh);
SetPageError(page);

तब तक पता चला है जो wait_on_page_writeback_range(...)के रूप में से बुलाया do_sync_mapping_range(...)के रूप से बुलाया sys_sync_file_range(...)के रूप से बुलाया sys_sync_file_range2(...)सी पुस्तकालय कॉल लागू करने के लिए fsync()

लेकिन केवल एक बार!

इस पर टिप्पणी sys_sync_file_range

168  * SYNC_FILE_RANGE_WAIT_BEFORE and SYNC_FILE_RANGE_WAIT_AFTER will detect any
169  * I/O errors or ENOSPC conditions and will return those to the caller, after
170  * clearing the EIO and ENOSPC flags in the address_space.

सुझाव देता है कि जब fsync()रिटर्न -EIOया (मैनपेज में अनडॉक्स्ड) होता है -ENOSPC, तो यह एरर स्टेट को क्लियर कर देगा, इसलिए बाद में fsync()सफलता की रिपोर्ट करेगा, हालांकि पेज कभी लिखे ही नहीं गए।

निश्चित रूप wait_on_page_writeback_range(...) से त्रुटि बिट्स को साफ करता है जब यह उनका परीक्षण करता है :

301         /* Check for outstanding write errors */
302         if (test_and_clear_bit(AS_ENOSPC, &mapping->flags))
303                 ret = -ENOSPC;
304         if (test_and_clear_bit(AS_EIO, &mapping->flags))
305                 ret = -EIO;

इसलिए अगर आवेदन की उम्मीद है fsync()कि यह तब तक फिर से कोशिश कर सकता है जब तक कि यह सफल न हो जाए और भरोसा हो कि डेटा ऑन-डिस्क है, यह बहुत गलत है।

मुझे पूरा यकीन है कि यह डेटा भ्रष्टाचार का स्रोत है जो मुझे डीबीएमएस में मिला है। यह पुनः प्रयास करता है fsync()और सोचता है कि सब कुछ ठीक हो जाएगा, जब यह सफल होता है।

क्या यह अनुमति है?

पर POSIX / SUS डॉक्सfsync() वास्तव में इस किसी भी तरह से निर्दिष्ट नहीं करते हैं:

यदि fsync () फ़ंक्शन विफल हो जाता है, तो बकाया I / O संचालन पूरा होने की गारंटी नहीं है।

लिनक्स का मैन-पेजfsync() सिर्फ असफलता के बारे में कुछ नहीं कहता है।

तो ऐसा लगता है कि fsync()त्रुटियों का अर्थ है "आपके लेखन के लिए क्या हुआ, शायद काम किया है या नहीं, बेहतर होगा सुनिश्चित करने के लिए फिर से प्रयास करें"।

नई गुठली

4.9 पर end_buffer_async_writeसेट -EIOपृष्ठ पर, बस के माध्यम से mapping_set_error

    buffer_io_error(bh, ", lost async page write");
    mapping_set_error(page->mapping, -EIO);
    set_buffer_write_io_error(bh);
    clear_buffer_uptodate(bh);
    SetPageError(page);

सिंक की तरफ मुझे लगता है कि यह समान है, हालांकि संरचना अब पालन करने के लिए बहुत जटिल है। filemap_check_errorsमें mm/filemap.cअब करता है:

    if (test_bit(AS_EIO, &mapping->flags) &&
        test_and_clear_bit(AS_EIO, &mapping->flags))
            ret = -EIO;

जिसका बहुत अधिक प्रभाव है। त्रुटि की जाँच सभी को लगती है filemap_check_errorsजिसके माध्यम से परीक्षण और स्पष्ट होता है:

    if (test_bit(AS_EIO, &mapping->flags) &&
        test_and_clear_bit(AS_EIO, &mapping->flags))
            ret = -EIO;
    return ret;

मैं btrfsअपने लैपटॉप पर उपयोग कर रहा हूं , लेकिन जब मैं ext4परीक्षण के लिए एक लूपबैक बनाता हूं /mnt/tmpऔर उस पर एक पूर्ण जांच सेट करता हूं :

sudo dd if=/dev/zero of=/tmp/ext bs=1M count=100
sudo mke2fs -j -T ext4 /tmp/ext
sudo mount -o loop /tmp/ext /mnt/tmp

sudo perf probe filemap_check_errors

sudo perf record -g -e probe:end_buffer_async_write -e probe:filemap_check_errors dd if=/dev/zero of=/mnt/tmp/test bs=4k count=1 conv=fsync

मुझे निम्नलिखित कॉल स्टैक में मिलता है perf report -T:

        ---__GI___libc_fsync
           entry_SYSCALL_64_fastpath
           sys_fsync
           do_fsync
           vfs_fsync_range
           ext4_sync_file
           filemap_write_and_wait_range
           filemap_check_errors

एक पढ़ने के माध्यम से पता चलता है कि हाँ, आधुनिक गुठली एक ही व्यवहार करती है।

इसका मतलब यह प्रतीत होता है कि यदि fsync()(या संभवत: write()या close()) रिटर्न -EIO, फाइल के बीच कुछ अपरिभाषित स्थिति में है, जब आप अंतिम रूप से सफलतापूर्वक इसे fsync()या close()इसके सबसे हाल ही में write()दस राज्य को डी या डी करते हैं ।

परीक्षा

मैंने इस व्यवहार को प्रदर्शित करने के लिए एक परीक्षण केस लागू किया है

निहितार्थ

एक DBMS क्रैश रिकवरी दर्ज करके इसका सामना कर सकता है। पृथ्वी पर एक सामान्य उपयोगकर्ता एप्लिकेशन को इससे कैसे सामना करना चाहिए? fsync()आदमी पेज कोई चेतावनी है कि इसका मतलब है देता है "fsync-अगर में आप महसूस की तरह यह" और मैं एक उम्मीद बहुत एप्लिकेशन की इस व्यवहार के साथ अच्छी तरह से सामना नहीं होंगे।

दोष रिपोर्ट

आगे की पढाई

lwn.net ने "बेहतर ब्लॉक-लेयर एरर हैंडलिंग" लेख में इस पर छुआ

postgresql.org मेलिंग सूची धागा


3
lxr.free-electrons.com/source/fs/buffer.c?v=2.6.26#L598 एक संभावित दौड़ है, क्योंकि यह {लंबित और अनुसूचित I / O} की प्रतीक्षा करता है, न कि {अभी तक I / O} के लिए। यह स्पष्ट रूप से डिवाइस के अतिरिक्त दौरों से बचने के लिए है। (मैं मानता हूं कि उपयोगकर्ता लिखता है () जब तक मैं / ओ शेड्यूल नहीं करता, तब तक मैं वापिस नहीं आता, जब मैं
मिमीप

3
क्या यह संभव है कि कुछ अन्य प्रक्रिया के लिए उसी डिस्क पर किसी अन्य फ़ाइल के लिए fsync की कॉल त्रुटि रिटर्न प्राप्त करती है?
रैंडम 832

3
@ Random832 PostgreSQL जैसे मल्टी-प्रोसेसिंग DB के लिए बहुत प्रासंगिक है, इसलिए अच्छा सवाल है। शायद लगता है, लेकिन मैं कर्नेल कोड को समझने के लिए पर्याप्त नहीं जानता। अगर वे दोनों एक ही फ़ाइल को किसी भी तरह से खोलते हैं, तो आपके प्रॉक्स का बेहतर सह-संचालन होता था।
क्रेग रिंगर

1
@DavidFoerster: syscalls नकारात्मक अशुद्ध कोड का उपयोग करके विफलताओं को लौटाता है; errnoपूरी तरह से यूजर्स सी लाइब्रेरी का निर्माण है। यह syscalls और C लाइब्रेरी के बीच रिटर्न वैल्यू के अंतर को अनदेखा करना आम है (जैसा कि क्रेग रिंगर, ऊपर), क्योंकि त्रुटि रिटर्न वैल्यू मज़बूती से पहचानता है कि कौन सा (syscall या C लाइब्रेरी फ़ंक्शन) संदर्भित किया जा रहा है: "के -1साथ " errno==EIO"सी लाइब्रेरी फ़ंक्शन को संदर्भित करता है, जबकि" -EIO"एक syscall को संदर्भित करता है। अंत में, लिनक्स मैन पेज ऑनलाइन लिनक्स मैन पेजों के संदर्भ में सबसे ऊपर हैं।
नाममात्र पशु

2
@ क्रेगिंगर: अपने अंतिम प्रश्न का उत्तर देने के लिए: "निम्न-स्तर I / O और fsync()/ fdatasync()जब लेन-देन का आकार एक पूर्ण फ़ाइल का उपयोग करके; लेन-देन का आकार पृष्ठ-संरेखित रिकॉर्ड का उपयोग करके mmap()/ msync()और निम्न-स्तर I का उपयोग करके; / O, fdatasync()और एक ही फ़ाइल के लिए कई समवर्ती फ़ाइल डिस्क्रिप्टर (एक डिस्क्रिप्टर और प्रति ट्रांजेक्शन) अन्यथा " । लिनक्स-विशिष्ट ओपन फाइल विवरण लॉक ( ) fcntl(), F_OFD_पिछले एक के साथ बहुत उपयोगी हैं।
सांकेतिक पशु

22

चूंकि एप्लिकेशन का लेखन () पहले ही त्रुटि के बिना वापस आ जाएगा, इसलिए लगता है कि आवेदन में त्रुटि की रिपोर्ट करने का कोई तरीका नहीं है।

मैं इससे सहमत नहीं हूँ। writeयदि लेखन केवल पंक्तिबद्ध है, तो त्रुटि के बिना वापस आ सकता है, लेकिन त्रुटि को अगले ऑपरेशन पर रिपोर्ट किया जाएगा जिसे डिस्क पर वास्तविक लेखन की आवश्यकता होगी, इसका मतलब है कि अगले पर fsync, संभवतः निम्नलिखित लिखने पर अगर सिस्टम कैश को फ्लश करने का निर्णय लेता है और कम से कम अंतिम फ़ाइल के करीब।

यही कारण है कि संभव लेखन त्रुटियों का पता लगाने के लिए करीब के रिटर्न मूल्य का परीक्षण करने के लिए आवेदन करना आवश्यक है।

यदि आपको वास्तव में चतुर त्रुटि प्रसंस्करण करने में सक्षम होने की आवश्यकता है, तो आपको यह मान लेना चाहिए कि अंतिम सफल के बाद से जो कुछ भी लिखा गया था वह विफल fsync हो सकता है और उस सब में कम से कम कुछ विफल हो गया है।


4
हाँ, मुझे लगता है कि यह नाखून। यह वास्तव में सुझाव देगा कि आवेदन को अंतिम पुष्टि-सफल होने के बाद से fsync()या close()फ़ाइल -EIOसे write(), fsync()या यदि यह हो जाए तो अपने सभी काम फिर से करने चाहिए close()। खैर, यह मजेदार है।
क्रेग रिंगर

1

write(२) आपकी अपेक्षा से कम प्रदान करता है। एक सफल write()कॉल के शब्दार्थ के बारे में पुरुष पृष्ठ बहुत खुला है :

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

हम यह निष्कर्ष निकाल सकते हैं कि एक सफल write()का मतलब है कि डेटा कर्नेल की बफरिंग सुविधाओं तक पहुंच गया है। यदि बफर को जारी रखने में विफल रहता है, तो फ़ाइल डिस्क्रिप्टर की एक बाद की पहुंच त्रुटि कोड वापस कर देगी। अंतिम उपाय के रूप में हो सकता है close()close(2) सिस्टम कॉल के मैन पेज में निम्नलिखित वाक्य हैं:

यह बहुत संभव है कि पहले write(2) ऑपरेशन की त्रुटियों को पहले अंतिम close() पर सूचित किया जाए ।

आपके आवेदन लागू करने के लिए की जरूरत है डेटा दूर बारे में इसका इस्तेमाल करने की है fsync/ fsyncdataएक नियमित आधार पर:

fsync()स्थानान्तरण ("फ़्लश") सभी संशोधित डेटा इन-कोर डेटा (यानी, संशोधित बफ़र कैश पेज के लिए) फ़ाइल को डिस्क डिस्क्रिप्टर fd द्वारा डिस्क डिवाइस (या अन्य स्थायी स्टोरेज डिवाइस) में भेजा जाता है ताकि सभी बदली गई जानकारी पुनः प्राप्त की जा सके सिस्टम के दुर्घटनाग्रस्त होने या फिर रिबूट होने के बाद भी। इसमें यदि मौजूद हो तो डिस्क कैश को लिखना या फ्लशिंग करना शामिल है। जब तक डिवाइस रिपोर्ट नहीं करता कि ट्रांसफर पूरा हो गया है तब तक कॉल ब्लॉक हो जाती है।


4
हाँ, मैं जानता हूँ कि fsync()आवश्यक है। लेकिन विशिष्ट मामले में जहां गिरी एक आई / ओ त्रुटि के कारण पृष्ठों खो देता है में होगा fsync()विफल? इसके बाद किन परिस्थितियों में वह सफल हो सकता है?
क्रेग रिंगर

मैं कर्नेल स्रोत को नहीं जानता। आइए I / O मुद्दों पर fsync()रिटर्न -EIOमानें (यह अन्यथा के लिए क्या अच्छा होगा?)। तो डेटाबेस जानता है कि पिछले लेखन में से कुछ विफल रहा है और पुनर्प्राप्त मोड में जा सकता है। क्या यह वह नहीं है जो आप चाहते हैं? आपके अंतिम प्रश्न की प्रेरणा क्या है? क्या आप जानना चाहते हैं कि कौन सा लेखन विफल हुआ या आगे के उपयोग के लिए फ़ाइल डिस्क्रिप्टर को पुनर्प्राप्त करना चाहिए?
fzgregor

आदर्श रूप से एक DBMS क्रैश रिकवरी (सभी उपयोगकर्ताओं को लात मारना और अस्थायी रूप से दुर्गम या कम से कम रीड-ओनली) बनना पसंद नहीं करेगा यदि वह संभवतः इससे बच सकता है। लेकिन भले ही कर्नेल हमें "बाइट्स 4096 से 8191 की fd X" बता सके, यह पता लगाना कठिन होगा कि क्रैश रिकवरी के बिना क्या (फिर से) लिखे जाएं। तो मुझे लगता है कि मुख्य सवाल किसी भी अधिक निर्दोष परिस्थितियों में जहां देखते हैं कि क्या है fsync()वापस आ सकते हैं -EIOजहां यह है पुन: प्रयास करने के लिए सुरक्षित, और अगर यह अंतर बताने में संभव है।
क्रेग रिंगर

निश्चित दुर्घटना वसूली अंतिम उपाय है। लेकिन जैसा कि आपने पहले ही कहा था कि ये मुद्दे बहुत कम होने की उम्मीद है। इसलिए, मैं किसी भी रिकवरी में जाने के साथ कोई समस्या नहीं देखता हूं -EIO। यदि प्रत्येक फ़ाइल डिस्क्रिप्टर का उपयोग केवल एक समय में एक थ्रेड द्वारा किया जाता है, तो यह थ्रेड अंतिम पर वापस जा सकता है fsync()और write()कॉल को फिर से कर सकता है। लेकिन फिर भी, अगर वे write()केवल एक सेक्टर का हिस्सा लिखते हैं तो अनमॉडिफाइड हिस्सा अभी भी भ्रष्ट हो सकता है।
फजेलर

1
आप सही हैं कि क्रैश रिकवरी में जाना उचित है। आंशिक रूप से भ्रष्ट क्षेत्रों के लिए, DBMS (PostgreSQL) पूरे पृष्ठ की एक छवि को पहली बार संग्रहीत करता है, क्योंकि यह किसी कारण से किसी भी चेकपॉइंट के बाद इसे छूता है, इसलिए यह ठीक होना चाहिए :)
क्रेग रिंगर

0

जब आप फ़ाइल खोलते हैं तो O_SYNC ध्वज का उपयोग करें। यह सुनिश्चित करता है कि डेटा डिस्क पर लिखा गया है।

यदि यह आपको संतुष्ट नहीं करेगा, तो कुछ भी नहीं होगा।


17
O_SYNCप्रदर्शन के लिए एक बुरा सपना है। इसका अर्थ है कि डिस्क I / O तब तक एप्लिकेशन कुछ और नहीं कर सकता है जब तक कि यह I / O थ्रेड्स को बंद न कर दे। आप यह भी कह सकते हैं कि बफ़र्ड I / O इंटरफ़ेस असुरक्षित है और सभी को AIO का उपयोग करना चाहिए। निश्चित रूप से चुपचाप खो गया लेखन बफ़र्ड I / O में स्वीकार्य नहीं हो सकता है?
क्रेग रिंगर

3
( O_DATASYNCउस संबंध में केवल थोड़ा बेहतर है)
क्रेग रिंगर

@ क्रेगिंगर आपको एआईओ का उपयोग करना चाहिए यदि आपके पास यह आवश्यकता है और किसी भी प्रकार के प्रदर्शन की आवश्यकता है। या बस एक DBMS का उपयोग करें; यह आपके लिए सब कुछ संभालता है।
डेमी

10
@Demi यहाँ आवेदन एक dbms (postgresql) है। मुझे यकीन है कि आप कल्पना कर सकते हैं कि बफ़र्ड I / O के बजाय AIO का उपयोग करने के लिए संपूर्ण एप्लिकेशन को फिर से लिखना व्यावहारिक नहीं है। और न ही यह आवश्यक होना चाहिए।
क्रेग रिंगर

-5

करीब के वापसी मूल्य की जाँच करें। बंद विफल हो सकता है, जबकि बफ़र किए गए लेखन सफल होते हैं।


8
ठीक है, हम शायद ही रहना चाहता हूँ open()ing और close()हर कुछ सेकंड फ़ाइल ing। इसलिए हमारे पास fsync()...
क्रेग रिंगर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.