原始文献 / 论坛帖 / Re: RFC: ship block chain 1-74000 with release tarballs?

Re: RFC: ship block chain 1-74000 with release tarballs?

Bitcointalk · 2010-11-29 20:19:12 UTC

AuthorSatoshi Nakamoto
TitleRe: RFC: ship block chain 1-74000 with release tarballs?
Date2010-11-29 20:19:12 UTC
ForumBitcointalk · 原文

你好像总比实际情况更倾向于认定一切都坏了。

写区块索引是轻活。建交易索引才是每区块大量随机访问的工作。我怀疑读所有前序 txin 才是慢的原因。读缓存能帮上忙。最好让 DB 自己做。也许它有缓存用多少内存的设置。

引用自(……):1)比特币应该在程序启动时打开数据库,而不只是打开环境,程序退出时关闭数据库。
已经是这样了。看 CDB。(比如)CTxDB 对象的生命周期只是为了支持数据库事务,以及在退出时知道还有没有东西在用数据库。

引用自(……):而且,比特币会强制做数据库 checkpoint,把日志里的所有事务推进主数据库。
如果真是这样会慢得多。正常应该是一分钟或 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);

引用自(……):2)初始区块下载时,txn commit 应该每 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.

Quote1) 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.

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

Quote2) 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.