目錄

名稱

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 內建的 tieGDBM 資料庫與 Perl 雜湊關聯

tie %hash, 'GDBM_File', $filename, $flags, $mode;

在此,$filename 是要開啟或建立的資料庫檔案名稱。$flags存取模式 和選用 修改器 的位元 OR。存取模式為下列其中之一

GDBM_READER

以唯讀模式開啟現有的資料庫檔案。

GDBM_WRITER

以讀寫模式開啟現有的資料庫檔案。

GDBM_WRCREAT

如果資料庫檔案存在,則以讀寫模式開啟。如果不存在,則先建立再以讀寫模式開啟。

GDBM_NEWDB

建立新的資料庫並以讀寫模式開啟。如果資料庫已存在,則先將其截斷。

可以將多個修改器 OR 到存取模式。大多數修改器很少需要 (請參閱 https://gnu.dev.org.tw.ua/software/gdbm/manual/Open.html 以取得完整清單),但有一個值得一提。GDBM_NUMSYNC 修改器與 GDBM_NEWDB 搭配使用時,會指示 GDBM延伸 (稱為 numsync) 格式建立資料庫。此格式最適合耐用實作。請參閱下方的 耐用性 以取得更多資訊。

$mode 參數是建立新資料庫檔案的檔案模式。請使用八進位常數或 Fcntl 模組中 S_I* 常數的組合。如果 $flagsGDBM_NEWDBGDBM_WRCREAT,則會使用此參數。

如果成功,tie 會傳回 GDBM_File 類別的物件。如果失敗,則會傳回 undef。建議總是檢查傳回值,以確保您的雜湊已成功與資料庫檔案關聯。請參閱下方的 錯誤處理 以取得範例。

靜態方法

GDBM_version

$str = GDBM_File->GDBM_version;
@ar = GDBM_File->GDBM_version;

傳回底層 libgdbm 函式庫的版本號碼。在純量內容中,傳回格式化為字串的函式庫版本

MINOR.MAJOR[.PATCH][ (GUESS)]

其中 MINORMAJORPATCH 是版本號碼,而 GUESS 是猜測等級 (請參閱下方)。

在清單內容中,傳回清單

( MINOR, MAJOR, PATCH [, GUESS] )

如果libgdbm版本為 1.8.3 或更早版本,則GUESS元件只會存在。這是因為libgdbm的早期版本未包含其版本資訊,而GDBM_File模組必須實作某些猜測才能確定它。GUESS是在字串內容中的文字描述,以及在清單內容中表示猜測有多粗略的正數。可能的數值為

1 - 精確猜測

保證主版本和次要版本號碼正確。實際的修補程式等級很可能猜測正確,但可能比指示的少 1-2 個。

2 - 近似

保證主版本和次要版本號碼正確。修補程式等級設定為上限。

3 - 粗略猜測

保證版本不會比MAJOR.MINOR更新。

錯誤處理

$GDBM_File::gdbm_errno

在數值內容中參照時,會擷取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";
    }
}

gdbm_check_syserr

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可確保資料庫檔案會關閉並解除鎖定。

errno

$db->errno

傳回與此資料庫相關聯的最後錯誤狀態。在字串內容中,傳回錯誤的可讀描述。另請參閱上方的$GDBM_File::gdbm_errno變數。

syserrno

$db->syserrno

傳回與此資料庫相關聯的最後系統錯誤狀態(C errno變數),

strerror

$db->strerror

傳回此資料庫中發生的最後錯誤的文字描述。

clear_error

$db->clear_error

清除錯誤狀態。

needs_recovery

$db->needs_recovery

如果資料庫需要復原,則傳回 true。

reorganize

$db->reorganize;

重新整理資料庫。

sync

$db->sync;

將資料庫的最新變更與其磁碟副本同步。

count

$n = $db->count;

傳回資料庫中的金鑰數量。

flags

$db->flags;

傳回作為tie的第 4 個引數傳遞的旗標。

dbname

$db->dbname;

傳回資料庫名稱(即tie的第 3 個引數)。

cache_size

$db->cache_size;
$db->cache_size($newsize);

傳回該資料庫的內部GDBM快取大小。

呼叫時附有引數,則將大小設定為$newsize

block_size

$db->block_size;

傳回資料庫的區塊大小。

sync_mode

$db->sync_mode;
$db->sync_mode($bool);

傳回自動同步模式的狀態。呼叫時附有引數,則根據 $bool 是true還是false來啟用或停用同步模式。

當同步模式開啟(true)時,對資料庫的任何變更都會立即寫入磁碟。這可確保在發生任何無法預見的錯誤(例如停電)時資料庫的一致性,但會大幅降低操作速度。

預設同步模式為關閉。

centfree

$db->centfree;
$db->centfree($bool);

傳回中央自由區塊池的狀態(0 - 已停用,1 - 已啟用)。

有參數時,會變更其狀態。

預設情況下,中央自由區塊池已停用。

coalesce

$db->coalesce;
$db->coalesce($bool);

mmap

$db->mmap;

如果已啟用記憶體對應,則傳回 true。

如果在沒有記憶體對應支援的情況下編譯 libgdbm 函式庫,此方法會croak

mmapsize

$db->mmapsize;
$db->mmapsize($newsize);

如果已啟用記憶體對應,則傳回記憶體對應的大小。有參數時,會將大小設定為 $newsize

如果在沒有記憶體對應支援的情況下編譯 libgdbm 函式庫,此方法會croak

recover

$db->recover(%args);

從失敗的資料庫中復原資料。%args 是選用的,且可以包含下列金鑰

err => sub { ... }

詳細錯誤回報的程式碼參考。遇到錯誤時,recover 會呼叫此子程式,並提供一個參數 - 錯誤描述。

backup => \$str

在復原前建立資料庫的備份副本,並在 $str 中傳回其檔案名稱。

max_failed_keys => $n

允許失敗金鑰的最大數量。如果實際數量等於 $nrecover 會中止並傳回錯誤。

max_failed_buckets => $n

允許失敗區塊的最大數量。如果實際數量等於 $nrecover 會中止並傳回錯誤。

max_failures => $n

復原期間允許的最大失敗數量。

stat => \%hash

%hash 中傳回復原統計資料。傳回時,會存在下列金鑰

recovered_keys

成功復原的金鑰數量。

recovered_buckets

成功復原的區塊數量。

failed_keys

無法擷取的金鑰數量。

failed_buckets

無法擷取的儲存區數量。

convert

$db->convert($format);

變更$db所引用的資料庫檔案格式。

從版本 1.20 開始,gdbm 支援兩種資料庫檔案格式:標準延伸。前者是傳統的資料庫格式,由先前的gdbm版本使用。延伸格式包含額外的資料,建議在耐用應用程式中使用。

https://gnu.dev.org.tw.ua/software/gdbm/manual/Numsync.html,討論兩種格式。

$format 參數設定新的所需資料庫格式。它是GDBM_NUMSYNC,將資料庫從標準格式轉換為延伸格式,以及0,將資料庫從延伸格式轉換為標準格式。

如果資料庫已採用要求的格式,函式會傳回成功,而不執行任何動作。

dump

$db->dump($filename, %options)

$filename中建立資料庫檔案的傾印。此類檔案可以用作備份副本,或透過網路傳送以在另一部電腦上重新建立資料庫。若要從傾印檔案建立資料庫,請使用load方法。

GDBM 支援兩種傾印格式:舊的二進位和新的ascii。二進位格式無法跨架構移植,且已不建議使用。它支援向後相容性。ascii 格式可移植,且儲存有關檔案的額外元資料。它在gdbm版本 1.11 中引入,且為建議的傾印格式。dump方法預設建立 ascii 傾印。

如果已存在指定檔案,函式會拒絕覆寫,並會發出錯誤訊息。如果檔案不存在,它會以由目前的umask修改的模式0666建立。

可以使用下列%options變更這些預設值

binary => 1

二進位格式建立傾印。

mode => MODE

將檔案模式設定為MODE

overwrite => 1

靜默覆寫現有檔案。

load

$db->load($filename, %options)

將傾印檔案$filename中的資料載入資料庫$db。檔案必須先前使用dump方法建立。檔案格式會自動辨識。預設情況下,如果傾印包含資料庫中已存在的金鑰,函式會發出錯誤訊息。它會靜默略過無法復原資料庫模式和/或擁有權的失敗。可以使用下列%options變更這些預設值

replace => 1

取代現有金鑰。

restore_mode => 0 | 1

如果為0,請勿嘗試將資料庫檔案的模式還原為儲存在傾印檔中的模式。

restore_owner => 0 | 1

如果為0,請勿嘗試將資料庫檔案的所有者還原為儲存在傾印檔中的所有者。

strict_errors => 1

如果無法還原所有權和/或模式,請發出 Croak。

從傾印檔重新建立資料庫的通常順序為

my %hash;
my $db = tie %hash, 'GDBM_File', 'a.db', GDBM_NEWDB, 0640;
$db->load('a.dump');

CRASH TOLERANCE

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);

crash_tolerance_status

GDBM_File->crash_tolerance_status;

此靜態方法會傳回防崩潰支援的狀態。非零值表示已編譯防崩潰並獲得作業系統支援。

failure_atomic

$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 靜態方法。

latest_snapshot

$file = GDBM_File->latest_snapshot($even, $odd);

($file, $error) = GDBM_File->latest_snapshot($even, $odd);

給定兩個快照名稱(先前在呼叫 failure_atomic 時使用),此方法會選取適合資料庫復原的快照,也就是包含最新資料庫快照的檔案。

在純量內容中,它會傳回選取的檔案名稱,或是在失敗時傳回 undef

在陣列內容中,它會傳回兩個元素的清單:檔案名稱和狀態碼。成功時,檔案名稱會被定義,而代碼會是 GDBM_SNAPSHOT_OK。發生錯誤時,檔案名稱會是 undef,而狀態會是下列其中一個

GDBM_SNAPSHOT_BAD

兩個快照檔案都不適用。這表示當機發生在呼叫 failure_atomic 完成之前。在這種情況下,最好回溯至資料檔案的安全備份副本。

GDBM_SNAPSHOT_ERR

發生系統錯誤。檢查 $! 以取得詳細資料。請參閱 <https://gnu.dev.org.tw.ua/software/gdbm/manual/Crash-recovery.html> 以取得完整的錯誤代碼清單及其意義。

GDBM_SNAPSHOT_SAME

兩個快照檔案的檔案模式和修改日期完全相同。這只會發生在標準格式的資料庫中。

GDBM_SNAPSHOT_SUSPICIOUS

兩個快照的numsync 計數器相差超過 1。最可能的原因是程式設計師錯誤:兩個參數所指的快照屬於不同的資料庫檔案。

AVAILABILITY

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)perldbmfiltergdbm(3)https://gnu.dev.org.tw.ua/software/gdbm/manual.html