内容

名称

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://www.gnu.org.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访问模式和可选修饰符的按位或。访问模式是以下之一

GDBM_READER

以只读模式打开现有数据库文件。

GDBM_WRITER

以读写模式打开现有数据库文件。

GDBM_WRCREAT

如果数据库文件存在,则以读写模式打开它。如果不存在,则先创建它并以读写模式打开。

GDBM_NEWDB

创建新的数据库并以读写模式打开它。如果数据库已存在,则先截断它。

可以将多个修饰符与访问模式进行 OR 操作。大多数修饰符很少需要(有关完整列表,请参阅 https://www.gnu.org.ua/software/gdbm/manual/Open.html),但其中一个值得一提。GDBM_NUMSYNC 修饰符与 GDBM_NEWDB 一起使用时,指示 GDBM扩展(称为numsync)格式创建数据库。这种格式最适合容错实现。有关更多信息,请参见下面的 CRASH TOLERANCE

$mode 参数是用于创建新数据库文件的文件模式。使用八进制常量或 Fcntl 模块中的 S_I* 常量的组合。如果 $flagsGDBM_NEWDBGDBM_WRCREAT,则使用此参数。

成功时,tie 返回一个 GDBM_File 类的对象。失败时,它返回 undef。建议始终检查返回值,以确保您的哈希已成功与数据库文件关联。有关示例,请参见下面的 ERROR HANDLING

静态方法

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://www.gnu.org.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。

数据库方法

close

$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 的第四个参数的标志。

dbname

$db->dbname;

返回数据库名称(即传递给 tie 的第三个参数)。

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://www.gnu.org.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

如果恢复所有权和/或模式失败,则发出“呱呱”声。

从转储文件重新创建数据库的通常顺序是

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

崩溃容错

崩溃容错是一项新功能,在操作系统和文件系统的适当支持下,可以保证在发生崩溃(例如断电、操作系统内核崩溃等)后,可以恢复数据库的逻辑一致的最新状态。

崩溃容错支持出现在 gdbm 版本 1.21 中。其背后的理论在 Terence Kelly 的“Crashproofing the Original NoSQL Key-Value Store”中进行了解释 (https://queue.acm.org/detail.cfm?id=3487353)。gdbm 实现的详细讨论可以在 GDBM 手册 (https://www.gnu.org.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://www.gnu.org.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

发生了系统错误。检查 **$!** 获取详细信息。有关错误代码及其含义的完整列表,请参阅

GDBM_SNAPSHOT_SAME

两个快照文件的模式和修改日期完全相同。这只会发生在标准格式的数据库中。

GDBM_SNAPSHOT_SUSPICIOUS

两个快照的 *numsync* 计数器相差超过一个。最可能的原因是程序员错误:这两个参数引用了属于不同数据库文件的快照。

AVAILABILITY

gdbm 可从任何 GNU 档案中获取。主站点是 `ftp.gnu.org`,但强烈建议您使用众多镜像站点之一。您可以从 http://www.gnu.org/order/ftp.html 获取镜像站点列表。

SECURITY AND PORTABILITY

GDBM 文件在不同平台之间不可移植。如果您希望通过网络传输 GDBM 文件,请先将其转储为可移植格式。

不要接受来自不可信来源的 GDBM 文件。

GDBM 对损坏数据库的鲁棒性高度依赖于其版本。1.15 之前的版本没有实现任何有效性检查,因此损坏或恶意制作的数据库文件会导致 perl 崩溃,甚至暴露安全漏洞。1.15 到 1.20 之间的版本逐渐加强了对无效输入的防御。最后,1.21 版本经过了广泛的模糊测试,证明了其能够承受任何类型的输入而不会崩溃。

SEE ALSO

perl(1)DB_File(3)perldbmfiltergdbm(3)https://www.gnu.org.ua/software/gdbm/manual.html