MySQL数据库表
长安链支持选用MySQL作为账本存储引擎,节点启动会自动创建数据库,使用chainId作为数据库名,同时也会自动创建相应的表:
区块元信息表
CREATE TABLEblock_infos
(chain_id
varchar(128)COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT'链标识',block_height
bigint(20)NOT NULL COMMENT'区块高度',pre_block_hash
varbinary(128)DEFAULT NULL COMMENT'上个区块的散列值',block_hash
varbinary(128)DEFAULT NULL COMMENT'本区块的散列值',pre_conf_height
bigint(20)DEFAULT'0'COMMENT'上一次修改链配置的区块高度',block_version
varbinary(128)DEFAULT NULL COMMENT'区块版本',dag_hash
varbinary(128)DEFAULT NULL COMMENT'当前区块Dag的散列值',rw_set_root
varbinary(128)DEFAULT NULL COMMENT'区块读写集的Merkle Root',tx_root
varbinary(128)DEFAULT NULL COMMENT'区块交易的Merkle Root',block_timestamp
bigint(20)DEFAULT'0'COMMENT'区块时间戳',proposer
blob COMMENT'区块的生产者标识',consensus_args
blob COMMENT'共识参数',tx_count
bigint(20)DEFAULT'0'COMMENT'交易数量',signature
blob COMMENT'区块生成者的签名',dag
blob COMMENT'区块内交易的执行依赖顺序',
tx_idslongtext COLLATE utf8mb4_general_ci COMMENT'区块中交易ID列表',
additional_datalongblob COMMENT'区块产生以后附加的数据',PRIMARY KEY(
block_height),KEY
idx_hash(
block_hash`))ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
交易表
CREATE TABLEtx_infos
(chain_id
varchar(128)COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT'链标识',sender
blob COMMENT'交易发送者信息',tx_id
varchar(128)COLLATE utf8mb4_general_ci NOT NULL COMMENT'交易ID',tx_type
int(11)DEFAULT NULL COMMENT'交易类型',block_height
bigint(20)DEFAULT NULL COMMENT'交易所在区块高度',offset
int(11)DEFAULT NULL COMMENT'交易在区块链中的位置',timestamp
bigint(20)DEFAULT'0'COMMENT'链标识生成交易的unix时间戳',expiration_time
bigint(20)DEFAULT'0'COMMENT'交易过期的unix时间戳',request_payload
longblob COMMENT'交易的载荷数据',request_signature
blob COMMENT'交易发送者的签名',code
int(11)DEFAULT NULL COMMENT'交易执行结果的状态',contract_result
longblob COMMENT'合约执行返回结果',rw_set_hash
varbinary(128)DEFAULT NULL COMMENT'交易执行结果的读写集哈希',PRIMARY KEY(tx_id
),KEYidx_height_offset
(block_height
,offset
))ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
世界状态表
CREATE TABLEstate_infos
(contract_name
varchar(128)COLLATE utf8mb4_general_ci NOT NULL COMMENT'合约名',object_key
varbinary(128)NOT NULL DEFAULT''COMMENT'状态数据的key',object_value
longblob COMMENT'状态数据的value',block_height
bigint(20)DEFAULT NULL COMMENT'该状态数据被修改时的区块高度',updated_at
datetime(3)DEFAULT NULL COMMENT'该状态数据被修改时的节点本地时间',PRIMARY KEY(contract_name
,object_key
),KEYidx_height
(block_height
))ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
历史读写集表
CREATE TABLEhistory_infos
(tx_id
varchar(128)COLLATE utf8mb4_general_ci NOT NULL COMMENT'交易ID',rw_sets
longblob COMMENT'读写集序列化后的数据',block_height
bigint(20)DEFAULT NULL COMMENT'该交易所在的区块高度',PRIMARY KEY(tx_id
),KEYidx_height
(block_height
))ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
链上数据归档
归档需求
数据转移到独立存储
归档数据应具备可查询
归档数据还可以再恢复到区块链节点中
总体方案
1.对区块链中的账本数据分类
状态数据,仅存储最新的数据快照,无历史版本,数据量相对较少,而且数据是否冷热由业务决定,因此不考虑对状态数据做归档。
非状态数据,如:区块、交易、历史读写集,数据量大,随交易不断膨胀,而且只读不修改,适合对某个区块高度之前的数据做归档。
归档后节点对其他节点提供同步服务时,其他节点需选择已归档高度低于同步节点高度的节点
归档只对单个节点,由节点运营方发起对自己节点的归档
2.数据迁移
使用cmc依次查询节点的区块数据。
将区块备份到链外存储,链外存储可以是数据库或IPFS,当前已支持mysql,其他存储形式后续进行支持。
备份完成后,发起清理区块数据的系统合约调用。存储模块提供清理区块数据的接口,将交易、读写集数据删除,索引数据保持不变,也就是说仍然可以在链上判断区块、交易是否存在。
leveldb/badgerdb在清理数据后,需要主动调用compaction释放空间,采用异步执行。
3.数据查询
使用现有cmc查询区块或交易内容,也可通过使用sdk自定义开发的app(以下简称”custom app”)进行查询。
如果返回数据已归档,可以使用cmc(提供了查询链外归档数据的命令)或者custom app在链外存储中查询已归档数据。
4.数据恢复
cmc从链外存储获取归档数据,以区块为单位。
cmc以区块为单位向链上发起区块恢复请求,链上存储模块提供恢复区块数据的接口,以区块为单位,将归档后的payload数据复原。
cmc会自动更新链外存储中区块数据的状态为已恢复。
leveldb/badgerdb在恢复数据后,需要主动调用compaction释放空间,采用异步执行。