getindexinfo:四类可选索引的进度一页账 图 1
getindexinfo:四类可选索引的进度一页账 · 图 1

比特币核心节点默认只维护两块基础存储:区块文件和 UTXO 集合。除此之外的一切”翻旧账”能力都来自可选索引——-txindex、-coinstatsindex、-blockfilterindex,以及 v31.0 新加的 -txospenderindex。开了哪个、追到多高、有没有追完,v31.1 的 getindexinfo 一条命令就能看全。

它返回什么

getindexinfo 可以不带参数,也可以带一个可选的 index_name 字符串参数过滤某一个索引。返回是一个对象:每个已启用的索引以自己的名字为键,值里只有两个字段。

  • synced:布尔值,这个索引是否已追平当前链 tip。
  • best_block_height:整数,索引已经处理到的高度。

一个容易踩的细节:没启用的索引不会出现在结果里。查询一个未开启的索引名不是报错,而是得到一个不含该键的对象。脚本里如果用”查不到就是坏了”的逻辑会误判,应当区分”没开”和”没追平”两种状态。

账本上可能出现的四个名字

  • txindex:交易索引,让 getrawtransaction 能按 txid 直接取链上任意历史交易。开它要多花几十 GB 磁盘。
  • coinstatsindex:UTXO 集合统计索引,gettxoutsetinfo 有它才快,也是 dumptxoutset 快速出快照的依赖之一。
  • blockfilterindex:按 BIP 158 紧凑过滤器的索引。它按网络分键(例如主网、测试链各一条),-blockfilterindex=1 会同时给所有启用网络建索引。
  • txospenderindex:v31.0 新增的输出花费索引,记录”哪个输入被哪笔交易花掉”,为 gettxspendingprevout 提供查表服务。这个索引与修剪模式互斥,开了修剪节点启动会直接报 Prune mode is incompatible with -txospenderindex. 而拒绝启动。

什么时候真正需要它

第一次开索引:索引是从创世块开始后台回放的,追平之前相关 RPC 会报”index not available”之类的错误。挂个循环每几分钟跑一次 getindexinfo,看 best_block_height 是否逼近 getblockcount,比凭感觉等要踏实。

节点崩溃重启后:索引与区块库的一致性由节点自己校验,重启初期 synced 为 false 可能只是还在追,也可能是在重建;结合 debug.log 里的索引线程日志判断,不要急着动手删文件。

用 loadtxoutset 导入快照的前后:快照同步期间活动链和后台验证链并存,索引状态值得留一份基线记录,出问题时好对比。

另外,-reindex 的官方帮助说明写得很直白:它会擦掉链状态和区块索引,并且”also wipe and rebuild other optional indexes that are active”——重索引等于把账本上所有启用中的索引一起推倒重来,getindexinfo 会先清零再慢慢爬。

读数的边界

synced 为 true 只代表这个节点的这个索引追平了自己看到的链,不代表全网共识、更不代表历史数据”正确”——索引只是对区块文件的重排,信的是底层区块库本身。多节点部署时,每个节点各查各的,getindexinfo 没有任何跨节点聚合语义。

三条使用守则

守则一:把 getindexinfo 当体检单而不是开关。它只读状态、不改变状态,循环调用没有成本,重启后、升级后、补建索引后各留一份快照,比事后翻日志快得多。守则二:进度和数据可得性是两件事。best_block_height 说的是索引处理到了哪个高度,不代表对应高度的区块数据一定还在盘上——txindex 与 txospenderindex 干脆不允许和修剪模式共存,启动就会被拦下;其余索引与修剪的组合,读历史数据前先自己验证可得性。守则三:过滤参数按名字精确匹配。带 index_name 时只返回同名索引,名字对不上不会报错、只会空手而归——脚本里与其猜键名,不如先拉全量结果再挑键,键名以返回为准。

最后提醒一个视角:这四类索引都是可丢弃的派生数据,坏了、歪了,正确的处理是关掉重建或整体重索引,而不是手工修文件。getindexinfo 的读数只回答追没追上,不回答对不对,对账要靠抽样比对几个已知交易或已知高度的结果。

风险提示:本文为节点运维与接口使用说明,索引会显著增加磁盘与内存占用,操作前请自行备份数据目录;本文不构成任何投资建议。