Skip to content

回复:RFC:随发布压缩包附带区块链 1-74000? ​

原始发布页

打开来源页面
查看 1 个交叉存档

看起来,你似乎更倾向于认定所有地方都有问题,而实际情况并非如此。

写入区块索引是很轻量的工作。构建交易索引则需要对每个区块进行多得多的随机访问。我怀疑,读取所有先前的 txin 才是速度慢的原因。读取缓存会对此有所帮助。最好让数据库来做这件事。也许它有一个设置,可以指定使用多少缓存内存。

引用

  1. 比特币应该在程序启动时打开数据库,而不只是打开环境,并在程序关闭时关闭数据库。

已经是这样做的。参见 CDB。(例如)CTxDB 对象的生命周期只是为了支持数据库事务,并在关闭时判断是否仍有任何对象正在使用数据库。

引用

而且,除此之外,比特币还会强制执行数据库检查点,把所有事务从日志推入主数据库。

如果它真这么做,速度会慢得多。按设计,它应该只每分钟或每 500 个区块执行一次:

if (strFile == "blkindex.dat" && IsInitialBlockDownload() && nBestHeight % 500 != 0) nMinutes = 1; dbenv.txn_checkpoint(0, nMinutes, 0);

也许应该加上这个: if (!fReadOnly) dbenv.txn_checkpoint(0, nMinutes, 0);

引用

  1. 对于初始区块下载,应该每 N 条记录提交一次事务,而不是每条记录都提交。我建议 N=1000。

提交事务就意味着刷盘吗?这让我很意外。我原以为,封装在事务中的数据库操作会像任何其他数据库操作一样被记入日志。许多数据库应用程序几乎需要把每一对操作都封装在一个事务中,例如把钱从一个账户转到另一个账户。(借记 a,贷记 b)我无法想象它们会被要求自行把所有操作都分批积攒起来。

在以下两种情况下,情况 1 会刷盘一次,而情况 2 会刷盘两次吗?

情况 1:

write
write
write
write
checkpoint

情况 2:

begin transaction
write
write
commit transaction
begin transaction
write
write
commit transaction
checkpoint

扭曲我们的数据库使用方式不会是正确的办法。解决之道会在 BDB 设置和缓存上。

英文原文 ​

展开英文原文

It seems like you're inclined to assume everything is wrong more than is actually so.

Writing the block index is light work. Building the tx index is much more random access per block. I suspect reading all the prev txins is what's slow. Read caching would help that. It's best if the DB does that. Maybe it has a setting for how much cache memory to use.

Quote

  1. bitcoin should be opening databases, not just environment, at program startup, and closing database at program shutdown.

Already does that. See CDB. The lifetime of the (for instance) CTxDB object is only to support database transactions and to know if anything is still using the database at shutdown.

Quote

And, additionally, bitcoin forces a database checkpoint, pushing all transactions from log into main database.

If it was doing that it would be much slower. It's supposed to be only once a minute or 500 blocks:

if (strFile == "blkindex.dat" && IsInitialBlockDownload() && nBestHeight % 500 != 0) nMinutes = 1; dbenv.txn_checkpoint(0, nMinutes, 0);

Probably should add this: if (!fReadOnly) dbenv.txn_checkpoint(0, nMinutes, 0);

Quote

  1. For the initial block download, txn commit should occur once every N records, not every record. I suggest N=1000.

Does transaction commit imply flush? That seems surprising to me. I assume a database op wrapped in a transaction would be logged like any other database op. Many database applications need to wrap almost every pair of ops in a transaction, such as moving money from one account to another. (debit a, credit b) I can't imagine they're required to batch all their stuff up themselves.

In the following cases, would case 1 flush once and case 2 flush twice?

case 1: write write write write checkpoint

case 2: begin transaction write write commit transaction begin transaction write write commit transaction checkpoint

Contorting our database usage will not be the right approach. It's going to be BDB settings and caching.

为历史保存,为中文读者整理。每篇档案均附来源与英文原文。