无法从大型Berkeley DB文件中读取数据

时间:2012-04-06 18:55:56

标签: java perl berkeley-db

我正在尝试从大小>的Berkeley DB文件中读取数据。 12 GB并写入键值对中的文本文件。 但我无法这样做,因为我的过程在阅读了2600万条记录后停止了。 我尝试使用perl / ruby​​读取文件,但似乎记录的对象只能容纳2600万条记录。 有没有办法拆分BDB文件,然后读取记录?或者,如果我能找到一些方法来读取块中的数据然后处理它们?

1 个答案:

答案 0 :(得分:0)

没有你的代码,几乎没有什么可说的。您使用的是BerkeleyDB模块吗?该文件是否为哈希表的形式?你用Perl和Java标记了你的问题;你试过用Java以及Perl和Ruby来读文件吗?

你可能已经使用Perl达到虚拟内存限制,因为与C等中的简单字符串相比,哈希和标量值的支持数据是巨大的。

我怀疑是否有分割Berkely DB文件的方法,但要求很简单,只能用几行C编写。

如果您需要帮助,请显示您的Perl代码,或者用C或Java重写它。一旦数据作为键/值对存储在文本文件中,Perl就可以轻松处理它。


修改

我建议您使用DB_File模块提供的本机Berkely DB API。这样可以避免将所有数据保存在单个Perl哈希中,并且很可能解决您的问题。

此代码编译但仅在最小数据上进行测试,因为我显然无法访问您的数据库文件。

use strict;
use warnings;

use DB_File;

my $db = tie my %dbhash, 'DB_File', 'TestId', O_RDONLY, 0644, $DB_BTREE
    or die "Cannot open file 'TestId' :$!\n";

my $file = 0;
my $fh;
my $c = 0;

my ($key, $val);

my $stat = $db->seq($key, $val, R_FIRST);
while ($stat == 0) {

  if (not $fh or $c == 10_000_000) {
    $file++;
    open $fh, '>', "TestId$file.txt" or die $!;
    $c = 0;
  }

  print $fh "$key|$val\n";
  $c++;
}
continue {
  $stat = $db->seq($key, $val, R_NEXT);
}
close $fh or die $!;

undef $db;
untie %dbhash;

修改2

如果使用DB_File的方法存在同样的问题,我建议您尝试使用BerkeleyDB模块。它由同一个作者编写,但有一个看起来独立于Perl哈希的界面。

以下是我之前尝试使用替代模块的等效代码。它在最小的数据集上工作正常。如果这也无法工作,那么我建议你在模块的作者Paul Marquess

中删除一行
use strict;
use warnings;

use BerkeleyDB;

my $db = BerkeleyDB::Btree->new(-Filename => 'TestId')
    or die "Cannot open file 'TestId' :$!\n";

my $cursor = $db->db_cursor;

my $file = 0;
my $fh;
my $c = 0;

my $key = my $val = "";

my $stat = $cursor->c_get($key, $val, DB_FIRST);
while ($stat == 0) {

  if (not $fh or $c == 10_000_000) {
    $file++;
    open $fh, '>', "TestId$file.txt" or die $!;
    $c = 0;
  }

  print $fh "$key|$val\n";
  $c++;
}
continue {
  $stat = $cursor->c_get($key, $val, DB_NEXT);
}

close $fh or die $!;