数据库设计

tron的数据库设计是在基于leveldb的基础上抽像自己的相关业务,设计出基于自己的业务数据操作类。
有两大块分别是:

  1. 内存数据库
  2. 持久化数据库

从两个角度进行梳理:

  1. 代码设计
  2. 业务应用
  • 代码结构
    • 代码结构设计
    • 接口关系、主要功能方面着手了解。
  • 业务使用
    • generateBlock
    • pushBlock
    • pushTransaction
    • switchFork

一、ITronChainBase 存储操作接口

数据库相关的接口比较多,有些关系结构看起来功能相似,反而不容易区分出差异。下面按照功能职责划分。

作用:提供基础数据库基础操作方法。
ITronChainBase.png

  1. ITronChainBase: 顶层接口,提供如:putgetdelete等相关操作,包含两个抽象类。
  2. TronStoreWithRevoking: 抽象类,提供构造器中包含初始化方法。各个Store的初始化从这里开始,包含36个Store,如:
    a. AccountStore
    b. BlockStore
    c. BlockIndexStore
  3. TronDatabase:抽象类,提供的方法大部分为抽像方法,这样的话,实现类可以根据需要,自行实现自己业务相关的数据库操作。
    构造器也提供初始化功能,其构造器中的初始化 DbSourceInter,直接操作数据库。
    子类如:
    a. KhaosDatabase:内存数据库
    b. CheckTmpStore:并没有真正实现ITronChainBase接口方法 ,接口方法都是空实现。
    从设计上看,只是将跟数据库操作相关的类,使用相同接口进行规范。

二、RevokingDatabase 可回退数据库

RevokingDatabase.png

作用:提供基于可回退的数据库操作。提供内存快照功能,管理指针对Session的处理:

  1. 快照创建
  2. 数据合并
  3. 快照销毁

相关接口、类如下:

  1. RevokingDatabase: 接口,提供buildSession、merge等操作。
  2. RevokingStore:快照存储v1版本,实现类主要功能依赖抽像类AbstractRevokingStore
  3. SnapshotManager:快照存储v2版本,当前主要实现类。
  4. v1、v2区别:
    a. db.version = 1, 方式:向数据库写入数据之前,将修改过程保存到内存,然后再将数据写到数据库,当需要数据回退的时候,根据内存保存的数据修改过程,还原数据库中的数据。
    b. db.version = 2,方式:向数据库写入的数据都是不可回退的数据,而将可回退的数据写入到内存,当可回退的数据变成不可回退的时候即固化,再将数据写入到数据库。
    c. db.version=1 这种方式,如果服务出现异常,回退就丢失了,不利于回退。

1.SnapshotManager 内存快照管理

作用:维护session状态,包括:创建、合并、刷盘等操作。
顶层接口:RevokingDatabase,数据库模型:构建内存快照链表。
使用可回退数据库模型TronStoreWithRevoking,未固化块均存在于内存快照中,固化块存在于底层数据库LevelDB或者rocksDB中。
基于SnapshotRoot快照模型

基于SnapshotRoot快照模型.png

每一个Snapshot就是内存当中的一个数据结构,是当前整个数据库的状态,是整个数据库的状态。
就是说,每一个Snapshot保存的是某个块高的快照状态。

怎么理解?
首先,状态只跟区块有关,每个Snapshot对应一个当前区块状态,如:
Snapshot1 对应 block=10001。

比如:block=10001的状态是:
account1=100
account2=222

Snapshot2 对应 block=10002。

比如:block=10001的状态是:
account1=110
account2=333

至于为什么是这样对应,为什么要这样设计,这样设计的用意、为了解决什么问题、好处、可能出现的问题,后面讲。