区块链数据分类
平台账本数据存储支持多账本,每个账本的数据是分开存储的,每条链对应一套账本,每个服务节点会维护多套账本,每套账本包含以下元素:
- 账本编号:快速查询存在哪些账本
- 账本数据:实际的区块数据存储
- 区块索引:快速查询区块/交易
- 状态数据:存储的所有对象(键)的最新值
- 历史数据:跟踪存储对象(键)的历史
每个服务节点会维护4份数据,它们分别是:
- idStore,存储账本编号。用户快速查询节点存在哪些账本
- blockdb,存储区块文件
- stateDB,存储状态数据
- historyDB,存储状态数据的版本变化
账本编号
账本编号的数据存储在数据库中,只是记录了有哪些账本,创建新的账本会检查是否有相同的账本编号存在,保证了全局唯一性。账本编号库并不存储与区块相关的数据,区别于账本数据。
账本数据
账本数据是以二进制文件的形式存储的,每个账本数据存储在不同的目录下。账本数据的所有操作都是通过区块文件管理器实现的。
状态数据
状态数据记录的是交易执行的结果,最新的状态代表了通道上键的最新值,链码调用根据当前状态数据执行交易。为了提高链码执行的效率,所有键的最新值都存储在状态数据库中。状态数据只是区块链交易的索引视图,因此可以随时根据区块链重新生成。状态数据在服务节点启动时候自动恢复,重新构建完成后才接受新的交易。
历史数据
历史数据记录了每个状态数据的历史信息。每份历史信息由以下四部分组成:
- namespace: 命令空间,代表不同的链码,每个链码的数据是隔离的。
- writeKey: 写入数据的键
- blockNo: 写入数据的区块编号
- tranNo:写入数据所在区块内的交易序号
从四部分信息可以看出来,历史信息记录的最细的粒度就是交易,如果一次交易中多次对同一个writeKey更新数据,则只会存储第一次数据为准。更新区块信息的时候,会同步更新检查点信息,保存的内容是最新的区块高度和最大的交易序号,检查点信息会判断历史信息的状态是否是最新的。