2011-03-29 42 views
5

我想在許多聯網的計算機上有許多進程通過OpenAFS 1.4.12.1同時訪問同一個SQLite數據庫。寫入會很少,所以SQLite的單寫設計應該不成問題。與OpenAFS鎖定兼容的SQLite?

我想知道這是否可行。我在查找兩條關鍵信息時遇到了問題:

SQLite documentation指出「SQLite使用POSIX顧問鎖來在Unix上實現鎖定」。它還警告說「你最好的防禦措施是不使用SQLite處理網絡文件系統上的文件」。但是,它似乎沒有指定SQLite是僅使用全文件鎖定還是使用字節範圍鎖定。

我也很難找出OpenAFS 1.4.12.1支持哪些類型的鎖定。不幸的是這個unofficial source from 1998是我能找到的最好的資源。那時,支持全文件鎖定,但是字節範圍鎖定不是。

官方文檔只有this page,儘管它的友好標題實際上並沒有說明最新的OpenAFS是否支持POSIX字節範圍諮詢鎖定。編輯: 這是可能的嗎?如果是這樣,是否需要任何編譯時SQLite標誌?

回答

5

我一直在使用SQLite很長一段時間,並有處理一些鎖定問題的「財富」。我很確定SQLite默認情況下在Unix文件系統上使用字節範圍鎖。

更確切地說,它包含一些替代鎖定方法的代碼(例如使用flock()dotlock-style整個文件鎖)。當使用SQLITE_ENABLE_LOCKING_STYLE option進行編譯時,它會嘗試自動檢測底層文件系統的正確鎖定方法。

自動檢測代碼包含一些硬編碼的情況(例如「ufs」,「nfs」和「smbfs」),它們都不是AFS。如果沒有硬編碼的大小寫匹配,SQLite將嘗試使用fcntl()獲取文件的字節範圍鎖定。然後假設如果fcntl()調用成功,則字節範圍鎖定可用。

這裏是OpenAFS進來使事情有趣。顯然([1],[2],[3])OpenAFS有一個long躺在用戶空間應用程序關於字節範圍鎖的歷史。從openafs-1.4.14源代碼:

/* next line makes byte range locks always succeed, 
* even when they should block */ 
if (af->l_whence != 0 || af->l_start != 0 || af->l_len != 0) { 
    DoLockWarning(); 
    afs_PutFakeStat(&fakestate); 
    return 0; 
} 

在一個字:哎喲!

它允許字節範圍鎖定無論如何成功。在Linux上,它可能更糟糕:它使用內核基礎結構在相同系統的進程中提供字節範圍鎖。這意味着應用程序不能只分叉一個新進程並測試鎖定機制 - 字節範圍鎖定似乎工作正常,但卻無法保護遠程進程中的文件。

簡而言之:不能在OpenAFS中可靠地使用未經修改的SQLite。大多數其他網絡文件系統也有問題,因此建議完全避免網絡文件系統。

幾個可能的變通沒有特定的順序:

  • 使用適當的DBMS,例如PostgreSQL。如果有可能做到這一點,那麼從長遠來看,你會變得更好。

  • 如果您的應用程序實現了您自己的服務器,如果一個成熟的DBMS過度殺傷。

  • 在OpenAFS上將SQLite源代碼修改爲默認爲flock()。我不確定這是否可以正常工作,因爲OpenAFS的歷史悠久([1],[2]),即使使用普通的舊版本flock()也是如此,但在測試之前您不會知道。

  • 使用OpenAFS用戶空間實現自己的OpenAFS VFS for SQLite,而不是通過內核。

  • 試試你的運氣與另一個網絡文件系統。

無論你做什麼,你將不得不執行廣泛的測試,如果以任何方式涉及SQLite3和共享數據庫文件。

編輯:

評論者建議使用點鎖文件機制。我沒有深入研究OpenAFS源代碼,但乍一看似乎支持創建SQLite使用的dotlock文件的open(O_CREAT|O_EXCL)方法。如果它按照它的設想工作,那麼SQLite可能確實可以與OpenAFS一起使用,如果您強制它使用點鎖方法。

這就是說,在沒有將網絡文件系統的複雜性引入混合中的情況下,在常規的本地文件系統中,dotlocks已經足夠了 - 這就是爲什麼我沒有首先提出它的原因。

+0

+1確實。但是,假設AFS提供了原子文件創建,不會出現點鎖嗎? – janneb 2011-04-04 14:23:17

+0

@janneb:我檢查了OpenAFS源碼w.r.t. dotlocks。結果是令人鼓舞的 - 或者因爲任何涉及到斑點的事情都是令人鼓舞的。 – thkala 2011-04-04 16:22:50