sync
sync(意指Synchronize,即「同步」)為UNIX操作系統的標準系統調用,功能為將內核文件系統緩衝區的所有數據(也即預定將通過低級I/O系統調用[註 1]寫入存儲介質的數據)寫入存儲介質(如硬盤)。
作為C語言的函數之一,sync()一般以void sync(void)的形式在unistd.h內聲明。該函數也可以從命令行執行sync命令的方式調用,同時在其他程序語言(如Perl)中也有名字與之相似的函數。
相關調用
UNIX中還有一些與sync相似的系統調用,如fsync與fdatasync。其中fsync負責寫入所有與特定文件描述符相關的緩衝區數據[1];fdatasync功能與fsync相似,但只負責寫入文件中被變更的數據,而不會修改文件的元數據(如文件屬性)[2]。
在系統中的應用
UNIX內核常會運行一些諸如flush或update之類的守護進程以將緩衝區數據寫入目標,而這些進程都要調用sync函數;在其他某些操作系統上這類任務由cron完成,而在Linux上負責者則為守護進程pdflush[3]。在卸載或以只讀權限重載文件系統時,系統也會將緩衝區內容寫入存儲介質。
數據庫中的應用
在對數據進行修改操作(包括增、刪、改)時,被修改的數據一般僅是暫存於基於內存的寫入緩存,而當掉電時這些修改便會丟失;而為保證數據的持久性,數據庫必須使用某些形式的sync,以確保修改的內容切實寫入非易失性存儲器,如PostgreSQL就使用了多種sync類調用(包括fsync與fdatasync)來達到這一目的[4]。
但是,對於旋轉尋道的硬盤來說,每次旋轉只能完成一項「提交」操作以將客戶端的修改寫入,因此每秒最多只能完成幾百次的「提交」操作[5];而若關閉fsync的限定來放寬要求,則可大幅提升性能,但同時也會帶來系統崩潰後數據庫損毀的潛在危險。有鑑於此,數據庫也使用囊括最近修改信息的日誌文件(一般比主題數據文件小得多)來保障可靠性:根據日誌文件,系統管理員可以在系統崩潰後準確地重做修改操作,以此即可減少對主要數據文件的sync操作。
相關爭議
在默認情況下,硬盤一般使用自有的易失性寫入緩存以緩存要寫入的數據。這一做法可以大幅提升性能,但同時也會帶來寫入操作丟失的潛在風險[6],不過開/關緩存的性能落差的確相當巨大,甚至連素來保守的FreeBSD社群為此也否決了在FreeBSD 4.3內默認關閉寫入緩存(即是說,修改後直接調用sync寫入硬盤)的提案[7]。
另外,在Firefox引入fsync調用的目的以保證其內嵌的SQLite數據庫的完整性後,便有人指出fsync降低了Firefox 3.0的性能[8];而Linux基金會的技術總監西奧多·周則在「Don't fear the fsync!」一文中討論了fsync的性能表現,並表示「沒有必要害怕fsync」[9]。
注釋
參考資料
- ^ fsync specification. [2012-12-28]. (原始內容存檔於2010-10-31).
- ^ fdatasync specification. [2012-12-28]. (原始內容存檔於2009-08-28).
- ^ The Linux Page Cache and pdflush. [2012-12-28]. (原始內容存檔於2009-11-24).
- ^ PostgreSQL Reliability and the Write-Ahead Log. [2012-12-28]. (原始內容存檔於2012-12-29).
- ^ Tuning PostgreSQL WAL Synchronization. [2012-12-28]. (原始內容存檔於2009-11-25).
- ^ Write-Cache Enabled?. [2012-12-28]. (原始內容存檔於2012-12-17).
- ^ FreeBSD Handbook — Tuning Disks. [2012-12-28]. (原始內容存檔於2012-12-24).
- ^ Mike Shaver. fsyncers and curveballs. [2012-12-28]. (原始內容存檔於2012-12-09).
- ^ Ts'o, Theodore. Don't fear the fsync!. 2009-03-16 [2017-09-06]. (原始內容存檔於2016-04-03).