欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

函數(shù)sync、fsync與fdatasync的總結(jié)整理(必看篇)

 更新時間:2016年12月24日 11:25:44   投稿:jingxian  
下面小編就為大家?guī)硪黄瘮?shù)sync、fsync與fdatasync的總結(jié)整理(必看篇)。小編覺得挺不錯的。現(xiàn)在就分享給大家。也給大家做個參考。一起跟隨小編過來看看吧

一、術(shù)語解釋

臟頁:linux內(nèi)核中的概念,因為硬盤的讀寫速度遠(yuǎn)趕不上內(nèi)存的速度,系統(tǒng)就把讀寫比較頻繁的數(shù)據(jù)事先放到內(nèi)存中,以提高讀寫速度,這就叫高速緩存,linux是以頁作為高速緩存的單位,當(dāng)進(jìn)程修改了高速緩存里的數(shù)據(jù)時,該頁就被內(nèi)核標(biāo)記為臟頁,內(nèi)核將會在合適的時間把臟頁的數(shù)據(jù)寫到磁盤中去,以保持高速緩存中的數(shù)據(jù)和磁盤中的數(shù)據(jù)是一致的。

內(nèi)存映射:內(nèi)存映射文件,是由一個文件到一塊內(nèi)存的映射。Win32提供了允許應(yīng)用程序把文件映射到一個進(jìn)程的函數(shù) (CreateFileMapping)。內(nèi)存映射文件與虛擬內(nèi)存有些類似,通過內(nèi)存映射文件可以保留一個地址空間的區(qū)域,同時將物理存儲器提交給此區(qū)域,內(nèi)存文件映射的物理存儲器來自一個已經(jīng)存在于磁盤上的文件,而且在對該文件進(jìn)行操作之前必須首先對文件進(jìn)行映射。使用內(nèi)存映射文件處理存儲于磁盤上的文件時,將不必再對文件執(zhí)行I/O操作,使得內(nèi)存映射文件在處理大數(shù)據(jù)量的文件時能起到相當(dāng)重要的作用。

//摘錄自百度百科

延遲寫(delayed write): 傳統(tǒng)的UNIX實現(xiàn)在內(nèi)核中設(shè)有緩沖區(qū)高速緩存或頁面高速緩存,大多數(shù)磁盤I/O都通過緩沖進(jìn)行。 當(dāng)將數(shù)據(jù)寫入文件時,內(nèi)核通常先將該數(shù)據(jù)復(fù)制到其中一個緩沖區(qū)中,如果該緩沖區(qū)尚未寫滿,則 并不將其排入輸出隊列,而是等待其寫滿或者當(dāng)內(nèi)核需要重用該緩沖區(qū)以便存放其他磁盤塊數(shù)據(jù)時, 再將該緩沖排入到輸出隊列,然后待其到達(dá)隊首時,才進(jìn)行實際的I/O操作。這種輸出方式就被稱為延遲寫。

//摘錄自《UNIX環(huán)境高級編程第三版》P65

二、正文

延遲寫減少了磁盤讀寫次數(shù),但是卻降低了文件內(nèi)容的更新速度,使得欲寫到文件中的數(shù)據(jù)在一段時間內(nèi)并沒有寫到磁盤上。當(dāng)系統(tǒng)發(fā)生故障時,這種延遲可能造成文件更新內(nèi)容的丟失。為了保證磁盤上實際文件系統(tǒng)與緩沖區(qū)高速緩存中內(nèi)容的一致性,UNIX系統(tǒng)提供了sync、fsync和fdatasync三個函數(shù)。

1、sync函數(shù)

sync函數(shù)只是將所有修改過的塊緩沖區(qū)排入寫隊列,然后就返回,它并不等待實際寫磁盤操作結(jié)束。

通常稱為update的系統(tǒng)守護(hù)進(jìn)程會周期性地(一般每隔30秒)調(diào)用sync函數(shù)。這就保證了定期沖洗內(nèi)核的塊緩沖區(qū)。命令sync(1)也調(diào)用sync函數(shù)。

2、fsync函數(shù)

fsync函數(shù)只對由文件描述符filedes指定的單一文件起作用,并且等待寫磁盤操作結(jié)束,然后返回。

fsync可用于數(shù)據(jù)庫這樣的應(yīng)用程序,這種應(yīng)用程序需要確保將修改過的塊立即寫到磁盤上。

3、fdatasync函數(shù)

fdatasync函數(shù)類似于fsync,但它只影響文件的數(shù)據(jù)部分。而除數(shù)據(jù)外,fsync還會同步更新文件的屬性。

對于提供事務(wù)支持的數(shù)據(jù)庫,在事務(wù)提交時,都要確保事務(wù)日志(包含該事務(wù)所有的修改操作以及一個提交記錄)完全寫到硬盤上,才認(rèn)定事務(wù)提交成功并返回給應(yīng)用層。

4、fflush:標(biāo)準(zhǔn)IO函數(shù)(如fread,fwrite等)會在內(nèi)存中建立緩沖,該函數(shù)刷新內(nèi)存緩沖,將內(nèi)容寫入內(nèi)核緩沖,要想將其真正寫入磁盤,還需要調(diào)用fsync。(即先調(diào)用fflush然后再調(diào)用fsync,否則不會起作用)。fflush以指定的文件流描述符為參數(shù)(對應(yīng)以fopen等函數(shù)打開的文件流),僅僅是把上層緩沖區(qū)中的數(shù)據(jù)刷新到內(nèi)核緩沖區(qū)就返回,

因此相對于fsync而言不是很安全,還需要再調(diào)用一下fsync來把數(shù)據(jù)真正寫入硬盤。使用函數(shù)

int fileno(FILE *stream);

把文件流描述符(fp)轉(zhuǎn)換為文件描述符(fd),以方便fsync的調(diào)用,那么,在Linux操作系統(tǒng)上,怎樣才能保證數(shù)據(jù)被正確地寫入外部永久存儲介質(zhì)?

1. write不能滿足要求,需要fsync

對于write函數(shù),我們認(rèn)為該函數(shù)一旦返回,數(shù)據(jù)便已經(jīng)寫到了文件中。但是這種概念只是宏觀上的,一般情況下,對硬盤(或者其他持久存儲設(shè)備)文件的write操作,更新的只是內(nèi)存中的頁緩存(page cache),而臟頁不會立即更新到硬盤中,而是由操作系統(tǒng)統(tǒng)一調(diào)度,如flusher內(nèi)核線程在滿足一定條件時(一定時間間隔、內(nèi)存中
的臟頁達(dá)到一定比例)將臟頁面同步到硬盤上(放入設(shè)備的IO請求隊列)。因為write調(diào)用不會等到硬盤IO完成之后才返回,設(shè)想如果操作系統(tǒng)在write調(diào)用之后、硬盤同步之前崩潰,則數(shù)據(jù)可能丟失。雖然這樣的時間窗口很小,但是對于需要保證事務(wù)的持久化(durability)和一致性(consistency)的數(shù)據(jù)庫程序來說,write()所提供的“松散的異步語義”是不夠的,通常需要操作系統(tǒng)提供的同步IO(synchronized-IO)原語來保證:

函數(shù)原型:

int fsync(int fd); 

fsync的功能是確保文件fd所有已修改的內(nèi)容已經(jīng)正確同步到硬盤上,該調(diào)用會阻塞等待直到設(shè)備報告IO完成。

PS:如果采用內(nèi)存映射文件的方式進(jìn)行文件IO(使用mmap,將文件的page cache直接映射到進(jìn)程的地址空間,通過寫內(nèi)存的方式修改文件),也有類似的系統(tǒng)調(diào)用來確保修改的內(nèi)容完全同步到硬盤之上:

#incude <sys/mman.h>
int msync(void *addr, size_t length, int flags)

msync需要指定同步的地址區(qū)間,如此細(xì)粒度的控制似乎比fsync更加高效(因為應(yīng)用程序通常知道自己的臟頁位置),但實際上(Linux)kernel中有著十分高效的數(shù)據(jù)結(jié)構(gòu),能夠很快地找出文件的臟頁,使得fsync只會同步文件的修改內(nèi)容。

2. fsync與fdatasync區(qū)別

除了同步文件的修改內(nèi)容(臟頁),fsync還會同步文件的描述信息(metadata,包括size、訪問時間等等),因為文件的數(shù)據(jù)和metadata通常存在硬盤的不同地方,因此fsync至少需要兩次IO寫操作,多余的一次IO操作,根據(jù)Wikipedia的數(shù)據(jù),當(dāng)前硬盤驅(qū)動的平均尋道時間(Average seek time)大約是3~15ms,7200RPM硬盤的平均旋轉(zhuǎn)延遲(Average rotational latency)大約為4ms,因此一次IO操作的耗時大約為10ms左右。Posix同樣定義了fdatasync,放寬了同步的語義以提高性能:

int fdatasync(int fd);

fdatasync的功能與fsync類似,但是僅僅在必要的情況下才會同步,因此可以減少一次IO寫操作。

"fdatasync does not flush modified metadata unless that metadata is needed in order to allow a subsequent data retrieval to be corretly handled."

舉例來說,文件的尺寸(st_size)如果變化,是需要立即同步的,否則OS一旦崩潰,即使文件的數(shù)據(jù)部分已同步,由于metadata沒有同步,依然讀不到修改的內(nèi)容。而最后訪問時間(atime)/修改時間(mtime)是不需要每次都同步的,只要應(yīng)用程序?qū)@兩個時間戳沒有苛刻的要求,基本沒有問題。

補(bǔ)充:函數(shù)open的參數(shù)O_SYNC/O_DSYNC有著和fsync/fdatasync類似的含義:使每次write都會阻塞等待硬盤IO完成。

O_SYNC 使每次write等待物理I/O操作完成,包括由write操作引起的文件屬性更新所需的I/O。

O_DSYNC 使每次write等待物理I/O操作完成,但是如果該寫操作并不影響讀取剛寫入的數(shù)據(jù),則不需等待文件屬性被更新。

注意區(qū)別:

O_DSYNC和O_SYNC標(biāo)志有微妙的區(qū)別:

僅當(dāng)文件屬性需要更新以反映文件數(shù)據(jù)變化(例如,更新文件大小以反映文件中包含了更多數(shù)據(jù))時,O_DSYNC標(biāo)志才影響文件屬性。而設(shè)置O_SYNC標(biāo)志后,數(shù)據(jù)和屬性總是同步更新。當(dāng)文件用O_DSYN標(biāo)志打開,在重寫其現(xiàn)有的部分內(nèi)容時,文件時間屬性不會同步更新。于此相反,文件如果是用O_SYNC標(biāo)志打開的,那么對于該文件的每一次write都將在write返回前更新文件時間,這與是否改寫現(xiàn)有字節(jié)或追加文件無關(guān)。相對于fsync/fdatasync,這樣的設(shè)置不夠靈活,應(yīng)該很少使用。

3. 使用fdatasync優(yōu)化日志同步

為了滿足事務(wù)要求,數(shù)據(jù)庫的日志文件是常常需要同步IO的。由于需要同步等待硬盤IO完成,所以事務(wù)的提交操作常常十分耗時,成為性能的瓶頸。在Berkeley DB下,如果開啟了AUTO_COMMIT(所有獨立的寫操作自動具有事務(wù)語義)并使用默認(rèn)的同步級別(日志完全同步到硬盤才返回),寫一條記錄的耗時大約為5~10ms級別,基本和一次IO操作(10ms)的耗時相同。

我們已經(jīng)知道,在同步上fsync是低效的。但是如果需要使用fdatasync減少對metadata的更新,則需要確保文件的尺寸在write前后沒有發(fā)生變化。日志文件天生是追加型(append-only)的,總是在不斷增大,似乎很難利用好fdatasync。

Berkeley DB是處理日志文件的步驟:

1.每個log文件固定為10MB大小,從1開始編號,名稱格式為“l(fā)og.%010d"

2.每次log文件創(chuàng)建時,先寫文件的最后1個page,將log文件擴(kuò)展為10MB大小

3.向log文件中追加記錄時,由于文件的尺寸不發(fā)生變化,使用fdatasync可以大大優(yōu)化寫log的效率

4.如果一個log文件寫滿了,則新建一個log文件,也只有一次同步metadata的開銷

三、總結(jié)

1、如果是對所有的緩沖區(qū)發(fā)出寫硬盤的命令,應(yīng)該使用sync函數(shù),但應(yīng)該注意該函數(shù)僅僅只是把該命令放入隊列就返回了,在編程時需要注意。

2、如果是要把一個已經(jīng)打開的文件所做的修改提交到硬盤,應(yīng)調(diào)用fsync函數(shù),該函數(shù)會在數(shù)據(jù)實際寫入硬盤后才返回,因此是最安全最可靠的方式。

3、如果是針對一個已經(jīng)打開的文件流操作,則應(yīng)該首先調(diào)用fsync函數(shù)把修改同步到內(nèi)核緩沖區(qū),然后再調(diào)用fsync把修改真正的同步到硬盤。

四、附man手冊關(guān)于fsync,fdatasync部分

fsync() transfers ("flushes") all modified in-core data of (i.e., modified buffer cache pages for) the file referred to by the file

descriptor fd to the disk device (or other permanent storage device) so that all changed information can be retrieved even after the sys‐

tem crashed or was rebooted. This includes writing through or flushing a disk cache if present. The call blocks until the device

reports that the transfer has completed. It also flushes metadata information associated with the file (see stat(2)).

Calling fsync() does not necessarily ensure that the entry in the directory containing the file has also reached disk. For that an

explicit fsync() on a file descriptor for the directory is also needed.

fdatasync() is similar to fsync(), but does not flush modified metadata unless that metadata is needed in order to allow a subsequent

data retrieval to be correctly handled. For example, changes to st_atime or st_mtime (respectively, time of last access and time of last

modification; see stat(2)) do not require flushing because they are not necessary for a subsequent data read to be handled correctly. On

the other hand, a change to the file size (st_size, as made by say ftruncate(2)), would require a metadata flush.

The aim of fdatasync() is to reduce disk activity for applications that do not require all metadata to be synchronized with the disk.

Linux、unix在內(nèi)核中設(shè)有緩沖區(qū)、高速緩沖或頁面高速緩沖,大多數(shù)磁盤I/O都通過緩沖進(jìn)行,采用延遲寫技術(shù)。

sync:將所有修改過的快緩存區(qū)排入寫隊列,然后返回,并不等待實際寫磁盤操作結(jié)束;

fsync:只對有文件描述符制定的單一文件起作用,并且等待些磁盤操作結(jié)束,然后返回;

fdatasync:類似fsync,但它只影響文件的數(shù)據(jù)部分。fsync還會同步更新文件的屬性;

fflush:標(biāo)準(zhǔn)I/O函數(shù)(如:fread,fwrite)會在內(nèi)存建立緩沖,該函數(shù)刷新內(nèi)存緩沖,將內(nèi)容寫入內(nèi)核緩沖,要想將其寫入磁盤,還需要調(diào)用fsync。(先調(diào)用fflush后調(diào)用fsync,否則不起作用)。

以上就是小編為大家?guī)淼暮瘮?shù)sync、fsync與fdatasync的總結(jié)整理(必看篇)全部內(nèi)容了,希望大家多多支持腳本之家~

相關(guān)文章

  • 詳解如何設(shè)置CentOS 7開機(jī)自動獲取IP地址

    詳解如何設(shè)置CentOS 7開機(jī)自動獲取IP地址

    本例中以CentOS 7舉例說明如何設(shè)置Linux開機(jī)自動獲取IP地址和設(shè)置固定IP地址。具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-03-03
  • Linux下apache如何限制并發(fā)連接和下載速度

    Linux下apache如何限制并發(fā)連接和下載速度

    在Linux下限值A(chǔ)pache的并發(fā)連接數(shù)和下載速度需要用到一款A(yù)pache的擴(kuò)展模塊mod_limitipconn,下面我們就來討論mod_limitipconn的安裝使用方法
    2014-11-11
  • CentOS服務(wù)器中安裝FFmpeg的完整步驟

    CentOS服務(wù)器中安裝FFmpeg的完整步驟

    這篇文章主要給大家介紹了關(guān)于在CentOS服務(wù)器中安裝FFmpeg的相關(guān)資料,文中通過示例代碼以及圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • centos8 使用yum 安裝 mongodb 4.2的方法

    centos8 使用yum 安裝 mongodb 4.2的方法

    這篇文章主要介紹了centos8 使用yum 安裝 mongodb 4.2的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-10-10
  • Linux一行命令處理批量文件詳解

    Linux一行命令處理批量文件詳解

    這篇文章主要介紹了Linux一行命令處理批量文件詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-08-08
  • 基于 Ubuntu 的發(fā)行版上安裝微軟 TrueType 字體的教程

    基于 Ubuntu 的發(fā)行版上安裝微軟 TrueType 字體的教程

    這篇文章主要介紹了基于 Ubuntu 的發(fā)行版上安裝微軟 TrueType 字體的教程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04
  • linux文件上傳,給文件或目錄添加apache權(quán)限的方法

    linux文件上傳,給文件或目錄添加apache權(quán)限的方法

    下面小編就為大家?guī)硪黄猯inux文件上傳,給文件或目錄添加apache權(quán)限的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-11-11
  • 安裝ubuntu時黑屏的解決辦法(3種)

    安裝ubuntu時黑屏的解決辦法(3種)

    這篇文章主要介紹了安裝ubuntu時黑屏的解決辦法(3種),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • 解決VScode配置遠(yuǎn)程調(diào)試Linux程序的問題

    解決VScode配置遠(yuǎn)程調(diào)試Linux程序的問題

    這篇文章主要介紹了VScode配置遠(yuǎn)程調(diào)試Linux程序及問題解決辦法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • Linux服務(wù)器間文件實時同步的實現(xiàn)

    Linux服務(wù)器間文件實時同步的實現(xiàn)

    這篇文章主要介紹了Linux服務(wù)器間文件實時同步的實現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11

最新評論