Storable.pm - 保存到非截断文件时出现损坏

9
在我的生产环境中,我们遇到了一个我们认为是由Storable.pm创建的损坏的可存储哈希。我无法在开发环境中复制这种行为,这使得确诊变得困难。
这段代码已经运行了很长时间,而导致它出错的改变是从哈希表中删除数据。直到最近,哈希表的大小要么保持不变,要么增加。
该文件以读写方式打开,然后store_fd将数据写入文件。由于哈希表现在(有时)更小,所以它只会向这个2000字节的文件写入1000字节。剩下的1000字节是旧的、垃圾数据。在我的测试用例中,当我检索哈希表时,垃圾数据被忽略,正如预期的那样。
open( $sf, "+< $self->{mod_state_filename}" );
flock( $sf, LOCK_EX );
$self->{mod_state} = fd_retrieve($sf);
delete ($self->{mod_state}{"somekey"});
seek( $sf, 0, 0 );
store_fd( $self->{mod_state}, $sf );
flock( $sf, LOCK_UN )
close($sf);

我的问题:

  1. 这个代码应该可以工作,还是必须要截断文件?
  2. 存储的哈希值是否使用了某种文件终止符?如果有,它是什么?
  3. 上面的代码,在我的测试用例中删除、添加、删除、添加,运行得非常完美。你能否提供任何可能会因为未截断文件而导致失败的测试用例序列呢?(我知道这是一个非常模糊的问题,所以请随意忽略它。)

2
为什么不使用Storable内置的存储和检索函数呢?Storable还支持锁定。http://search.cpan.org/~ams/Storable-2.24/Storable.pm#ADVISORY_LOCKING - singingfish
我知道它确实存在,但我没有编写这段代码。在我继承它多年之前,它就是这样的(除了删除)。我考虑更改代码以使用Storable::locking,但我不知道它是否会(并且怀疑它可能不会)解决我的问题。(我可以尝试,但问题只出现在生产环境中,所以我需要确定修复方案。我不能试错)我不认为我的问题是由于锁定引起的。 - Brock
2个回答

1

我不确定Storable对于尾随垃圾的处理效果如何,但是添加该语句肯定不会有害。

truncate $sf, tell($sf);

在调用store_fd之后,消除所有关于它现在和将来是否能够处理它的疑虑。


彼得,不要叫我雪莉。我同意,但我想先在测试条件下确认一下,所以才问的。 - Brock

0

抱歉,我以为我已经更新了。

我向perl5-porters提出了问题,并得到了答案。

由于我无法在测试中复制该问题,因此我尚未实施修复,因此不想将其推送到我的生产环境中,我的解决方法目前更安全。

根据perl5-porters的答案,截断绝对是一个好主意。

我不知道有人已经(或可以!)对我的问题提出悬赏。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接