# 鏁版嵁瀛樺偍

##  姒傝堪

瀛樺偍妯″潡璐熻矗鎸佷箙鍖栧瓨鍌ㄩ摼涓婄殑鍖哄潡銆佷氦鏄撱€佺姸鎬併€佸巻鍙茶鍐欓泦绛夎处鏈暟鎹紝骞跺澶栨彁渚涗笂杩版暟鎹殑鏌ヨ鍔熻兘銆傚尯鍧楅摼浠ュ尯鍧椾负鍗曚綅杩涜鎵归噺鐨勬暟鎹彁浜わ紝涓€娆″尯鍧楁彁浜や細娑夊強鍒板椤硅处鏈暟鎹殑鎻愪氦锛屾瘮濡傦細浜ゆ槗鎻愪氦锛岀姸鎬佹暟鎹慨鏀圭瓑锛屾墍浠ュ瓨鍌ㄦā鍧楅渶瑕佺淮鎶よ处鏈暟鎹殑鍘熷瓙鎬с€傞暱瀹夐摼鏀寔甯哥敤鐨勬暟鎹簱鏉ュ瓨鍌ㄨ处鏈暟鎹紝濡侹V鏁版嵁搴擄紙LevelDB銆丅adgerDB绛夛級銆佸垎甯冨紡鏁版嵁搴擄紙TikvDB绛夛級鍜屽叧绯诲瀷鏁版嵁搴擄紙MySQL銆乀DSQL鍜岃揪姊︾瓑锛夛紝涓氬姟鍙€夋嫨鍏朵腑浠绘剰涓€绉嶆暟鎹簱鏉ラ儴缃插尯鍧楅摼銆�

璐︽湰鏁版嵁涓昏鍒嗕负5绫伙細

1. 鍖哄潡鏁版嵁锛岃褰曞尯鍧楀厓淇℃伅鍜屼氦鏄撴暟鎹細
    - 鍖哄潡鍏冩暟鎹寘鎷細鍖哄潡澶淬€佸尯鍧桪AG銆佸尯鍧椾腑浜ゆ槗鐨則xid鍒楄〃锛宎dditionalData绛夛紱
    - 浜ゆ槗鏁版嵁锛屽嵆搴忓垪鍖栧悗鐨勪氦鏄撲綋锛屼负浜嗘彁渚涘鍗曠瑪浜ゆ槗鏁版嵁鐨勬煡璇紝鎵€浠ュ浜ゆ槗鏁版嵁杩涜浜嗗崟鐙瓨鍌ㄣ€�
2. 鐘舵€佹暟鎹紝璁板綍鏅鸿兘鍚堢害涓鍐欑殑閾句笂鐘舵€佹暟鎹紝鍗充笘鐣岀姸鎬併€�
3. 鍘嗗彶鏁版嵁锛岄暱瀹夐摼瀵规瘡绗斾氦鏄撳湪鎵ц杩囩▼涓殑鐘舵€佸彉鍖栧巻鍙层€佸悎绾﹁皟鐢ㄥ巻鍙层€佽处鎴峰彂璧蜂氦鏄撳巻鍙查兘鍙互杩涜璁板綍锛屽彲鐢ㄤ簬鍚庣画杩芥函浜ゆ槗銆佺姸鎬佹暟鎹殑鍙樿縼杩囩▼銆�
4. 鍚堢害鎵ц缁撴灉璇诲啓闆嗘暟鎹紝闀垮畨閾惧姣忕瑪浜ゆ槗鍦ㄦ墽琛岃繃绋嬩腑鐨勬墍璇诲啓鐨勭姸鎬佹暟鎹泦杩涜浜嗗崟鐙繚瀛橈紝鏂逛究鍏朵粬鑺傜偣杩涜蹇€熺殑鏁版嵁鍚屾銆�
5. 浜嬩欢鏁版嵁锛屽悎绾︽墽琛岃繃绋嬩腑浜х敓鐨勪簨浠舵棩蹇�

## 瀛樺偍妯″潡杩愯閫昏緫

閽堝涓婅堪5绫昏处鏈暟鎹紝闀垮畨閾惧垎鍒疄鐜颁簡5涓狣B绫伙紝鍒嗗埆鏄細Block DB銆丼tate DB銆丠istory DB銆丷esult DB鍜孋ontract Event DB銆傞噰鐢ㄥ涓暟鎹簱涔嬪悗锛屽氨闇€瑕佺淮鎶ゆ暟鎹簱涔嬮棿鐨勬暟鎹竴鑷存€э紝閬垮厤浠呮湁閮ㄥ垎鏁版嵁搴撴彁浜ゅ悗锛屽彂鐢熺▼搴忎腑鏂€屽鑷翠笉鍚屾暟鎹簱闂寸殑鏁版嵁涓嶄竴鑷达紝鍥犳锛岄暱瀹夐摼寮曞叆浜咮lock binary log缁勪欢鏉ユ寔涔呭寲瀛樺偍鍖哄潡鐨勫師濮嬪唴瀹癸紝鐢ㄤ簬閲嶅惎杩囩▼涓殑鏁版嵁鎭㈠锛岀被浼间簬鏁版嵁搴撲腑鐨勯鍐欏紡鏃ュ織(wal)鐨勫姛鑳姐€� 闇€瑕佹敞鎰忕殑鏄紝鍘嗗彶鏁版嵁銆佺粨鏋滄暟鎹苟涓嶆槸姣忎釜鑺傜偣蹇呴』淇濆瓨鐨勶紝鑺傜偣鍙互鏍规嵁鑷繁鐨勪笟鍔¢渶瑕佸湪閰嶇疆鏂囦欢涓惎鐢ㄦ垨鑰呭叧闂巻鍙叉暟鎹簱鍜岀粨鏋滄暟鎹簱銆�

![瀛樺偍妯″潡杩愯閫昏緫](../images/DataStorage-StorageStructure.jpg)

## 鍖哄潡鎻愪氦娴佺▼

1.  棣栧厛灏嗗簭鍒楀寲鍚庣殑鍖哄潡銆佽鍐欓泦鏁版嵁銆佷互鍙婃渶鏂扮殑鍖哄潡楂樺害鍐欏叆Block binary log锛岀敤浜庡紓甯镐腑鏂悗鐨勬暟鎹仮澶嶃€備负浜嗘彁楂樻€ц兘锛屽姞鍏ヤ竴灞俢ache锛屾柊鍖哄潡鎻愪氦璇锋眰鍦ㄦ洿鏂板畬Block binary log涔嬪悗锛屽啀灏嗗尯鍧楁暟鎹啓鍏ache锛屽湪鏇存柊瀹宭og鍜宑ache鍚庯紝鎻愪氦鍗冲彲杩斿洖锛岀敱鍚庡彴绾跨▼寮傛鏇存柊Block DB銆丼tate DB銆丆ontractEvent DB銆丠istory DB鍜孯esult DB銆�
2.  鍦˙lock DB涓褰曞尯鍧楀厓淇℃伅涓庝氦鏄撲俊鎭紝鍏朵腑浜ゆ槗淇℃伅浠xID浣滀负涓婚敭瀛樺偍锛屽尯鍧椾俊鎭互BlockHeight浣滀负涓婚敭瀛樺偍锛屽尯鍧楀厓淇℃伅涓彧璁板綍浜ゆ槗ID鍒楄〃锛屽悓鏃剁储寮旴lockHash鍒癇lockHeight鐨勬槧灏勫叧绯汇€侭lock DB涓澶栬褰曚簡褰撳墠鏈€鏂扮殑鍖哄潡楂樺害锛圠astBlockHeight锛変綔涓篶heckpoint锛岀敤浠ラ噸鍚悗鐨勬暟鎹仮澶嶃€�
3.  鍦⊿tate DB涓繚瀛榮tate鏁版嵁锛宬ey涓哄悎绾﹀悕涓庡璞′富閿殑缁勫悎锛�<contractName, ObjectKey>锛屽悓鏃惰褰曟渶鏂扮殑鍖哄潡楂樺害锛圠astBlockHeight锛変綔涓篶heckpoint銆�
4.  鍦℉istory DB涓褰曚氦鏄撲骇鐢熺殑涓夌绫诲瀷鐨勭储寮曪細
    1.  鐘舵€佸彉鏇村巻鍙诧紝浠�<contractName, ObjectKey锛孴xId>涓虹储寮�
    2.  鍚堢害璋冪敤鍘嗗彶锛屼互<contractName, TxId>涓虹储寮�
    3.  璐︽埛浜ゆ槗鍘嗗彶锛屼互<accountId,TxId>涓虹储寮�
5.  鍦≧esult DB涓褰曚氦鏄撶殑璇诲啓闆嗭紝璇诲啓闆嗕互TxID浣滀负key锛屽悓鏃惰褰曟渶鏂扮殑鍖哄潡楂樺害锛圠astBlockHeight锛変綔涓篶heckpoint銆�
6.  鍦–ontractEventDB涓褰曚笅浜ゆ槗缁撴灉鐨凟ventLog锛屽苟璁板綍鏈€鏂板尯鍧楅珮搴︿綔涓篶heckpoint銆�

## 璐︽湰鎭㈠娴佺▼

濡傛灉鍖哄潡姝e湪鎻愪氦杩囩▼涓紝鑺傜偣鍥犲紓甯搁€€鍑猴紝鑺傜偣鍦ㄤ笅娆″惎鍔ㄦ椂瀛樺偍妯″潡浼氳繘鍏ユ仮澶嶆祦绋嬶細

1. 鍒嗗埆浠嶣lock binary log銆丅lock DB銆丼tate DB銆丆ontractEvent DB銆丠istory DB銆丷esult DB涓幏鍙栨渶鏂扮殑鍖哄潡楂樺害锛屼互Block binary log涓殑鍖哄潡楂樺害浣滀负鍩哄噯楂樺害锛屽垽鏂叾浠朌B鏄惁钀藉悗鍩哄噯楂樺害銆�
2. 濡傛灉鏈夋煇涓狣B钀藉悗鍩哄噯楂樺害锛屽垯浠嶣lock binary log涓幏鍙栫己澶辩殑鍖哄潡鍙婅鍐欓泦锛屼緷娆℃彁浜ゅ埌钀藉悗DB涓€�
3. 鎵€鏈塂B鍚屾鍒板熀鍑嗛珮搴﹀悗锛屽瓨鍌ㄦā鍧楀惎鍔ㄥ畬鎴愶紝鑺傜偣杩涘叆姝e父娴佺▼銆�

## 瀛樺偍鎺ュ彛璇存槑

```go
// BlockchainStore provides handle to store instances
type BlockchainStore interface {
    StateSqlOperation
    SysContractQuery
    MemberQuery
    //InitGenesis 鍒濆鍖栧垱涓栧崟鍏冨埌鏁版嵁搴�
    InitGenesis(genesisBlock *store.BlockWithRWSet) error
    // PutBlock commits the block and the corresponding rwsets in an atomic operation
    PutBlock(block *common.Block, txRWSets []*common.TxRWSet) error

    // GetBlockByHash returns a block given its hash, or returns nil if none exists.
    GetBlockByHash(blockHash []byte) (*common.Block, error)

    // BlockExists returns true if the black hash exist, or returns false if none exists.
    BlockExists(blockHash []byte) (bool, error)

    // GetHeightByHash returns a block height given its hash, or returns nil if none exists.
    GetHeightByHash(blockHash []byte) (uint64, error)

    // GetBlockHeaderByHeight returns a block header by given its height, or returns nil if none exists.
    GetBlockHeaderByHeight(height uint64) (*common.BlockHeader, error)

    // GetBlock returns a block given its block height, or returns nil if none exists.
    GetBlock(height uint64) (*common.Block, error)

    // GetLastConfigBlock returns the last config block.
    GetLastConfigBlock() (*common.Block, error)
    //GetLastChainConfig return the last chain config
    GetLastChainConfig() (*configPb.ChainConfig, error)
    // GetBlockByTx returns a block which contains a tx.
    GetBlockByTx(txId string) (*common.Block, error)

    // GetBlockWithRWSets returns a block and the corresponding rwsets given
    // its block height, or returns nil if none exists.
    GetBlockWithRWSets(height uint64) (*store.BlockWithRWSet, error)

    // GetTx retrieves a transaction by txid, or returns nil if none exists.
    GetTx(txId string) (*common.Transaction, error)
    //GetTxWithRWSet return tx and its rw set
    GetTxWithRWSet(txId string) (*common.TransactionWithRWSet, error)
    //GetTxInfoWithRWSet return tx and tx info and rw set
    GetTxInfoWithRWSet(txId string) (*common.TransactionInfoWithRWSet, error)
    //GetTxWithInfo get tx and tx block information
    GetTxWithInfo(txId string) (*common.TransactionInfo, error)
    // TxExists returns true if the tx exist, or returns false if none exists.
    TxExists(txId string) (bool, error)
    // TxExistsInFullDB returns true and the latest committed block height in db if the tx exist,
    // or returns false and math.MaxUint64 if none exists.
    TxExistsInFullDB(txId string) (bool, uint64, error)
    // TxExistsInIncrementDB returns true if the tx exist from starHeight to the latest committed block,
    // or returns false if none exists.
    TxExistsInIncrementDB(txId string, startHeight uint64) (bool, error)
    // TxExistsInIncrementDBState returns
    // first return value is true if the tx exist from starHeight to the
    // latest committed block,or returns false if none exists.
    // second return value is true if inside the window or false if outside the window.
    TxExistsInIncrementDBState(txId string, startHeight uint64) (bool, bool, error)
    //GetTxInfoOnly get tx block height,timestamp, txindex
    GetTxInfoOnly(txId string) (*commonPb.TransactionInfo, error)
    //Deprecated, please use GetTxInfoOnly, retrieves a transaction height by txid, or returns nil if none exists.
    GetTxHeight(txId string) (uint64, error)

    //Deprecated, please use GetTxInfoOnly, returns the confirmed time for given tx
    GetTxConfirmedTime(txId string) (int64, error)

    // GetLastBlock returns the last block.
    GetLastBlock() (*common.Block, error)

    // ReadObject returns the state value for given contract name and key, or returns nil if none exists.
    ReadObject(contractName string, key []byte) ([]byte, error)

    // ReadObjects returns the state values for given contract name and keys
    ReadObjects(contractName string, keys [][]byte) ([][]byte, error)

    // SelectObject returns an iterator that contains all the key-values between given key ranges.
    // startKey is included in the results and limit is excluded.
    SelectObject(contractName string, startKey []byte, limit []byte) (StateIterator, error)

    // GetTxRWSet returns an txRWSet for given txId, or returns nil if none exists.
    GetTxRWSet(txId string) (*common.TxRWSet, error)

    // GetTxRWSetsByHeight returns all the rwsets corresponding to the block,
    // or returns nil if zhe block does not exist
    GetTxRWSetsByHeight(height uint64) ([]*common.TxRWSet, error)

    // GetDBHandle returns the database handle for given dbName
    GetDBHandle(dbName string) DBHandle

    //GetArchivedPivot returns the archived pivot (include this pivot height)
    //Deprecated
    GetArchivedPivot() uint64

    // GetArchiveStatus returns archive status
    GetArchiveStatus() (*store.ArchiveStatus, error)

    // ArchiveBlock the block after backup
    ArchiveBlock(archiveHeight uint64) error

    //RestoreBlocks restore blocks from outside block data
    RestoreBlocks(serializedBlocks [][]byte) error

    // Close closes all the store db instances and releases any resources held by BlockchainStore
    Close() error
    //GetHistoryForKey 鏌ヨ鏌愬悎绾︿腑鏌愪釜Key鐨勫彉鏇村巻鍙�
    GetHistoryForKey(contractName string, key []byte) (KeyHistoryIterator, error)
    //GetAccountTxHistory 鏌ヨ涓€涓处鎴风殑浜ゆ槗鍘嗗彶璁板綍
    GetAccountTxHistory(accountId []byte) (TxHistoryIterator, error)
    //GetContractTxHistory 鏌ヨ涓€涓悎绾︾殑璋冪敤浜ゆ槗鍘嗗彶璁板綍
    GetContractTxHistory(contractName string) (TxHistoryIterator, error)
}

//StateSqlOperation 鐘舵€佹暟鎹簱鐨凷QL鎿嶄綔
type StateSqlOperation interface {
    //QuerySingle 涓嶅湪浜嬪姟涓紝鐩存帴鏌ヨ鐘舵€佹暟鎹簱锛岃繑鍥炰竴琛岀粨鏋�
    QuerySingle(contractName, sql string, values ...interface{}) (SqlRow, error)
    //QueryMulti 涓嶅湪浜嬪姟涓紝鐩存帴鏌ヨ鐘舵€佹暟鎹簱锛岃繑鍥炲琛岀粨鏋�
    QueryMulti(contractName, sql string, values ...interface{}) (SqlRows, error)
    //ExecDdlSql 鎵ц寤鸿〃銆佷慨鏀硅〃绛塂DL璇彞锛屼笉寰楀湪浜嬪姟涓繍琛�
    ExecDdlSql(contractName, sql, version string) error
    //BeginDbTransaction 鍚敤涓€涓簨鍔�
    BeginDbTransaction(txName string) (SqlDBTransaction, error)
    //GetDbTransaction 鏍规嵁浜嬪姟鍚嶏紝鑾峰緱涓€涓凡缁忓惎鐢ㄧ殑浜嬪姟
    GetDbTransaction(txName string) (SqlDBTransaction, error)
    //CommitDbTransaction 鎻愪氦涓€涓簨鍔�
    CommitDbTransaction(txName string) error
    //RollbackDbTransaction 鍥炴粴涓€涓簨鍔�
    RollbackDbTransaction(txName string) error
    //CreateDatabase 涓烘柊鍚堢害鍒涘缓鏁版嵁搴�
    CreateDatabase(contractName string) error
    //DropDatabase 鍒犻櫎涓€涓悎绾﹀搴旂殑鏁版嵁搴�
    DropDatabase(contractName string) error
    //GetContractDbName 鑾峰緱涓€涓悎绾﹀搴旂殑鐘舵€佹暟鎹簱鍚�
    GetContractDbName(contractName string) string
}

//SysContractQuery query system contract data
type SysContractQuery interface {
    GetContractByName(name string) (*commonPb.Contract, error)
    GetContractBytecode(name string) ([]byte, error)
}

//MemberQuery query member information
type MemberQuery interface {
    //GetMemberExtraData get member extra data by member
    GetMemberExtraData(member *accesscontrol.Member) (*accesscontrol.MemberExtraData, error)
}
```

## 鏁版嵁搴�

### 姒傝堪

瀛樺偍妯″潡涓殑Block DB銆丼tate DB銆丠istory DB绛夐兘鏄皝瑁呭悗鐨凞B瀵硅薄锛屽叾鍏蜂綋瀹炵幇瑕佸熀浜庣壒瀹氱殑鏁版嵁搴撳紩鎿庯紝姣斿KV鏁版嵁搴擄紙LevelDB銆丅adgerDB绛夛級銆佸垎甯冨紡鏁版嵁搴擄紙TikvDB绛夛級鍜屽叧绯诲瀷鏁版嵁搴擄紙MySQL銆乀DSQL鍜岃揪姊︼級绛夊紩鎿庛€備负浜嗗疄鐜板彲鎻掓嫈鐨勬暟鎹簱寮曟搸锛岄暱瀹夐摼鍦ㄦ暟鎹簱寮曟搸涔嬩笂灏佽浜嗕竴灞傛帴鍙o紝骞跺皢LevelDB銆丅adgerDB銆乀ikvDB銆丮ySQL銆乀DSQL鍜岃揪姊︾瓑鏁版嵁搴撳皝瑁呮垚DB provider銆傜敤鎴峰彲浠ユ牴鎹笟鍔¢渶姹傞€夋嫨鍚堥€傜殑鏁版嵁搴撳紩鎿庝綔涓洪暱瀹夐摼鐨勫簳灞傚瓨鍌ㄧ粍浠躲€�

<span id="storeMode"></span>
#### 鏁版嵁搴撳瓨鍌ㄦā寮�
闀垮畨閾剧殑瀛樺偍鍒嗕负RawDB(闈炴枃浠跺瓨鍌�)鍜孊FDB(鏂囦欢瀛樺偍)涓ょ鏂瑰紡
- RawDB锛歊awDB鏄寚灏嗘暟鎹畬鍏ㄥ瓨鍌ㄥ湪鍏崇郴鎴栭潪鍏崇郴鍨嬫暟鎹簱涓璕awDB鐨勪紭鐐规槸鏁版嵁瀛樺偍鍦ㄦ暟鎹簱涓紝瀛樺偍杩愯閫昏緫濡備笅鍥撅紝姝ゆ椂鎵€鏈夋暟鎹兘鐩存帴瀛樻斁鍦ㄤ笟鍔℃暟鎹簱(鍖哄潡鏁版嵁搴撱€佺姸鎬佹暟鎹簱銆佸巻鍙叉暟鎹簱銆佺粨鏋滄嵁搴撱€佷簨浠舵暟鎹簱)涓�
  
![瀛樺偍妯″潡RawDB鏃惰繍琛岄€昏緫](../images/DataStorage-StorageStructure-RawDB.png)

- BFDB锛欱FDB鏄寚灏嗗尯鍧楁暟鎹瓨鏀惧湪"鍖哄潡鏂囦欢瀛樺偍"涓紝鐒跺悗灏�"鍖哄潡鏂囦欢瀛樺偍"鐨勬暟鎹储寮曚俊鎭瓨鏀惧湪鍖哄潡鏁版嵁搴撱€佺粨鏋滄嵁搴擄紝鍏朵粬涓氬姟鏁版嵁搴�(鐘舵€佹暟鎹簱銆佸巻鍙叉暟鎹簱銆佷簨浠舵暟鎹簱)涓嶳awDB鐨勬暟鎹竴鏍凤紝瀛樺偍杩愯閫昏緫濡備笅鍥�
  
![瀛樺偍妯″潡BFDB鏃惰繍琛岄€昏緫](../images/DataStorage-StorageStructure-BFDB.png)
  - RawDB鍜孊FDB鏀寔鐗堟湰

| 鑺傜偣鏁版嵁瀛樺偍绫诲瀷 |  鍒О   |            閰嶇疆鏂瑰紡             | chainmaker-go鏀寔鐗堟湰 | blockdb/resultdb/statedb/historydb绛夌殑provider | 鏄惁鎺ㄨ崘 |
|:--------:|:-----:|:---------------------------:|:-----------------:|:--------------------------------------------:|:----:|
|  RawDB   | 闈炴枃浠跺瓨鍌� | disable_block_file_db:true  |    \>= v1.2.4     |         leveldb/badgerdb/tikvdb/sql          |  鍚�   |
|   BFDB   | 鏂囦欢瀛樺偍  | disable_block_file_db:false |    \>= v2.2.0     |        leveldb/badgerdb/tikvdb/sqlkv         |  鏄�   |

  - 娉�:
    - "闀垮畨閾捐妭鐐�" BFDB褰掓。鏂规涓嶆敮鎸侀噰鐢╯ql鏂瑰紡锛坧rovider: sql锛夊瓨鍌ㄧ殑鑺傜偣鏁版嵁锛岀敤鎴峰彲浠ヤ娇鐢╯qlkv锛坧rovider: sqlkv锛夋柟寮忔浛浠�
    - 閲囩敤sql鏂瑰紡锛坧rovider: sql锛夊瓨鍌ㄧ殑鑺傜偣棰濆鏀寔鍦ㄩ摼涓婇儴缃叉敮鎸乻ql鐨勫悎绾︼紝浣嗚sql鍚堢害鎬ц兘鍋忎綆锛屼笉鎺ㄨ崘浣跨敤
    - 琛ㄦ牸涓殑provider涓猴細chainmaker.yml -> storage -> blockdb_config/statedb_config/... -> provider

#### 鏀寔鐨勬暟鎹簱绫诲瀷

闀垮畨閾剧洰鍓嶆敮鎸�6绉嶆暟鎹簱寮曟搸鍙緵閫夋嫨锛屽垎鍒槸LevelDB銆丅adgerDB銆乀ikvDB銆丮ySQL銆乀DSQL鍜岃揪姊︺€�

- LevelDB: 榛樿閲囩敤鐨勬暟鎹簱寮曟搸锛孡evelDB浣滀负涓€娆惧祵鍏ュ紡KV鏁版嵁搴擄紝榛樿闆嗘垚鍦ㄩ暱瀹夐摼鑺傜偣涓紝鏃犻渶閮ㄧ讲锛屾€ц兘涔熺浉瀵瑰叧绯诲瀷鏁版嵁瑕佹洿濂斤紝閫傚悎鍦ㄦ暟鎹噺涓嶅ぇ鐨勬儏鍐典笅浣跨敤銆�
- BadgerDB: 浣滀负鍙︿竴绉嶅舰寮忕殑KV鍗曟満鏁版嵁搴撶殑瀹炵幇锛屼篃鏄祵鍏ュ紡KV鏁版嵁搴擄紝鎬ц兘鍦ㄥ啓鍏alue姣旇緝澶ф椂姣擫evelDB鏇撮珮,浣嗘槸璇绘€ц兘鍙兘宸簬LevelDB锛岄€傚悎鍦ㄦ暟鎹噺涓嶅ぇ鐨勬儏鍐典笅浣跨敤銆�
- TikvDB: 浣滀负KVDB鐨勬í鍚戞墿瀹圭増鏈紝闇€瑕佸崟鐙惎鍔╰ikv鏈嶅姟锛屽簳灞備娇鐢╮ocksdb,鎬ц兘鏇撮珮銆傞€傚悎鍦ㄥぇ瑙勬ā鏁版嵁鎯呭喌涓嬩娇鐢紝浣嗘槸闇€瑕佽繍钀ヨ€呰嚜琛岃礋璐ikv鏁版嵁搴撻泦缇ょ殑缁存姢宸ヤ綔銆俒tikv閮ㄧ讲娴佺▼](./Tikv瀹夎閮ㄧ讲.md)
- MySQL: (provider涓猴細chainmaker.yml -> storage -> blockdb_config/statedb_config/resultdb/... -> provider)
    - 閲囩敤鍏崇郴鍨嬫暟鎹簱鐨勬柟寮�(provider: sql)锛屾敮鎸乻chema鍜屽瘜鏌ヨ锛屾€ц兘杈僈V鏁版嵁搴撲綆锛岀洰鍓嶅叧绯诲瀷鏁版嵁搴撲笌鍖哄潡閾剧殑鐘舵€佹暟鎹苟涓嶈兘寰堝ソ鐨勭粨鍚堬紝瀵艰嚧寰堝皯鏈夊尯鍧楅摼閲囩敤鍏崇郴鍨嬫暟鎹簱浣滀负鐘舵€佹暟鎹簱銆傚師鍥犱富瑕佹湁涓ょ偣锛�1.鍖哄潡閾鹃渶瑕佸鏅鸿兘鍚堢害鎵€璇诲啓鐨勭姸鎬佹暟鎹仛涓ユ牸鐨勬帶鍒跺拰鏍¢獙锛岃€孲QL璇彞鐩稿鍖哄潡閾炬潵璇磋繃浜庣伒娲伙紝闅句互鎺у埗锛�2.闇€瑕佹彁鍓嶅垱寤哄簱琛ㄥ拰绱㈠紩锛岄渶瑕侀拡瀵逛笉鍚岀殑鏅鸿兘鍚堢害鍒涘缓涓嶅悓鐨勬暟鎹簱琛ㄧ粨鏋勶紝涓嶅鐏垫椿銆傜洰鍓嶉暱瀹夐摼鏀寔MySQL瀛樺偍寮曟搸锛屽湪绯荤粺鏁版嵁濡侭lock DB涓婃敮鎸佸尯鍧楀厓淇℃伅銆佷氦鏄撲俊鎭殑鍏崇郴鍨嬭涔夛紝鐘舵€佹暟鎹簱鏀寔kv鐨勬柟寮忓拰鏅鸿兘鍚堢害缂栧啓SQL璇彞鏂瑰紡璇诲啓鐘舵€佹暟鎹�(world state)銆�
    - 閲囩敤妯℃嫙闈炲叧绯诲瀷鏁版嵁搴撶殑鏂瑰紡(provider: sqlkv)锛岀被浼糑V鏁版嵁搴撶殑鏂瑰紡缁勭粐鏁版嵁瀛樺偍鍒癿ysql涓紝閫傚悎鎼厤BFDB瀛樺偍妯″紡浣跨敤(鐢ㄦ埛鏁版嵁閲忓亸澶ф椂鍙皢mysql鏁版嵁搴撴浛鎹㈡垚TDSQL绛夊垎甯冨紡瀛樺偍鏁版嵁搴�)(鎺ㄨ崘浣跨敤)銆�

<span id="store_config"></span>
###  閰嶇疆璇存槑

鑺傜偣鏈湴閰嶇疆鏂囦欢chainmaker.yml涓瓨鍌ㄩ儴鍒嗙殑閰嶇疆璇存槑

> 娉細
>
> 鑻ラ渶浣跨敤Mysql瀛樺偍锛岀壒娈婇厤缃細max_allowed_packet 灞炴€ч渶姣攂c.yml涓殑block_size瑕佸ぇ
>
> 涓存椂淇敼锛歴et global max_allowed_packet = 2 * 1024 * 1024 * 10
>
> 姘镐箙淇敼锛�
>
> vim /etc/my.cnf
> [mysqld]
> max_allowed_packet = 20M

```yml
storage:
  store_path: ../data/ledgerData  #璐︽湰鐨勫瓨鍌ㄨ矾寰勶紝 鍖呮嫭LevelDB銆丅adgerDB鐨勬暟鎹洰褰曪紝Block binary log鐨勬暟鎹洰褰�
  # block_store_tmp_path: "../data/ledgerData_tmp" # tmp file鏂囦欢澶�, 榛樿涓�""锛屽嵆涓嶉厤缃紝浠h〃涓嶅紑鍚鍔熻兘
  write_buffer_size: 4  #LevelDB鐨剋rite_buffer_size锛� 鍗曚綅涓篗B锛岄粯璁や负4M
  disable_historydb: false  #鏄惁绂佺敤鍘嗗彶璇诲啓闆嗙殑瀛樺偍鍔熻兘锛� 榛樿涓篺alse锛屼篃灏辨槸淇濆瓨鍘嗗彶璇诲啓闆嗐€�
  disable_block_file_db: false  #鏄惁绂佺敤鍖哄潡鏂囦欢瀛樺偍鍔熻兘锛� 榛樿涓簍rue锛屼篃灏辨槸鏈惎鐢�,鏂拌妭鐐瑰缓璁澶勮缃负false銆�
  logdb_segment_async: false  #鍖哄潡鏂囦欢寮傛钀界洏涓庡惁锛� 榛樿涓篺alse锛屼篃灏辨槸榛樿鍚屾钀界洏锛屽紓姝ヨ惤鐩樻椂瀛樺湪鏂數鍚庢暟鎹崯鍧忛闄┿€�
  logdb_segment_size: 128  #鍖哄潡鏂囦欢澶у皬锛屽崟浣峂B锛岄粯璁�64MB锛屾渶灏忓€�: 64MB銆�
  read_bfdb_timeout: 10000 # 璇诲彇 bfdb 涓嬪尯鍧楁枃浠剁殑瓒呮椂鏃堕棿锛屽崟浣峬s, 榛樿: 10000锛屽嵆10s銆�
  unarchive_block_height: 300000 # 涓嶅厑璁稿綊妗g殑楂樺害锛� 榛樿: 300000锛屽綊妗f渶楂橀珮搴︿负 褰撳墠楂樺害 - unarchive_block_height銆�
  archive_check_interval: 10 # 褰掓。鎿嶄綔妫€鏌ラ棿闅旓紝鍗曚綅s, 榛樿: 10锛屽嵆10s銆�
  restore_interval: 60 # 鎭㈠鍖哄潡鏂囦欢鐨勯棿闅旓紝鍗曚綅s, 榛樿: 60锛屽嵆60s锛岃妭鐐瑰皢鍦ㄦ暟鎹仮澶嶆搷浣�60s鍚庡紑濮嬪悎骞舵暟鎹埌閾句笂銆�
  # encryptor: sm4    # Symmetric encryption algorithm for writing data to disk. can be sm4 or aes
  # encrypt_key: "1234567890123456" # Symmetric encryption key:16 bytes key銆� 濡傛灉 pkcs11 璁剧疆鏈夊€硷紝浠h〃鎵撳紑encryption
  write_block_type: 0            # 0 common write锛�1 quick write

  # bigfilter config
  enable_bigfilter: false    #default false  鏄惁浣跨敤bigfilter,濡傛灉浣跨敤闇€瑕佸畨瑁卹edis
  bigfilter_config:
    redis_hosts_port: "127.0.0.1:6300,127.0.0.1:6301"   #redis host:port
    redis_password: abcpass  #redis password
    tx_capacity: 1000000000   #support max transaction capacity
    fp_rate: 0.000000001      #false postive rate

  # RWC config               
  enable_rwc: true          #default false, 鏄惁寮€鍚粦鍔ㄧ獥鍙g紦瀛�
  rolling_window_cache_capacity: 55000 # greater than max_txpool_size*1.1

  disable_state_cache: false   #default false, 鏄惁鍏抽棴statedb缂撳瓨锛屾ā寮忔槸鎵撳紑鐨�.
  state_cache_config:            # statedb cache
    life_window: 3000000000000   # key/value ttl time, ns
    clean_window: 1000000000     # 闂撮殧涓€瀹氭椂闂村悗娓呯悊 expired keys and values(clean up), ns
    max_entry_size: 500          # 姣忎釜entry鐨勬渶澶уぇ灏忥紝鍗曚綅byte銆�
    hard_max_cache_size: 1024    # 鏈€澶х紦瀛樺ぇ灏忥紝鍗曚綅MB銆�
  blockdb_config: #BlockDB 鏁版嵁搴撻厤缃�
    provider: leveldb #鏁版嵁搴撶被鍨嬶紝鏀寔LevelDB锛孊adgerDB锛孴ikvDB锛孧ysql锛岃繖閲岀ず渚嬩负LevelDB
    leveldb_config: #LevelDB鐨勮缁嗛厤缃�
      store_path: ../data/org1/blocks
      write_buffer_size: 4	#LevelDB鐨剋rite_buffer_size锛� 鍗曚綅涓篗B锛岄粯璁や负4M
      block_write_buffer_size:
  statedb_config: #StateDB 鏁版嵁搴撻厤缃�
    provider: sqlkv  #鏁版嵁搴撶被鍨嬶紝鏀寔LevelDB锛孊adgerDB锛孴ikvDB锛孧ysql锛岃繖閲岀ず渚嬩负Mysql, 浼樺厛鎺ㄨ崘浣跨敤'sqlkv'浠f浛 'sql'
    # 鎴栬€� provider: sql
    sqldb_config: #SQL鏁版嵁搴撶殑璇︾粏閰嶇疆
      sqldb_type:  mysql #鍏蜂綋鐨凴DBMS涓簃ysql锛屼篃鍙互鏄痵qlite銆乵ssql绛�
      dsn:  root:password@tcp(127.0.0.1:3306)/ #MySQL鐨勬暟鎹簱杩炴帴瀛楃涓�
      max_idle_conns: 10  #杩炴帴姹犱腑缁存寔鐨勬渶澶х殑绌洪棽杩炴帴鏁帮紝榛樿涓�10
      max_open_conns: 10  #鏈€澶х殑鍙敤杩炴帴鏁帮紝榛樿涓�10
      conn_max_lifetime: 60  #杩炴帴缁存寔鐨勬渶闀挎椂闂达紝鍗曚綅绉掞紝榛樿涓�60
  
  historydb_config: #HistoryDB鏁版嵁搴撻厤缃�
    provider: badgerdb #鏁版嵁搴撶被鍨嬶紝鏀寔LevelDB锛孊adgerDB锛孴ikvDB锛孧ysql锛岃繖閲岀ず渚嬩负BadgerDB
    badgerdb_config:
      store_path: ../data/org1/history
      compression: 0 # value涓�0 涓嶅帇缂╋紝1 Snappy鍘嬬缉锛�2 ZSTD鍘嬬缉锛岄粯璁や负0
      value_threshold: 10240 # 鍗曚綅涓篵ytes锛岄粯璁や负10240 bytes
  resultdb_config: #ResultDB鏁版嵁搴撻厤缃�
    provider: tikvdb # 鏀寔LevelDB锛孊adgerDB锛孴ikvDB锛孧ysql
    tikvdb_config:
       endpoints: "127.0.0.1:2379" # tikv pd server url锛屾敮鎸佸涓猽rl锛� 濡�: "192.168.1.2:2379,192.168.1.3:2379"
       max_batch_count: 128 # 姣忔kv batch鏈€澶уぇ灏� 榛樿128
       grpc_connection_count: 4 # chainmaker杩炴帴tikv鐨勮繛鎺ユ暟锛� 榛樿4
       grpc_keep_alive_time: 10 # 淇濇寔杩炴帴鐨勮繛鎺ユ暟锛� 榛樿10
       grpc_keep_alive_timeout: 3 # 淇濇寔杩炴帴鐨勮秴鏃舵椂闂� 榛樿3
       write_batch_size: 128 # 姣忔鎻愪氦tikv鎵规鏈€澶уぇ灏忥紝榛樿128
  disable_contract_eventdb: true  #鏄惁绂佹鍚堢害浜嬩欢瀛樺偍鍔熻兘锛岄粯璁や负true锛屽鏋滆缃负false,闇€瑕侀厤缃甿ysql
  contract_eventdb_config:
    provider: sql                 #濡傛灉寮€鍚痗ontract event db 鍔熻兘锛岄渶瑕佹寚瀹歱rovider涓簊ql
    sqldb_config:
      sqldb_type: mysql           #contract event db 鍙敮鎸乵ysql
      dsn: root:password@tcp(127.0.0.1:3306)/  #mysql鐨勮繛鎺ヤ俊鎭紝鍖呮嫭鐢ㄦ埛鍚嶃€佸瘑鐮併€乮p銆乸ort绛夛紝绀轰緥锛歳oot:admin@tcp(127.0.0.1:3306)/
```

###  瀛樺偍鐗规€у姛鑳戒粙缁�

#### 鍖哄潡鏂囦欢瀛樺偍(BFDB)
1. 鍖哄潡鏂囦欢瀛樺偍浠巚2.2.0(>= v2.2.0)浠ュ悗寮€濮嬫敮鎸侊紝榛樿鏈紑鍚�(鍦ㄦ湭閰嶇疆鏃�)銆傚彲浠ヤ慨鏀归厤缃负寮€鍚�(璁剧疆 disable_block_file_db:false), 浣跨敤chainmaker-go鐨勯厤缃敓鎴愬伐鍏风敓鎴愰厤缃椂锛屾澶勭殑鍊间负false锛屽嵆鐢熸垚鐨勯厤缃粯璁ゆ槸寮€鍚殑
2. 鍖哄潡鏂囦欢瀛樺偍鏄€傚悎鍖哄潡鏁版嵁搴撳ぇ浜�400GB浠ュ悗鐨勫満鏅紝閲囩敤涓庝箣鍓嶆柟妗堜笉鍚岀殑鍖哄潡瀛樺偍鏂瑰紡锛屼互瑙e喅鏃ョ泭澧為暱鐨勫尯鍧楁暟鎹鑷磋妭鐐归€熷害鍙樻參鐨勯棶棰�(鎺ㄨ崘浼樺厛浣跨敤)锛屾晠鏆傛椂涓庢棫鐗堟湰鐨勮妭鐐规暟鎹笉鍏煎
3. 鍖哄潡鏂囦欢瀛樺偍浠巚2.3.2寮€濮嬫敮鎸佸綊妗�
4. 鍖哄潡鏂囦欢瀛樺偍鏈紑鍚椂锛屽吋瀹规棫鐗堟湰鐨勬暟鎹�
5. 寤鸿閰嶇疆disable_block_file_db:false & logdb_segment_async: false
6. 鏂囦欢瀛樺偍瀹炵幇鍘熺悊:
   1. 鍖哄潡鍦ㄥ埌杈惧瓨鍌ㄦā鍧楀悗浼氳繘琛屽簭鍒楀寲鎿嶄綔锛屼负涓嬩竴姝ュ尯鍧楁暟鎹惤鐩樺仛鍑嗗锛屾鏃舵垜浠皢鍖哄潡瀵硅薄涓殑瀛愬璞″崟鐙簭鍒楀寲锛屽悓鏃惰褰曞簭鍒楀寲浜х敓瀛楄妭娴佺殑闀垮害锛岀劧鍚庡啀鎷兼帴璧锋潵锛屽氨鏄竴涓簭鍒楀寲涔嬪悗鐨勫畬鏁村尯鍧楃殑瀛楄妭娴�
   2. 鍦ㄥ簭鍒楀寲鍜屾嫾鎺ョ殑鏃跺€欒褰曞瓙瀵硅薄鍦ㄥ尯鍧楀瓧鑺傛祦鐨勫亸绉婚噺鍜岄暱搴︼紝鍗�: 鏌愬瓙瀵硅薄鍦ㄦ暣涓尯鍧楀瓧鑺傛祦鐨勮捣濮嬩綅缃拰闀垮害锛屽湪鍙嶅簭鍒楀寲瀛楄妭娴佹垚瀵硅薄鐨勬椂鍊欑洿鎺ユ埅鍙栧尯鍧楁寚瀹氫綅缃壒瀹氶暱搴︾殑鐗囨锛屽啀鍙嶅簭鍒楀寲锛屽嵆鍙緱鍒板師濮嬪璞�
   3. 鍖哄潡瀛楄妭娴佷富瑕佺敱鍖哄潡鍏冩暟鎹€佷氦鏄撱€佽鍐欓泦銆佷簨浠舵棩蹇楋紝鐢变簬鍖哄潡鏂囦欢瀛樺偍涓嶅啀鍒犻櫎瀛樺叆鐨勫尯鍧楋紝鍚屾椂涔熻兘鍏锋湁鍘熸潵WAL鐨勬晥鏋滐紝鍥犳KV鏁版嵁搴撲腑涓嶅啀闇€瑕佸瓨鍌ㄥ師濮嬬殑鍖哄潡淇℃伅锛屽彧闇€瑕佸瓨鍌ㄥ尯鍧楀師濮嬫暟鎹湪鏂囦欢瀛樺偍涓殑(鍖哄潡鍏冩暟鎹€佷氦鏄撱€佽鍐欓泦銆佷簨浠舵棩蹇�)绱㈠紩鍗冲彲
   4. 闀垮畨閾惧湪鏂囦欢瀛樺偍涓畾涔変簡鍖哄潡瀛樺偍鐨勬枃浠�.fdb鏂囦欢锛岀敤浜庡瓨鏀炬瘡娆′骇鐢熺殑鍖哄潡鏂囦欢,濡備笅鍥撅細
   ![鍖哄潡鏂囦欢瀛樺偍fdb鏂囦欢缁撴瀯](../images/DataStorage-BlockFileDBStructure.png)
   5. 鍦ㄨ鍙栧尯鍧楁椂锛屼粠KV鏁版嵁搴撲腑鑾峰彇鍖哄潡鎵€鍦ㄥ湪fdb鏂囦欢鍚嶅拰鍦ㄨ鏂囦欢涓殑璧峰鍜岄暱搴︼紝鐒跺悗鍐嶅弽搴忓垪鍖栧嵆鍙�
   6. 鍦ㄨ鍙栧尯鍧椾腑鐨勬暟鎹浜ゆ槗鏃讹紝鍚屾牱鑾峰彇璇ヤ氦鏄撴墍鍦╢db鏂囦欢鍚嶅拰鍦ㄨ鏂囦欢涓殑璧峰鍜岄暱搴︼紝鐒跺悗鍐嶅弽搴忓垪鍖栧嵆鍙�
   7. 鏂囦欢瀛樺偍鍙互灏嗗尯鍧楀瓨鍌ㄥ浜庣鐩樼殑KV鏁版嵁搴撻殢鏈哄啓锛屽彉鎴愬浜庣鐩樼殑椤哄簭鍐欙紝鍙互闄嶄綆纾佺洏鐨勮鍐欏帇鍔涳紝鍚屾椂闄嶄綆KV鏁版嵁搴撶殑鍘嬪姏

#### 鍖哄潡鏂囦欢瀛樺偍涓存椂瀛樺偍

鍖哄潡涓存椂瀛樺偍: StoreTmpPath (閰嶇疆鍚�: block_store_tmp_path)
1. 璇ュ姛鑳芥湰璐ㄦ槸鍦ㄥ皢鍖哄潡鏂囦欢鍏堝啓鍒癰lock_store_tmp_path锛屼箣鍚庡啀绉诲姩鍒板師鏉ユ斁缃尯鍧楁枃浠剁殑鏂囦欢澶�(鍘焍fdb鏂囦欢澶�), 鐢ㄦ埛鍙皢block_store_tmp_path鎸囧畾涓篠SD,fbdb鎸囧畾涓篐DD浠ユ彁楂樺瓨鍌ㄦ晥鐜囩殑鍚屾椂锛岄檷浣庣鐩樺瓨鍌ㄦ垚鏈�,娴佺▼濡備笅鍥�:
   
   <img src="../images/DataStorage-StorageTmpPath.jpg" alt="DataStorage-StorageTmpPath"  height="600" align="bottom" />
2. 杩愯娴佺▼锛�
    1. 鑺傜偣鍚姩鍚庡鏋滄鏌lock_store_tmp_path鍊肩殑闀垮害澶т簬0鏃讹紝琛ㄧず鐢ㄦ埛閰嶇疆浜哠toreTmpPath
    2. 妫€鏌lock_store_tmp_path鏂囦欢璺緞鏄惁瀛樺湪锛屽鏋滀笉瀛樺湪锛屽垯灏濊瘯鍒涘缓鏀规枃浠跺す
    3. 鍒涘缓鏂囦欢澶瑰畬鎴愬悗浼氬皾璇曞悜璇ユ枃浠跺す鍐欏叆tmp.txt鏂囦欢锛屼箣鍚庡啀鍒犻櫎锛屼互娴嬭瘯瀵逛簬璇ユ枃浠跺す鏈夊啓鏉冮檺
    4. 涓婅堪娴佺▼涓€鏃﹀嚭閿欙紝鍒欎細鎵撳嵃鍑洪敊璇紝涓斿叧闂璖toreTmpPath鍔熻兘锛屽瓨鍌ㄦ寜鐓ф病鏈夎鍔熻兘鐨勬柟寮忚繍琛�
    5. 鑻ヨ妭鐐逛箣鍓嶆病鏈夊惎鍔ㄨ鍔熻兘锛屾槸鍦ㄥ悗鏈熷惎鐢ㄣ€傚彲浠ュ湪閰嶇疆濂絙lock_store_tmp_path涔嬪悗鍚姩鑺傜偣锛岀劧鍚庣珛鍗冲叧闂妭鐐癸紝鍐嶅皢鍘焍fdb鏂囦欢澶逛笅闈㈢殑.END鏂囦欢瑕嗙洊鍒癰lock_store_tmp_path涓嬮潰鐨刡fdb鏂囦欢澶癸紝涔嬪悗鍐嶅惎鍔ㄨ妭鐐瑰嵆鍙�
    6. 鑺傜偣鍦ㄥ惎鐢ㄨ鍔熻兘鍚庯紝鍖哄潡鏂囦欢鎸夌収鍘熸潵鐨勯€昏緫鍐欏叆block_store_tmp_path涓�: 鍏堢敓鎴�.END鏂囦欢锛岀劧鍚庡悜鍏朵腑鍐欏叆鍖哄潡锛屽緟鍏跺彉鎴�.fdb鏂囦欢涔嬪悗锛岃妭鐐逛細灏�.fdb鏂囦欢绉诲姩鍒板師bfdb鏂囦欢澶逛笅锛屽悓鏃禸lock_store_tmp_path涓嬩細鐢熸垚鏂扮殑.END鏂囦欢锛屽姝ゅ惊鐜繍琛�
    7. 鑰冭檻鍒癰lock_store_tmp_path鍜屽師bfdb鏂囦欢澶瑰彲鑳藉鍦ㄤ笉鍚岀殑纾佺洏涓斿彲鑳藉瓨鍦ㄧ綉缁滅洏锛屼负浜嗘暟鎹畨鍏紝杩欓噷鐨勭Щ鍔ㄩ噰鐢ㄥ厛鎷疯礉鍐嶅垹闄ゆ簮鏂囦欢鐨勬柟寮忥紝涓斿湪鎷疯礉澶辫触鏃讹紝杩樻湁2娆¢噸璇曘€傚鏋滈噸璇曚箣鍚庤繕鏄け璐ワ紝浼氭湁鍗忕▼10s鎵弿涓€娆lock_store_tmp_path锛岃嫢鍙戠幇鏈�.fdb鏂囦欢锛屽皢鍐嶆瑙﹀彂绉诲姩娴佺▼
    8. .fdb绉诲姩鐨勮繃绋嬫槸寮傛鐨勶紝浠ラ檷浣庣Щ鍔ㄥ鎬ц兘鐨勫奖鍝嶃€傝妭鐐规柊鍚姩鏃讹紝鑻ュ彂鐜癰lock_store_tmp_path涓嬫湁.fdb鏂囦欢锛屽垯浼氬皢.fdb鏂囦欢绉诲姩鍒板師bfdb鏂囦欢澶癸紝寰呯Щ鍔ㄥ畬鎴愬悗鎵嶈兘鍚庣画鍚姩杩愯锛岃杩囩▼涓哄悓姝ョЩ鍔�
    9. 鐢ㄦ埛鍙皢block_store_tmp_path鎸囧悜鎬ц兘鏇村ソ鐨勭鐩橈紝浠ユ彁楂樺尯鍧楀啓鍏ラ€熷害锛屽皢鍘熸潵鐨刡fdb璺緞鎸囧悜鎬ц兘涓嶆€庝箞濂界殑纾佺洏锛屼互鑺傜渷鎴愭湰銆傚缓璁鐩業O鎬ц兘涓嶇浉宸お澶э紝閬垮厤鍑虹幇澶ч噺.fdb鏂囦欢鍚屾椂鎷疯礉鑰屼笉缁撴潫鐨勬儏鍐碉紝璇ユ儏鍐典細褰卞搷GetBlock鐨勭浉鍏宠姹傦紝褰卞搷浼氭寔缁埌瀵瑰簲.fdb鏂囦欢绉诲姩瀹屾瘯
3. 鑺傜偣浠庢湭寮€鍚疭toreTmpPath鍒板紑鍚鍔熻兘:
   1. 鍋囪StoreTmpPath涓�"./youdata/ledgerData_TMP"锛岃鑺傜偣涓哄崟閾句笖chainID涓篶hain1锛屽皢StoreTmpPath鍦╟hainmaker.yml涓厤缃ソ銆傚: block_store_tmp_path: "./youdata/ledgerData_TMP"
   2. 鍏堝垱寤�"./youdata/ledgerData_TMP/chain1/bfdb"鏂囦欢澶�(绠€绉皌mpfile)锛屼笖淇濊瘉鏂囦欢澶规湁璇诲啓鏉冮檺
   3. 鍋滄鑺傜偣锛岃烦杞埌鍘熸潵鏀剧疆.fdb鐨勬枃浠跺す涓�,濡�: "yourprojectpath/build/release/chainmaker-v2.3.1-wx-org1.chainmaker.org/data/wx-org1.chainmaker.org/ledgerData1/chain1/bfdb",(绠€绉皁riginfile)
   4. 灏唎riginfile涓嬬殑.END鏂囦欢绉诲姩鍒皌mpfile涓嬶紝鐒跺悗鍚姩鍐嶈妭鐐�,绛夊緟鑺傜偣鍚姩瀹屾瘯鍗冲彲銆傝繖閲岀殑绉诲姩涓轰簡瀹夊叏璧疯锛屽缓璁厛鎷疯礉originfile涓嬬殑.END鏂囦欢鍒皌mpfile涓嬶紝纭鎷疯礉鏃犺鍚庯紝鐒跺悗鍐嶅垹闄riginfile涓嬬殑.END鏂囦欢
   5. 鑻ヨ妭鐐逛负澶氶摼缁撴瀯锛屽垯chainID鏈夊涓紝濡�: chain1,chain2,chain3..., 姝ゆ椂:
      
        originfile1: yourprojectpath/build/release/chainmaker-v2.3.1-wx-org1.chainmaker.org/data/wx-org1.chainmaker.org/ledgerData1/chain1/bfdb ----绉诲姩.END鏂囦欢鍒�---> tmpfile1: ./youdata/ledgerData_TMP/chain1/bfdb
        
        originfile2: yourprojectpath/build/release/chainmaker-v2.3.1-wx-org1.chainmaker.org/data/wx-org1.chainmaker.org/ledgerData1/chain2/bfdb ----绉诲姩.END鏂囦欢鍒�---> tmpfile1: ./youdata/ledgerData_TMP/chain2/bfdb
        
        originfile3: yourprojectpath/build/release/chainmaker-v2.3.1-wx-org1.chainmaker.org/data/wx-org1.chainmaker.org/ledgerData1/chain3/bfdb ----绉诲姩.END鏂囦欢鍒�---> tmpfile1: ./youdata/ledgerData_TMP/chain3/bfdb
        
        ...
4. 鑺傜偣浠庡紑鍚疭toreTmpPath鍒板叧闂鍔熻兘:
    1. 鍋囪StoreTmpPath涓�"./youdata/ledgerData_TMP"锛岃鑺傜偣涓哄崟閾句笖chainID涓篶hain1锛屽皢block_store_tmp_path鍦╟hainmaker.yml涓厤缃垹闄�
    2. 杩涘叆"./youdata/ledgerData_TMP/chain1/bfdb"鏂囦欢澶�(绠€绉皌mpfile)
    3. 鍋滄鑺傜偣锛岃鍘熸潵鏀剧疆.fdb鐨勬枃浠跺す涓�: "yourprojectpath/build/release/chainmaker-v2.3.1-wx-org1.chainmaker.org/data/wx-org1.chainmaker.org/ledgerData1/chain1/bfdb",(绠€绉皁riginfile)
    4. 灏唗mpfile涓嬬殑.END鏂囦欢绉诲姩鍒皁riginfile涓嬶紝鐒跺悗鍚姩鍐嶈妭鐐�,绛夊緟鑺傜偣鍚姩瀹屾瘯鍗冲彲銆傝繖閲岀殑绉诲姩涓轰簡瀹夊叏璧疯锛屽缓璁厛鎷疯礉tmpfile涓嬬殑.END鏂囦欢鍒皁riginfile涓嬶紝纭鎷疯礉鏃犺鍚庯紝鐒跺悗鍐嶅垹闄mpfile涓嬬殑.END鏂囦欢
    5. 鑻ヨ妭鐐逛负澶氶摼缁撴瀯锛屽垯chainID鏈夊涓紝濡�: chain1,chain2,chain3..., 姝ゆ椂:
       
       tmpfile1: ./youdata/ledgerData_TMP/chain1/bfdb ----绉诲姩.END鏂囦欢鍒�---> originfile1: yourprojectpath/build/release/chainmaker-v2.3.1-wx-org1.chainmaker.org/data/wx-org1.chainmaker.org/ledgerData1/chain1/bfdb
           
       tmpfile2: ./youdata/ledgerData_TMP/chain2/bfdb ----绉诲姩.END鏂囦欢鍒�---> originfile2: yourprojectpath/build/release/chainmaker-v2.3.1-wx-org1.chainmaker.org/data/wx-org1.chainmaker.org/ledgerData1/chain2/bfdb
           
       tmpfile3: ./youdata/ledgerData_TMP/chain3/bfdb ----绉诲姩.END鏂囦欢鍒�---> originfile3: yourprojectpath/build/release/chainmaker-v2.3.1-wx-org1.chainmaker.org/data/wx-org1.chainmaker.org/ledgerData1/chain3/bfdb
           
       ...


#### MySQL鏁版嵁搴撹〃

闀垮畨閾炬敮鎸侀€夌敤MySQL浣滀负璐︽湰瀛樺偍寮曟搸锛岃妭鐐瑰惎鍔ㄤ細鑷姩鍒涘缓鏁版嵁搴擄紝浣跨敤chainId浣滀负鏁版嵁搴撳悕锛屽悓鏃朵篃浼氳嚜鍔ㄥ垱寤虹浉搴旂殑琛細

1. 鍖哄潡鍏冧俊鎭〃

   ```sql
   CREATE TABLE `block_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 '鏈尯鍧楃殑鏁e垪鍊�',
    `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 '鍖哄潡浜ゆ槗鐨凪erkle 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_ids` longtext COLLATE utf8mb4_general_ci COMMENT '鍖哄潡涓氦鏄揑D鍒楄〃',
    `additional_data` longblob COMMENT '鍖哄潡浜х敓浠ュ悗闄勫姞鐨勬暟鎹�',
    PRIMARY KEY (`block_height`),
    KEY `idx_hash` (`block_hash`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
   ```

2. 浜ゆ槗琛�

   ```sql
   CREATE TABLE `tx_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 '浜ゆ槗杩囨湡鐨剈nix鏃堕棿鎴�',
    `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`),
    KEY `idx_height_offset` (`block_height`,`offset`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
   ```

3. 涓栫晫鐘舵€佽〃

   ```sql
   CREATE TABLE `state_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`),
    KEY `idx_height` (`block_height`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
   ```

4. 鍘嗗彶璇诲啓闆嗚〃

   ```sql
   CREATE TABLE `history_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`),
    KEY `idx_height` (`block_height`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
   ```

<span id="store_archive_restore"></span>
## 閾句笂鏁版嵁褰掓。

### 褰掓。闇€姹�

1. 鑺傜偣鍦ㄩ暱鏃堕棿杩愯鍚庯紝浼氱Н绱ぇ閲忔暟鎹紝杩欎簺鏁版嵁涓嶅父璁块棶锛屼絾涓嶈兘涓㈠純锛屽洜姝ら渶瑕侀暱瀹夐摼闇€瑕佹彁渚涙暟鎹綊妗e姛鑳�
2. 褰掓。涔嬪悗鑺傜偣闇€瑕佽兘姝e父杩愯锛屼笉褰卞搷鑺傜偣鍙備笌鍏辫瘑鍑哄潡鍜屽澶栨彁渚涙湇鍔�
3. 褰掓。鍑哄幓鐨勬暟鎹鏀寔鍦ㄩ渶瑕佺殑鏃跺€欐仮澶嶅埌鑺傜偣涓�
4. 鎭㈠鐨勫尯鍧楀簲璇ヤ笌鍘熷厛褰掓。鐨勫尯鍧楀唴瀹逛竴鑷达紝鑳芥嫆缁濊妭鐐圭鏀瑰悗鐨勫尯鍧楁仮澶嶅埌鑺傜偣涓�
5. 闀垮畨閾惧湪鏃╂湡鎺ㄥ嚭杩囦竴绉嶆暟鎹綊妗e拰鎭㈠鏂规锛屽綋鍓嶅綊妗e拰鎭㈠鏂规闇€瑕佸敖鍙兘淇濇寔浣跨敤鏂瑰紡鐨勪竴鑷�

### 鎬讳綋鏂规

#### 瀵瑰尯鍧楅摼涓殑璐︽湰鏁版嵁鍒嗙被

1. 鐘舵€佹暟鎹紝浠呭瓨鍌ㄦ渶鏂扮殑鏁版嵁蹇収锛屾棤鍘嗗彶鐗堟湰锛屾暟鎹噺鐩稿杈冨皯锛岃€屼笖鏁版嵁鏄惁鍐风儹鐢变笟鍔″喅瀹氾紝鍥犳涓嶈€冭檻瀵圭姸鎬佹暟鎹仛褰掓。銆�
2. 闈炵姸鎬佹暟鎹紝濡傦細鍖哄潡銆佷氦鏄撱€佸巻鍙茶鍐欓泦锛屾暟鎹噺澶э紝闅忎氦鏄撲笉鏂啫鑳€锛岃€屼笖鍙涓嶄慨鏀癸紝閫傚悎瀵规煇涓尯鍧楅珮搴︿箣鍓嶇殑鏁版嵁鍋氬綊妗c€�
3. 褰掓。鍚庤妭鐐瑰鍏朵粬鑺傜偣鎻愪緵鍚屾鏈嶅姟鏃讹紝鍏朵粬鑺傜偣闇€閫夋嫨宸插綊妗i珮搴︿綆浜庡悓姝ヨ妭鐐归珮搴︾殑鑺傜偣

褰掓。鍙鍗曚釜鑺傜偣锛岀敱鑺傜偣杩愯惀鏂瑰彂璧峰鑷繁鑺傜偣鐨勫綊妗�

### 鏁翠綋娴佺▼

1. 鏁版嵁褰掓。鏈嶅姟涓昏妯″潡
   - 鑺傜偣: 鍖哄潡閾句腑杩愯鐨勮妭鐐规湇鍔★紝鍙互鏄叡璇嗚妭鐐癸紝涔熷彲浠ユ槸鍚屾鑺傜偣锛屼骇鐢熷苟淇濆瓨鍖哄潡鏁版嵁
   - 浜や簰宸ュ叿: cmc鎴栬€卌hainmaker-sdk绛夛紝涓庤妭鐐瑰拰閾惧瀛樺偍宸ュ叿鐨勯摼鎺ユ湇鍔�
   - 瀛樺偍浠撳簱:
     - 褰掓。涓績锛� 闀垮畨閾句富鎺ㄧ殑褰掓。鏁版嵁瀛樺偍浠撳簱锛岄噰鐢ㄤ笌鑺傜偣绫讳技鐨勫瓨鍌ㄥ尯鍧楁柟寮忥紝鎻愪緵鏁版嵁鍘嬬缉鍔熻兘锛岄檷浣庣鐩樺瓨鍌ㄦ垚鏈紝瀹炵幇瀹屾暣鐨勬暟鎹煡璇㈠姛鑳斤紝鎻愪緵鏁版嵁鏌ヨ鏈嶅姟
     - 閾惧瀛樺偍锛� 鑷暱瀹夐摼v1.2.x寮€濮嬫敮鎸佺殑閾惧mysql鏁版嵁搴擄紝鐢ㄦ埛閫氳繃sql璇彞璁块棶瀛樺偍鐨勬暟鎹紝闇€鑷缁勭粐sql璇彞璁块棶
2. 鏁版嵁褰掓。娴佺▼

   ![DataStructure-ARCHIVE-archive-arch.jpeg](../images/DataStructure-ARCHIVE-archive-arch.jpeg)
   - 浜や簰宸ュ叿鍙戦€乨ump璇锋眰锛岃姹傚尯鍧椾俊鎭�
   - 鑺傜偣杩斿洖鍖哄潡淇℃伅浜や簰宸ュ叿锛屼氦浜掑伐鍏疯浆鍙戝尯鍧楀埌鏁版嵁浠撳簱
   - 鏁版嵁浠撳簱淇濆瓨鑾峰彇鍒扮殑鍘熷鍖哄潡淇℃伅
3. 鏁版嵁鎭㈠娴佺▼

   ![DataStructure-ARCHIVE-restore-arch.jpeg](../images/DataStructure-ARCHIVE-restore-arch.jpeg)
   - 浜や簰宸ュ叿鍙戦€佽姹傦紝璇锋眰鍖哄潡淇℃伅
   - 鏁版嵁浠撳簱杩斿洖鍖哄潡淇℃伅鍒颁氦浜掑伐鍏�
   - 浜や簰宸ュ叿杞彂鍖哄潡鍒拌妭鐐癸紝鐢辫妭鐐瑰瓨鍌ㄦ仮澶嶅洖鏉ョ殑鍖哄潡
4. 鏁版嵁褰掓。/鎭㈠鏈嶅姟鎷撴墤

   ![DataStructure-ARCHIVE-store_arch.jpeg](../images/DataStructure-ARCHIVE-store_arch.jpeg)
   - 鍗曚釜鏁版嵁浠撳簱鍙互瀛樺偍澶氭潯閾剧殑鏁版嵁
   - 鍗曚釜閾炬垨鑰呰妭鐐瑰彲浠ュ瓨鍌ㄦ暟鎹埌浠绘剰涓€涓暟鎹粨搴�
   - 鑺傜偣鍜屾暟鎹粨搴撻€氳繃鏍¢獙鑺傜偣鐨勫垱濮嬪尯鍧梙ash璇嗗埆浠撳簱瀛樺偍鐨勬暟鎹綊灞炰簬鍝潯閾�
   - 鍚屼竴涓摼鐨勫涓妭鐐瑰湪鍚屼竴涓綊妗d腑蹇冪殑鏁版嵁鏄叡鐢ㄧ殑

### 瀵瑰鎺ュ彛

#### 鑾峰彇鑺傜偣褰掓。鐘舵€�

**鍙傛暟璇存槑**
- 杈撳嚭锛氳緭鍑鸿妭鐐瑰綋鍓嶉噰鐢ㄥ綊妗g被鍨嬶細RawDB(鍏ㄦ暟鎹簱/闈炴枃浠跺瓨鍌�)锛孊FDB(鏂囦欢瀛樺偍)
- 杈撳嚭锛氬凡褰掓。鐨勫尯鍧楅珮搴�
- 杈撳嚭锛氳妭鐐瑰厑璁哥殑褰掓。鐨勬渶楂橀珮搴�
- 杈撳嚭锛氬綋鍓嶈妭鐐圭殑褰掓。鐘舵€侊細Normal(姝e父), Archiving(姝e湪褰掓。), Restoring(姝e湪鎭㈠)
- 杈撳嚭锛氬綋鍓嶈妭鐐逛笂鍙仮澶嶅尯鍧楃殑鏆傚瓨鏂囦欢淇℃伅锛屾槸涓€涓狥ileRange鏁扮粍

```go
GetArchiveStatus() (*store.ArchiveStatus, error)

// archive status data
type ArchiveStatus struct {
  // store type: RawDB銆丅FDB
  Type StoreType `protobuf:"varint,1,opt,name=type,proto3,enum=store.StoreType" json:"type,omitempty"`
  // file range data
  FileRanges []*FileRange `protobuf:"bytes,2,rep,name=file_ranges,json=fileRanges,proto3" json:"file_ranges,omitempty"`
  // current archive pivot height
  ArchivePivot uint64 `protobuf:"varint,3,opt,name=archive_pivot,json=archivePivot,proto3" json:"archive_pivot,omitempty"`
  // max allow archive height
  MaxAllowArchiveHeight uint64 `protobuf:"varint,4,opt,name=max_allow_archive_height,json=maxAllowArchiveHeight,proto3" json:"max_allow_archive_height,omitempty"`
  // node archive process status: Normal銆丄rchiving銆丷estoring
  Process ArchiveProcess `protobuf:"varint,5,opt,name=process,proto3,enum=store.ArchiveProcess" json:"process,omitempty"`
}

type FileRange struct {
  // file name: 00000000000000000019, fdb鏂囦欢鍚�
  FileName string `protobuf:"bytes,1,opt,name=file_name,json=fileName,proto3" json:"file_name,omitempty"`
  // file contains block start height
  Start uint64 `protobuf:"varint,2,opt,name=Start,proto3" json:"Start,omitempty"`
  // file contains block end height
  End uint64 `protobuf:"varint,3,opt,name=End,proto3" json:"End,omitempty"`
}

```

#### 褰掓。鍖哄潡

**鍙傛暟璇存槑**
- archiveHeight: 褰掓。鐩爣鍖哄潡楂樺害
- 澶囨敞锛氬繀椤诲湪ArchiveStatus.Process褰掓。鐘舵€佷负Normal鏃舵墠鍙皟鐢ㄦ垚鍔�
    - archiveHeight 鑼冨洿锛欰rchivePivot < archiveHeight < MaxAllowArchiveHeight
    - ArchivePivot銆丮axAllowArchiveHeight銆丳rocess鍙敱GetArchiveStatus()鎺ュ彛鑾峰彇
    - 杩斿洖"archive range less than"閿欒淇℃伅鏃讹紝璇疯皟澶rchiveHeight鍊硷紝鐩村埌鎴愬姛
    - 瀹為檯鐨勫綊妗e尯鍧楅珮搴﹀彲鑳戒細姣攁rchiveHeight灏忥紝鑺傜偣浼氭牴鎹綋鍓嶅瓨鍌ㄧ姸鎬佽嚜鍔ㄩ€夋嫨鍚堥€傜殑褰掓。鍖哄潡楂樺害

```go
ArchiveBlock(archiveHeight uint64) error
```

#### 鎭㈠鍖哄潡

**鍙傛暟璇存槑**
- serializedBlocks: 瑕佹仮澶嶇殑鍖哄潡搴忓垪鍖栦箣鍚庣殑鏁版嵁娴佹暟缁勶紝鏁扮粍涓殑鍖哄潡楂樺害椤哄簭蹇呴』鏄粠浣庡埌楂�
- 澶囨敞锛氬繀椤诲湪ArchiveStatus.Process褰掓。鐘舵€佷负Normal鏃舵墠鍙皟鐢ㄦ垚鍔燂紝鑺傜偣鍦ㄦ渶鍚庢敹鍒板尯鍧�(榛樿)1鍒嗛挓涔嬪悗鍐嶅紑濮嬫仮澶嶆暟鎹啓鍏ラ摼涓婃搷浣�
    - serializedBlocks鏁版嵁婕旂ず:
        - 璁炬仮澶嶇殑鍖哄潡鑼冨洿涓�800锝�500锛� 姣忔壒娆℃帹閫�100涓尯鍧楋紝鍒欓渶鎺ㄩ€�4娆�
        - 鎺ㄩ€佸尯鍧楃粰鑺傜偣鏃跺尯鍧楃殑缁勭粐鏂瑰紡涓�(鏁板€间负鍖哄潡楂樺害):
            - 绗竴娆℃帹閫佸尯鍧楅珮搴�: 701锝�800
            - 绗簩娆℃帹閫佸尯鍧楅珮搴�: 601锝�700
            - 绗笁娆℃帹閫佸尯鍧楅珮搴�: 501锝�600
            - 绗洓娆℃帹閫佸尯鍧楅珮搴�: 500
        - 鎺ㄩ€佺殑鍖哄潡涓笉鑳藉寘鍚€滆妭鐐规殏瀛樼┖闂粹€濆瓨鍦ㄧ殑鍖哄潡锛屽惁鍒欎細鎺ㄩ€佸け璐ワ紝鍙€氳繃GetArchiveStatus()杩斿洖鐨凢ileRanges淇℃伅鏌ョ湅鈥滆妭鐐规殏瀛樼┖闂粹€濆凡鏈夊摢浜涘尯鍧�

```go
RestoreBlocks(serializedBlocks [][]byte) error
```


### 鈥滃尯鍧楅摼鑺傜偣鈥濆綊妗e姛鑳界増鏈敮鎸�
闀垮畨閾剧殑瀛樺偍鍒嗕负RawDB(闈炴枃浠跺瓨鍌�)鍜孊FDB(鏂囦欢瀛樺偍)涓ょ鏂瑰紡

- 鏈璁ㄨ鐨勯暱瀹夐摼鏀寔鐨勫綊妗f柟寮忎负鈥滃尯鍧楅摼鑺傜偣鈥滀笂鏁版嵁鐨勫鐞嗘柟寮忥紝鐢ㄦ埛鍦ㄩ€夋嫨浣跨敤鈥滄暟鎹粨搴撯€濇椂锛屽彲浠ヨ嚜鐢遍€夋嫨浣跨敤褰掓。涓績銆侀摼澶栧瓨鍌ㄦ垨鑰呰嚜宸卞疄鐜扮殑鏁版嵁浠撳簱
- 鑺傜偣鏀寔鐨勫綊妗f柟妗堟槸鍦ㄨ妭鐐瑰惎鍔ㄥ墠鍦╟hainmaker.yml鐨剆torage閰嶇疆涓喅瀹氱殑锛岃妭鐐瑰惎鍔ㄥ悗灏卞凡缁忕‘瀹氭敮鎸佺殑褰掓。鏂瑰紡銆傞暱瀹夐摼鑺傜偣鎻愪緵涓ょ褰掓暟鎹柟寮忥細RawDB(闈炴枃浠跺瓨鍌�)鍜孊FDB(鏂囦欢瀛樺偍)锛屼笉鍚岀殑瀛樺偍鏂瑰紡瀵瑰簲浜嗕笉鍚岀殑鏁版嵁褰掓。鍐呴儴杩愯鏂瑰紡锛屼絾瀵瑰鎻愪緵鐨勬湇鍔℃槸鐩稿悓鐨�
- RawDB: 瀛樺偍鏂瑰紡涓哄皢鎵€鏈夋暟鎹兘鐩存帴瀛樺偍鍦╨eveldb/mysql绛夋暟鎹簱涓紝(disable_block_file_db:true)
    - RawDB鐨勮妭鐐筨lockdb鍜宺esultdb瀛樺偍鏁版嵁scheme

|  涓氬姟鏁版嵁搴�   |          key          |          value           | 褰掓。鎿嶄綔鐩爣 |   澶囨敞    | 褰掓。 | 鏁版嵁鎭㈠ |
|:--------:|:---------------------:|:------------------------:|:------:|:-------:|:--:|:----:|
| blockdb  |  lastBlockNumKeyStr   |    lastBlockNumBytes     |   鍚�    |    -    | -  |  -   |
| blockdb  |       heightKey       |    serializedMetaData    |   鏄�    |    -    | 鍒犻櫎 |  鎭㈠  |
| blockdb  |     blockHashKey      | block.Header.BlockHeight |   鍚�    |    -    | -  |  -   |
| blockdb  |     blockTxIdKey      |        txBlockInf        |   鍚�    |    -    | -  |  -   |
| blockdb  |        txIdKey        |         txBytes          |   鏄�    |    -    | 鍒犻櫎 |  鎭㈠  |
| blockdb  | lastConfigBlockNumKey |    lastBlockNumBytes     |   鍚�    | 閰嶇疆鍖哄潡鎵嶄細鏈� | -  |  -   |
| resultdb | resultDBSavepointKey  |    lastBlockNumBytes     |   鍚�    |    -    | -  |  -   |
| resultdb |      txRWSetKey       |       txRWSetBytes       |   鏄�    |    -    | 鍒犻櫎 |  鎭㈠  |

- BFDB: 涓昏鐗圭偣涓洪檷鍖哄潡淇℃伅瀛樺偍鍦ㄩ暱瀹夐摼鑷爺鐨勬枃浠跺瓨鍌ㄧ郴缁熶腑锛屽彧灏嗙浉鍏崇储寮曞拰鐘舵€佹暟鎹瓨鏀惧湪leveldb/mysql绛夋暟鎹簱涓�,(disable_block_file_db:false)
    - BFDB鐨勮妭鐐筨lockdb鍜宺esultdb瀛樺偍鏁版嵁scheme


|  涓氬姟鏁版嵁搴�   |          key          |          value           | 褰掓。鎿嶄綔鐩爣 |   澶囨敞    |          褰掓。           |         鏁版嵁鎭㈠          |
|:--------:|:---------------------:|:------------------------:|:------:|:-------:|:---------------------:|:---------------------:|
| blockdb  |  lastBlockNumKeyStr   |    lastBlockNumBytes     |   鍚�    |    -    |           -           |           -           |
| blockdb  |     blockIndexKey     |      blockIndexInfo      |   鏄�    |    -    |          鍒犻櫎           |          鎭㈠           |
| blockdb  |     metaIndexKey      |      metaIndexInfo       |   鏄�    |    -    |          鍒犻櫎           |          鎭㈠           |
| blockdb  |     blockHashKey      | block.Header.BlockHeight |   鍚�    |    -    |           -           |           -           |
| blockdb  |     blockTxIdKey      |        txBlockInf        |   鏄�    |    -    | 鍒犻櫎txBlockInf涓殑txIndex | 鎭㈠txBlockInf涓殑txIndex |
| blockdb  | lastConfigBlockNumKey |    lastBlockNumBytes     |   鍚�    | 閰嶇疆鍖哄潡鎵嶄細鏈� |           -           |           -           |
| resultdb | resultDBSavepointKey  |    lastBlockNumBytes     |   鍚�    |    -    |           -           |           -           |
| resultdb |     rwSetIndexKey     |       rwIndexInfo        |   鏄�    |    -    |          鍒犻櫎           |          鎭㈠           |

- 鈥滃尯鍧楅摼鑺傜偣鈥濅笂褰掓。鍔熻兘鏀寔璇︽儏琛紝瀛樺偍瑙掑害锛歊awDB(闈炴枃浠跺瓨鍌�)鍜孊FDB(鏂囦欢瀛樺偍)

| 鑺傜偣鏁版嵁瀛樺偍绫诲瀷 |               閰嶇疆鏂瑰紡                |     鏀寔鐗堟湰     |       blockdb/resultdb        | statedb/historydb绛� | 浼樺厛鎺ㄨ崘鐨勬暟鎹粨搴� | 褰掓。鏁堢巼 |
|:--------:|:---------------------------------:|:------------:|:-----------------------------:|:------------------:|:---------:|:----:|
|  RawDB   | 闈炴枃浠跺瓨鍌�(disable_block_file_db:true) |  \>= v1.2.4  |  leveldb/badgerdb/tikvdb/sql  |      瀵硅鏁版嵁搴撴棤鎿嶄綔      |  閾惧mysql  |  浣�   |
|   BFDB   | 鏂囦欢瀛樺偍(disable_block_file_db:false) | \>= v2.3.1.1 | leveldb/badgerdb/tikvdb/sqlkv |      瀵硅鏁版嵁搴撴棤鎿嶄綔      |   褰掓。涓績    |  楂�   |

- 鈥滃尯鍧楅摼鑺傜偣鈥濅笂褰掓。鍔熻兘鏀寔璇︽儏琛紝鑺傜偣瑙掑害锛氫笉鍚岀増鏈�

|        闀垮畨閾剧増鏈�        | 鑺傜偣鏁版嵁瀛樺偍绫诲瀷 |               閰嶇疆鏂瑰紡                | 鏄惁鏀寔 |       blockdb/resultdb        | statedb/historydb绛� | 浼樺厛鎺ㄨ崘鐨勬暟鎹粨搴� | 褰掓。鏁堢巼 |
|:-------------------:|:--------:|:---------------------------------:|:----:|:-----------------------------:|:------------------:|:---------:|:----:|
| >= v1.2.4 <v2.3.1.1 |  RawDB   | 闈炴枃浠跺瓨鍌�(disable_block_file_db:true) |  鏄�   |  leveldb/badgerdb/tikvdb/sql  |      瀵硅鏁版嵁搴撴棤鎿嶄綔      |  閾惧mysql  |  浣�   |
| >= v1.2.4 <v2.3.1.1 |   BFDB   | 鏂囦欢瀛樺偍(disable_block_file_db:false) |  鍚�   |           瀵硅鏁版嵁搴撴棤鎿嶄綔            |      瀵硅鏁版嵁搴撴棤鎿嶄綔      |     鏃�     |  -   |
|     >= v2.3.1.1     |  RawDB   | 闈炴枃浠跺瓨鍌�(disable_block_file_db:true) |  鏄�   |  leveldb/badgerdb/tikvdb/sql  |      瀵硅鏁版嵁搴撴棤鎿嶄綔      |  閾惧mysql  |  浣�   |
|     >= v2.3.1.1     |   BFDB   | 鏂囦欢瀛樺偍(disable_block_file_db:false) |  鏄�   | leveldb/badgerdb/tikvdb/sqlkv |      瀵硅鏁版嵁搴撴棤鎿嶄綔      |   褰掓。涓績    |  楂�   |


娉細
- "闀垮畨閾捐妭鐐�" BFDB褰掓。鏂规涓嶆敮鎸侀噰鐢╯ql鏂瑰紡锛坧rovider: sql锛夊瓨鍌ㄧ殑鑺傜偣鏁版嵁锛岀敤鎴峰彲浠ヤ娇鐢╯qlkv锛坧rovider: sqlkv锛夋柟寮忔浛浠�
- 閲囩敤sql鏂瑰紡锛坧rovider: sql锛夊瓨鍌ㄧ殑鑺傜偣棰濆鏀寔鍦ㄩ摼涓婇儴缃叉敮鎸乻ql鐨勫悎绾︼紝浣嗚sql鍚堢害鎬ц兘鍋忎綆锛屼笉鎺ㄨ崘浣跨敤

### [褰掓。涓績璁捐鍜屽疄鐜癩(./褰掓。涓績璁捐鍜屽疄鐜�.md)

### 鏃跺簭鍥�
- 鏁版嵁杞瓨鍚庡綊妗o細

![DataStructure-ARCHIVE-timeline_archive.jpeg](../images/DataStructure-ARCHIVE-timeline_archive.jpeg)
- 鏁版嵁鎭㈠锛�

![DataStructure-ARCHIVE-timeline_restore.jpeg](../images/DataStructure-ARCHIVE-timeline_restore.jpeg)

### [cmc宸ュ叿鎿嶄綔](../dev/鍛戒护琛屽伐鍏�.html#archive)

<span id="rebuild_dbs"></span>
## 鏁版嵁鎭㈠(rebuild_dbs)

![DataStructure-RebuildDBS.png](../images/DataStructure-RebuildDBS.png)

1. 鎿嶄綔姝ラ 
   1. 鍋滄鍖哄潡閾炬湇鍔�
   2. 鎵ц鏁版嵁鎭㈠锛堟墽琛岃繃绋嬪涓婂浘锛夛紝绀轰緥濡備笅
        
        ./chainmaker rebuild-dbs -c ../config/wx-org1-solo/chainmaker.yml ci-solo
        
   3. 鏌ョ湅鏃ュ織锛岀‘璁ゆ仮澶嶆垚鍔�

2. 浣跨敤闄愬埗
   
   1. 褰撳墠浠呮敮鎸乴eveldb瀛樺偍鏂瑰紡鐨勬仮澶�
   
3. 鍏朵粬
   1. 鎵ц鏁版嵁鎭㈠锛屼細鑷姩澶囦唤鍘熸暟鎹�
   2. 鍙互閰嶇疆鎭㈠鍖哄潡楂樺害锛屼笉閰嶇疆鍒欐仮澶嶅叏閮�
      
      storage:
      rebuild_block_height: 10
      
   3. 鍙互鍦ㄥ懡浠よ鏈熬娣诲姞chainid鏉ユ寚瀹氭仮澶嶇殑chainid
      
      ./chainmaker rebuild-dbs -c ../config/wx-org1-solo/chainmaker.yml ci-solo --chain-id=chain1
      
   4. 鍙互鍦ㄥ懡浠よ鏈熬娣诲姞need-verify锛屽浜庡彲闈犵殑鏁版嵁鎭㈠鍘熷鏁版嵁璺宠繃鍖哄潡楠岃瘉杩囩▼锛屾彁楂樻仮澶嶉€熷害锛岄粯璁rue
      
      ./chainmaker rebuild-dbs -c ../config/wx-org1-solo/chainmaker.yml ci-solo --chain-id=chain1 --need-verify=false
      
4. 鐢ㄦ硶
    1. 鍚敤浜嗘枃浠跺瓨鍌ㄥ姛鑳�(鎺ㄨ崘鍚姩)锛�
        1. 鏁版嵁搴撴仮澶�: 鍦ㄦ暟鎹簱鏁版嵁鎹熷潖鏃讹紝浣跨敤block鍜宭edgerData1鏂囦欢澶圭殑鏁版嵁锛屽彲浠ラ噸鏂扮敓鎴愬叾浠栨枃浠跺す鐨勬暟鎹�
        2. 鏁版嵁鍚屾: 鍦ㄥ悓姝ヨ繃绋嬩腑锛屽彲浠ユ嫹璐濈洰鏍囪妭鐐圭殑block鍜宭edgerData1鏁版嵁锛岀劧鍚庝娇鐢ㄨ宸ュ叿鍦ㄦ湰鍦伴噸鏂扮敓鎴愬叾浠栨枃浠跺す鐨勬暟鎹紝涔嬪悗鍗冲彲浠ュ揩閫熷惎鍔ㄩ摼锛岃揪鍒板揩閫熷悓姝ョ殑鏁堟灉
        3. 鍥炴粴閾惧埌鎸囧畾楂樺害: 鍦ㄦ渶鏂版暟鎹啓鍏ョ磰涔憋紝鏁版嵁搴撲笉鍙敤鏃讹紝涔熷彲浠ヤ娇鐢ㄨ宸ュ叿鎭㈠鍒版暟鎹湭绱婁贡鏃剁殑楂樺害锛岃揪鍒版暟鎹洖婊氱殑鏁堟灉
    2. 鏈惎鐢ㄦ枃浠跺瓨鍌ㄥ姛鑳斤細
        1. 鏁版嵁搴撴仮澶�: 鍦ㄦ暟鎹簱鏁版嵁鎹熷潖鏃讹紝闇€瑕佸畬鏁寸殑澶氫釜鏁版嵁搴撴枃浠跺す锛屼娇鐢ㄨ宸ュ叿閲嶆柊鐢熸垚鏁版嵁鍒版寚瀹氱殑鏁版嵁鏈崯鍧忔椂鐨勯珮搴�
        2. 鍥炴粴閾惧埌鎸囧畾楂樺害: 鍦ㄦ渶鏂版暟鎹啓鍏ョ磰涔憋紝鏁版嵁搴撲笉鍙敤鏃讹紝涔熷彲浠ヤ娇鐢ㄨ宸ュ叿鎭㈠鍒版暟鎹湭绱婁贡鏃剁殑楂樺害锛岃揪鍒版暟鎹洖婊氱殑鏁堟灉


## 閫忔槑鏁版嵁鍔犲瘑锛圱DE锛�

[閫忔槑鏁版嵁鍔犲瘑锛圱ransparent Data Encryption (绠€绉癟DE)锛塢(閫忔槑鏁版嵁鍔犲瘑.md)鏄寚鍙互鍦ㄦ枃浠跺眰瀵规暟鎹拰鏂囦欢杩涜瀹炴椂鍔犲瘑鍜岃В瀵嗭紝钀界洏鐨勬枃浠舵槸鍔犲瘑鍚庣殑鍐呭锛岃€屽浜庝笂灞傚簲鐢ㄧ郴缁熷拰寮€鍙戜汉鍛樿€岃█锛屽姞瑙e瘑杩囩▼鏄棤鎰熺煡鐨勶紝鍐欏叆鍜岃鍙栫殑鍐呭鏄槑鏂囧唴瀹癸紝鎵€浠ュ彨鍋氶€忔槑鏁版嵁鍔犲瘑銆傞暱瀹夐摼瀵嗙爜妯″潡鍚屾椂鎻愪緵浜嗚蒋浠跺疄鐜板拰纭欢闆嗘垚锛屼娇鐢ㄤ互涓嬫楠ゅ嵆鍙畬鎴怲DE鐨勯厤缃€�

### 鍩轰簬杞欢瀹炵幇鐨凾DE閰嶇疆

#### 鍒涘缓瀵圭О瀵嗛挜

闀垮畨閾剧殑閫忔槑鏁版嵁鍔犲瘑榛樿鏀寔AES鍜屽浗瀵哠M4涓ょ瀵圭О鍔犲瘑绠楁硶銆侫ES绠楁硶鏀寔128浣嶃€�192浣嶃€�256浣嶈繖3绉嶅瘑閽ラ暱搴︼紝SM4绠楁硶鏀寔128浣嶅瘑閽ラ暱搴︺€傚瘑閽ラ暱搴﹀繀椤讳笌瀵瑰簲鐨勭畻娉曞尮閰嶏紝濡傛灉闀垮害涓嶅尮閰嶅垯鏃犳硶姝e父鍚姩闀垮畨閾俱€傛垜浠互鍥藉瘑SM4绠楁硶涓轰緥锛屽瘑閽ユ帹鑽愪娇鐢ㄩ殢鏈哄瘑鐮佺敓鎴愬櫒鐢熸垚鐨勫瘑鐮侊紝姣斿鈥�0H#y@EGXPOAScAnB鈥濊繖鏍风殑褰㈠紡锛屽皢鏈夋晥鎻愰珮鏁版嵁鐨勫畨鍏ㄦ€э紝闃叉琚瓧鍏哥牬瑙c€傞櫎浜嗗瓧绗︿覆褰㈠紡鐨勫瘑閽ワ紝闀垮畨閾捐繕鏀寔浠绘剰浜岃繘鍒跺舰寮忕殑瀵嗛挜锛屽彧瑕侀暱搴︽弧瓒宠姹傦紙鍥藉瘑SM4锛�128浣嶏級鍗冲彲銆傛柊鐢熸垚鐨勫瘑閽ヨ鍋氬ソ瀹夊叏澶囦唤锛岄槻姝㈠瘑閽ヤ涪澶卞悗鏁版嵁鏃犳硶瑙h銆�

#### 閰嶇疆閫忔槑鏁版嵁鍔犲瘑

鍦ㄩ暱瀹夐摼鑺傜偣鐨勯厤缃枃浠讹紝鍗砪hainmaker.yml鏂囦欢涓紝storage閰嶇疆椤逛笅鎻愪緵浜嗗璇ヨ妭鐐筎DE鐨勯厤缃€夐」锛屽舰濡傦細

```
storage:
  encryptor: sm4    # sm4/aes
  encrypt_key: "1234567890123456" #16 bytes key
```

* encryptor鏄噰鐢ㄧ殑瀵圭О鍔犲瘑绠楁硶锛岀洰鍓嶆敮鎸乻m4鍜宎es涓や釜閫夐」銆�
* encrypt_key鏄绉板姞瀵嗙殑瀵嗛挜锛屾敮鎸佸瓧绗︿覆銆佸崄鍏繘鍒跺拰鏂囦欢璺緞涓夌褰㈠紡銆�
  - 瀛楃涓诧紝鏀寔瀛楁瘝澶у皬鍐欍€佹暟瀛椼€佺鍙枫€佺┖鏍肩瓑锛岄暱搴﹀繀椤绘弧瓒冲姞瀵嗙畻娉曡姹�
  - 鍗佸叚杩涘埗锛屽繀椤讳互0x寮€澶达紝鍚庨潰璺熷搴斿瘑閽ョ殑鍗佸叚杩涘埗鍐呭
  - 鏂囦欢璺緞锛屽皢瀵嗛挜淇濆瓨鍒颁竴涓枃浠朵腑锛岀劧鍚庡皢鏂囦欢缁濆璺緞閰嶇疆鍒拌繖閲岋紝骞剁‘淇濋暱瀹夐摼杩涚▼鐢ㄦ埛鍏锋湁璇诲啓璇ユ枃浠剁殑鏉冮檺銆�
    浠ヤ笅閰嶇疆绀轰緥锛�

```
storage:
  encryptor: aes    # sm4/aes
  encrypt_key: "0x48656c6c6f20436861696e4d616b6572" #16 bytes key
```

```
storage:
  encryptor: sm4    # sm4/aes
  encrypt_key: "/usr/key/my.key" #this file content is a 16 bytes key
```

#### 鍚敤鑺傜偣

瀹屾垚TED鐨勯厤缃悗锛岃纭繚褰撳墠鑺傜偣娌℃湁浠讳綍鏁版嵁锛屽鏋滀箣鍓嶅凡缁忔湁鏁版嵁锛岄渶瑕佸畬鍏ㄥ垹闄ゃ€傝妭鐐瑰惎鍔ㄥ悗灏嗕細浠庡垱涓栧尯鍧楀紑濮嬪熀浜嶵DE鐨勫瘑閽ュ姣忎釜鍖哄潡姣忎釜浜ゆ槗姣忎釜涓栫晫鐘舵€乂alue杩涜缁熶竴鐨勫姞瀵嗗瓨鍌ㄣ€�
鍦╡ncrypt_key涓婁娇鐢ㄦ枃浠惰矾寰勯厤缃瘑閽ョ殑鎯呭喌涓嬶紝闀垮畨閾惧湪鍚姩鏃跺皢璇诲彇鏂囦欢鍐呭浣滀负瀵嗛挜锛屽悓鏃跺皢鏂囦欢鍐呭娓呯┖锛岄槻姝㈢‖鐩樻暟鎹鐩楁椂瀵嗛挜涔熷悓鏃惰鐩椼€傛墍浠ュ鏋滀笅娆¤閲嶆柊鍚姩闀垮畨閾捐繘绋嬶紝蹇呴』閲嶆柊鍦ㄥ搴旂殑瀵嗛挜鏂囦欢涓啓鍏ュ瘑閽ユ墠鑳芥甯稿惎鍔ㄣ€�

### 鍩轰簬纭欢瀵嗙爜鏈虹殑TDE閰嶇疆

鍩轰簬杞欢鐨勫绉板姞瀵嗗瓨鍦ㄥ崰鐢ㄤ富鏈鸿绠楄祫婧愶紝瀵嗛挜瀹规槗鏆撮湶鐨勯闄╋紝鍩轰簬纭欢瀵嗙爜鏈虹殑鏂规鍙互鏈夋晥鎻愬崌鍔犺В瀵嗙殑鎬ц兘鍜屽瘑閽ョ殑瀹夊叏鎬с€傞暱瀹夐摼鏀寔PKCS11鏍囧噯鐨勭‖浠跺瘑鐮佹満鎺ュ叆锛屼互涓嬩负鍦═DE涓惎鐢ㄧ‖浠跺瘑鐮佹満闆嗘垚鐨勬楠ゃ€�

#### 鍦ㄥ姞瀵嗕腑鐢熸垚瀵圭О瀵嗛挜

鍩轰簬纭欢瀵嗙爜鏈虹殑鎯呭喌涓嬶紝瀵嗛挜閮芥墭绠″湪瀵嗙爜鏈哄唴閮紝澶栭儴绋嬪簭鏃犳硶鑾峰緱瀵嗛挜鍐呭锛屽彧鑳介€氳繃鏍囧噯鎺ュ彛杩涜瀵嗛挜鐢熸垚銆佸姞瑙e瘑銆佺鍚嶃€佸搱甯岀瓑瀵嗙爜瀛︽搷浣溿€傝繘鍏ュ瘑鐮佹満鑷甫鐨勭鐞嗗悗鍙板彲浠ヤ负TDE鐢熸垚瀵瑰簲鐨勫瘑閽ワ紝瀵圭О鍔犲瘑绠楁硶鍙€夋嫨AES鎴栬€呭浗瀵哠M4銆傚瘑閽ョ敓鎴愬悗浼氭湁涓€涓搴旂殑KeyID浣滀负璇ュ瘑閽ュ湪瀵嗙爜鏈轰腑鐨勫敮涓€鏍囪瘑锛屽湪鎺ヤ笅鏉ラ厤缃腑浼氱敤鍒般€�

#### 閰嶇疆PKCS11

闀垮畨閾惧熀浜嶱KCS11鏍囧噯涓庡瘑鐮佹満杩涜閫氳锛屽叾瀵瑰簲鐨勯厤缃湪chainmaker.yml閰嶇疆鏂囦欢鐨刵ode閰嶇疆鑺傜偣涓嬶紝閰嶇疆绀轰緥濡備笅锛�

```
node:
  pkcs11:
    enabled: true
    library: /usr/local/lib64/pkcs11/libupkcs11.so      # path to the so file of pkcs11 interface
    label: HSM                                          # label for the slot to be used
    password: 11111111                                  # password to logon the HSM
    session_cache_size: 10                              # size of HSM session cache, default to 10
    hash: "SHA256"                                      # hash algorithm used to compute SKI
```

鍏蜂綋閰嶇疆鍥犱负瀵瑰簲鐨勫瘑鐮佹満涓嶅悓鑰屼笉鍚岋紝鍏蜂綋鍙傝[纭欢鍔犲瘑](纭欢鍔犲瘑.md)绔犺妭銆�

#### 閰嶇疆閫忔槑鏁版嵁鍔犲瘑

鍦ㄥ畬鎴愪簡node閰嶇疆鑺傜偣涓嬬殑pkcs11閰嶇疆鍚庯紝鎺ヤ笅鏉ラ渶瑕佽繘琛宻torage閰嶇疆鑺傜偣涓嬪叧浜嶵DE鍔犲瘑绠楁硶鍜屽瘑閽ョ殑閰嶇疆锛屽浜庡瘑鐮佹満锛屾垜浠苟涓嶇煡閬撳搴旂殑瀵嗛挜鍐呭锛屽彧鏈夊瘑閽ョ殑ID锛屾墍浠ユ垜浠彧闇€瑕侀厤缃垚瀵瑰簲鐨凨eyID鍗冲彲锛屾瘮濡傦細

```
storage:
  encryptor: sm4    # sm4/aes
  encrypt_key: "MasterKey1" #瀵嗙爜鏈轰笂瀵瑰簲KeyID
```

#### 鍚敤鑺傜偣

鍦ㄥ畬鎴愰厤缃悗锛屽悓鏍锋槸闇€瑕佷繚璇佹湰鑺傜偣鐨勬暟鎹簱鏄┖鐨勶紝濡傛灉涔嬪墠宸茬粡鍚屾杩囧尯鍧楁垨鑰呭凡缁忓啓鍏ヤ簡鍒涗笘鍖哄潡锛岄兘闇€瑕佸垹闄ゃ€傚惎鍔ㄨ妭鐐瑰悗锛岄暱瀹夐摼灏嗕細鎶婃墍鏈夊啓鍏ユ暟鎹簱鐨勯敭鍊煎鏁版嵁涓殑Value閮ㄥ垎鍙戦€佺粰瀵嗙爜鏈鸿繘琛屽姞瀵嗭紝灏嗗姞瀵嗗悗鐨勫唴瀹硅繘琛屽瓨鍌ㄣ€�