GDBM_File - Perl5 存取 gdbm 函式庫。
use GDBM_File;
[$db =] tie %hash, 'GDBM_File', $filename, GDBM_WRCREAT, 0640
or die "$GDBM_File::gdbm_errno";
# Use the %hash...
$e = $db->errno;
$e = $db->syserrno;
$str = $db->strerror;
$bool = $db->needs_recovery;
$db->clear_error;
$db->reorganize;
$db->sync;
$n = $db->count;
$n = $db->flags;
$str = $db->dbname;
$db->cache_size;
$db->cache_size($newsize);
$n = $db->block_size;
$bool = $db->sync_mode;
$db->sync_mode($bool);
$bool = $db->centfree;
$db->centfree($bool);
$bool = $db->coalesce;
$db->coalesce($bool);
$bool = $db->mmap;
$size = $db->mmapsize;
$db->mmapsize($newsize);
$db->recover(%args);
untie %hash ;
GDBM_File 是個模組,允許 Perl 程式使用 GNU gdbm 函式庫提供的功能。如果您打算使用這個模組,您真的應該準備好一份 GDBM 手冊。手冊可以在線上取得,網址為 https://gnu.dev.org.tw.ua/software/gdbm/manual。
大多數的 gdbm 函式都可透過 GDBM_File 介面取得。
與 Perl 內建的雜湊不同,在使用 each
迭代 GDBM_File 繫結雜湊時,無法安全地 delete
目前的項目。這是 gdbm 函式庫的限制。
使用 Perl 內建的 tie 將 GDBM 資料庫與 Perl 雜湊關聯
tie %hash, 'GDBM_File', $filename, $flags, $mode;
在此,$filename 是要開啟或建立的資料庫檔案名稱。$flags 是 存取模式 和選用 修改器 的位元 OR。存取模式為下列其中之一
以唯讀模式開啟現有的資料庫檔案。
以讀寫模式開啟現有的資料庫檔案。
如果資料庫檔案存在,則以讀寫模式開啟。如果不存在,則先建立再以讀寫模式開啟。
建立新的資料庫並以讀寫模式開啟。如果資料庫已存在,則先將其截斷。
可以將多個修改器 OR 到存取模式。大多數修改器很少需要 (請參閱 https://gnu.dev.org.tw.ua/software/gdbm/manual/Open.html 以取得完整清單),但有一個值得一提。GDBM_NUMSYNC 修改器與 GDBM_NEWDB 搭配使用時,會指示 GDBM 以 延伸 (稱為 numsync) 格式建立資料庫。此格式最適合耐用實作。請參閱下方的 耐用性 以取得更多資訊。
$mode 參數是建立新資料庫檔案的檔案模式。請使用八進位常數或 Fcntl 模組中 S_I*
常數的組合。如果 $flags 是 GDBM_NEWDB 或 GDBM_WRCREAT,則會使用此參數。
如果成功,tie 會傳回 GDBM_File 類別的物件。如果失敗,則會傳回 undef。建議總是檢查傳回值,以確保您的雜湊已成功與資料庫檔案關聯。請參閱下方的 錯誤處理 以取得範例。
$str = GDBM_File->GDBM_version;
@ar = GDBM_File->GDBM_version;
傳回底層 libgdbm 函式庫的版本號碼。在純量內容中,傳回格式化為字串的函式庫版本
MINOR.MAJOR[.PATCH][ (GUESS)]
其中 MINOR、MAJOR 和 PATCH 是版本號碼,而 GUESS 是猜測等級 (請參閱下方)。
在清單內容中,傳回清單
( MINOR, MAJOR, PATCH [, GUESS] )
如果libgdbm版本為 1.8.3 或更早版本,則GUESS元件只會存在。這是因為libgdbm的早期版本未包含其版本資訊,而GDBM_File模組必須實作某些猜測才能確定它。GUESS是在字串內容中的文字描述,以及在清單內容中表示猜測有多粗略的正數。可能的數值為
保證主版本和次要版本號碼正確。實際的修補程式等級很可能猜測正確,但可能比指示的少 1-2 個。
保證主版本和次要版本號碼正確。修補程式等級設定為上限。
保證版本不會比MAJOR.MINOR更新。
在數值內容中參照時,會擷取gdbm_errno變數的目前值,也就是描述任何gdbm資料庫上最近操作狀態的數值代碼。每個數值代碼都有與之關聯的符號名稱。如需這些代碼的完整清單,請參閱 https://gnu.dev.org.tw.ua/software/gdbm/manual/Error-codes.html。請注意,此清單包含為gdbm最新版本定義的所有錯誤代碼。根據GDBM_File建置的實際程式庫版本,其中一些代碼可能不存在。
在字串內容中,$gdbm_errno會傳回錯誤的人類可讀描述。必要時,此描述會包含$!的值。這使得它可以在診斷訊息中使用。例如,通常的繫結順序為
tie %hash, 'GDBM_File', $filename, GDBM_WRCREAT, 0640
or die "$GDBM_File::gdbm_errno";
以下更複雜的範例說明如果資料庫檔案權限禁止讀寫存取,您可以如何改為使用唯讀模式
use Errno qw(EACCES);
unless (tie(%hash, 'GDBM_File', $filename, GDBM_WRCREAT, 0640)) {
if ($GDBM_File::gdbm_errno == GDBM_FILE_OPEN_ERROR
&& $!{EACCES}) {
if (tie(%hash, 'GDBM_File', $filename, GDBM_READER, 0640)) {
die "$GDBM_File::gdbm_errno";
}
} else {
die "$GDBM_File::gdbm_errno";
}
}
if (gdbm_check_syserr(gdbm_errno)) ...
如果系統錯誤號碼 ($!) 提供有關錯誤原因的更多資訊,則傳回 true。
$db->close;
關閉資料庫。一般來說,您只需執行untie即可。但是,如果您已明確將tie的結果指定給變數,而且希望將資料庫釋出給其他使用者,則需要使用此函數。請考慮下列程式碼
$db = tie %hash, 'GDBM_File', $filename, GDBM_WRCREAT, 0640;
# Do something with %hash or $db...
untie %hash;
$db->close;
在此範例中,單獨執行untie是不夠的,因為資料庫仍會由$db參照,因此資料庫檔案仍會保持鎖定狀態。呼叫$db->close可確保資料庫檔案會關閉並解除鎖定。
$db->errno
傳回與此資料庫相關聯的最後錯誤狀態。在字串內容中,傳回錯誤的可讀描述。另請參閱上方的$GDBM_File::gdbm_errno變數。
$db->syserrno
傳回與此資料庫相關聯的最後系統錯誤狀態(C errno
變數),
$db->strerror
傳回此資料庫中發生的最後錯誤的文字描述。
$db->clear_error
清除錯誤狀態。
$db->needs_recovery
如果資料庫需要復原,則傳回 true。
$db->reorganize;
重新整理資料庫。
$db->sync;
將資料庫的最新變更與其磁碟副本同步。
$n = $db->count;
傳回資料庫中的金鑰數量。
$db->flags;
傳回作為tie的第 4 個引數傳遞的旗標。
$db->dbname;
傳回資料庫名稱(即tie的第 3 個引數)。
$db->cache_size;
$db->cache_size($newsize);
傳回該資料庫的內部GDBM快取大小。
呼叫時附有引數,則將大小設定為$newsize。
$db->block_size;
傳回資料庫的區塊大小。
$db->sync_mode;
$db->sync_mode($bool);
傳回自動同步模式的狀態。呼叫時附有引數,則根據 $bool 是true還是false來啟用或停用同步模式。
當同步模式開啟(true)時,對資料庫的任何變更都會立即寫入磁碟。這可確保在發生任何無法預見的錯誤(例如停電)時資料庫的一致性,但會大幅降低操作速度。
預設同步模式為關閉。
$db->centfree;
$db->centfree($bool);
傳回中央自由區塊池的狀態(0 - 已停用,1 - 已啟用)。
有參數時,會變更其狀態。
預設情況下,中央自由區塊池已停用。
$db->coalesce;
$db->coalesce($bool);
$db->mmap;
如果已啟用記憶體對應,則傳回 true。
如果在沒有記憶體對應支援的情況下編譯 libgdbm 函式庫,此方法會croak。
$db->mmapsize;
$db->mmapsize($newsize);
如果已啟用記憶體對應,則傳回記憶體對應的大小。有參數時,會將大小設定為 $newsize。
如果在沒有記憶體對應支援的情況下編譯 libgdbm 函式庫,此方法會croak。
$db->recover(%args);
從失敗的資料庫中復原資料。%args 是選用的,且可以包含下列金鑰
詳細錯誤回報的程式碼參考。遇到錯誤時,recover 會呼叫此子程式,並提供一個參數 - 錯誤描述。
在復原前建立資料庫的備份副本,並在 $str 中傳回其檔案名稱。
允許失敗金鑰的最大數量。如果實際數量等於 $n,recover 會中止並傳回錯誤。
允許失敗區塊的最大數量。如果實際數量等於 $n,recover 會中止並傳回錯誤。
復原期間允許的最大失敗數量。
在 %hash 中傳回復原統計資料。傳回時,會存在下列金鑰
$db->convert($format);
變更$db所引用的資料庫檔案格式。
從版本 1.20 開始,gdbm 支援兩種資料庫檔案格式:標準和延伸。前者是傳統的資料庫格式,由先前的gdbm版本使用。延伸格式包含額外的資料,建議在耐用應用程式中使用。
https://gnu.dev.org.tw.ua/software/gdbm/manual/Numsync.html,討論兩種格式。
$format 參數設定新的所需資料庫格式。它是GDBM_NUMSYNC,將資料庫從標準格式轉換為延伸格式,以及0,將資料庫從延伸格式轉換為標準格式。
如果資料庫已採用要求的格式,函式會傳回成功,而不執行任何動作。
$db->dump($filename, %options)
在$filename中建立資料庫檔案的傾印。此類檔案可以用作備份副本,或透過網路傳送以在另一部電腦上重新建立資料庫。若要從傾印檔案建立資料庫,請使用load方法。
GDBM 支援兩種傾印格式:舊的二進位和新的ascii。二進位格式無法跨架構移植,且已不建議使用。它支援向後相容性。ascii 格式可移植,且儲存有關檔案的額外元資料。它在gdbm版本 1.11 中引入,且為建議的傾印格式。dump方法預設建立 ascii 傾印。
如果已存在指定檔案,函式會拒絕覆寫,並會發出錯誤訊息。如果檔案不存在,它會以由目前的umask修改的模式0666建立。
可以使用下列%options變更這些預設值
$db->load($filename, %options)
將傾印檔案$filename中的資料載入資料庫$db。檔案必須先前使用dump方法建立。檔案格式會自動辨識。預設情況下,如果傾印包含資料庫中已存在的金鑰,函式會發出錯誤訊息。它會靜默略過無法復原資料庫模式和/或擁有權的失敗。可以使用下列%options變更這些預設值
取代現有金鑰。
如果為0,請勿嘗試將資料庫檔案的模式還原為儲存在傾印檔中的模式。
如果為0,請勿嘗試將資料庫檔案的所有者還原為儲存在傾印檔中的所有者。
如果無法還原所有權和/或模式,請發出 Croak。
從傾印檔重新建立資料庫的通常順序為
my %hash;
my $db = tie %hash, 'GDBM_File', 'a.db', GDBM_NEWDB, 0640;
$db->load('a.dump');
Crash tolerance 是一項新功能,在作業系統和檔案系統提供適當支援的情況下,保證在發生崩潰(例如停電、作業系統核心恐慌等)後,可以復原資料庫最近的邏輯一致狀態。
Crash tolerance 支援出現在 gdbm 版本 1.21 中。其背後的理論由 Terence Kelly 在「Crashproofing the Original NoSQL Key-Value Store」中說明(https://queue.acm.org/detail.cfm?id=3487353)。gdbm 實作的詳細說明可在 GDBM 手冊中找到(https://gnu.dev.org.tw.ua/software/gdbm/manual/Crash-Tolerance.html)。下列資訊說明 Perl 介面。
為了獲得最大的穩健性,我們建議對防崩潰資料庫使用延伸資料庫格式。若要建立延伸格式的資料庫,請在開啟資料庫時使用 GDBM_NEWDB|GDBM_NUMSYNC,例如
$db = tie %hash, 'GDBM_File', $filename,
GDBM_NEWDB|GDBM_NUMSYNC, 0640;
若要將現有資料庫轉換為延伸格式,請使用上述說明的 convert 方法,例如
$db->convert(GDBM_NUMSYNC);
GDBM_File->crash_tolerance_status;
此靜態方法會傳回防崩潰支援的狀態。非零值表示已編譯防崩潰並獲得作業系統支援。
$db->failure_atomic($even, $odd)
啟用資料庫 $db 的防當機功能,參數是兩個檔案的路徑名稱,這些檔案將會建立並填入資料庫檔案的快照。呼叫此方法時,這兩個檔案不可存在,並且必須與資料庫檔案位於同一個檔案系統中。此檔案系統必須支援reflink 作業(https://gnu.dev.org.tw.ua/software/gdbm/manual/Filesystems-supporting-crash-tolerance.html>)。
成功呼叫 failure_atomic 之後,每次呼叫 $db-sync> 方法都會在其中一個檔案中建立資料庫檔案的有效率 reflink 快照;連續呼叫 sync 會在兩個檔案之間交替,因此有這些名稱。
當機後,可以使用這些檔案中最近建立的檔案來復原資料庫。若要選取正確的快照,請使用 latest_snapshot 靜態方法。
$file = GDBM_File->latest_snapshot($even, $odd);
($file, $error) = GDBM_File->latest_snapshot($even, $odd);
給定兩個快照名稱(先前在呼叫 failure_atomic 時使用),此方法會選取適合資料庫復原的快照,也就是包含最新資料庫快照的檔案。
在純量內容中,它會傳回選取的檔案名稱,或是在失敗時傳回 undef。
在陣列內容中,它會傳回兩個元素的清單:檔案名稱和狀態碼。成功時,檔案名稱會被定義,而代碼會是 GDBM_SNAPSHOT_OK。發生錯誤時,檔案名稱會是 undef,而狀態會是下列其中一個
兩個快照檔案都不適用。這表示當機發生在呼叫 failure_atomic 完成之前。在這種情況下,最好回溯至資料檔案的安全備份副本。
發生系統錯誤。檢查 $! 以取得詳細資料。請參閱 <https://gnu.dev.org.tw.ua/software/gdbm/manual/Crash-recovery.html> 以取得完整的錯誤代碼清單及其意義。
兩個快照檔案的檔案模式和修改日期完全相同。這只會發生在標準格式的資料庫中。
兩個快照的numsync 計數器相差超過 1。最可能的原因是程式設計師錯誤:兩個參數所指的快照屬於不同的資料庫檔案。
gdbm 可從任何 GNU 檔案庫取得。主站點為 ftp.gnu.org
,但強烈建議您使用眾多鏡像站點之一。您可以從 https://gnu.dev.org.tw/order/ftp.html 取得鏡像站點清單。
GDBM 檔案無法在不同平台之間攜帶。如果您希望透過網路傳輸 GDBM 檔案,請先將其傾印到可攜式格式。
請勿接受來自不受信任來源的 GDBM 檔案。
GDBM 對於損毀資料庫的健全性高度依賴於其版本。1.15 之前的版本未實作任何有效性檢查,因此損毀或惡意製作的資料庫檔案可能會導致 perl 崩潰,甚至造成安全漏洞。1.15 到 1.20 之間的版本逐漸針對無效輸入進行強化。最後,1.21 版本經過廣泛的模糊檢查,證明其能夠承受任何類型的輸入而不會崩潰。
perl(1)、DB_File(3)、perldbmfilter、gdbm(3)、https://gnu.dev.org.tw.ua/software/gdbm/manual.html。