# 深入学习 Go-Ethereum : 011. CMD 模块 - Geth -dbcmd.go

By [OutOfToken](https://paragraph.com/@lua) · 2022-07-21

---

⬇️以下是 cmd/geth 包中其他代码的介绍：

    ├── accountcmd.go 
    ├── chaincmd.go 
    ├── config.go 
    ├── consolecmd.go 
    ├── dbcmd.go 🔫
    ├── misccmd.go
    ├── snapshot.go
    ├── usage.go
    └── version_check.go
    

[《深入学习 Go-Ethereum : 010. CMD 模块 - Geth - consolecmd.go》](https://mirror.xyz/laosan.eth/Tb3ppjEJqUBbbYjuBiGFhoSCm5_OTM1Oe2oIa-Wj-5M)中罗列了 `consolecmd` 主要源码，接下来描述下关于 `dbcmd.go` 中的代码功能。

dbcmd 会依赖 [go-ethereum](https://github.com/ethereum/go-ethereum) 项目源码中

`"github.com/ethereum/go-ethereum/cmd/utils"`、 `"github.com/ethereum/go-ethereum/common"`、 `"github.com/ethereum/go-ethereum/common/hexutil"`、 `"github.com/ethereum/go-ethereum/console/prompt"`、 `"github.com/ethereum/go-ethereum/core/rawdb"`、 `"github.com/ethereum/go-ethereum/core/state/snapshot"`、 `"github.com/ethereum/go-ethereum/core/types"`、 `"github.com/ethereum/go-ethereum/ethdb"`、 `"github.com/ethereum/go-ethereum/log"`、 `"github.com/ethereum/go-ethereum/trie"` 相关组件。

⬇️ dbcmd.go
-----------

dbcmd 主要功能是操作[levelDB](https://github.com/google/leveldb)(一个本地的 Key-Value 数据库)，代码主要包含了 `db` 命令和 `13 个子命令`及实现相应功能的函数。

![dbcmd.go 代码结构](https://storage.googleapis.com/papyrus_images/56dc6fd32b8609d0f848fbb4148c700e3d5a2be513a84e512697f7f0a9e30b85.png)

dbcmd.go 代码结构

`geth db --help` 查看子命令列表及简介

![](https://storage.googleapis.com/papyrus_images/4ce756629408822c7d4140db1d142fee3fb91b4adac7d3b77f1756697e055447.png)

### ⬇️ removeDB 方法：

查看 db 统计信息

![](https://storage.googleapis.com/papyrus_images/322dc66a001b2ee64532b0648dbeb7c2876f12dd5bceeaa7b1cc81340d21af65.png)

删除数据库中数据 `geth removedb`

![](https://storage.googleapis.com/papyrus_images/1e68f57d60a39aa4a26fbbd2a45b4bc1a4c6ad4a1c9f1a989c24aedc9abfc1bc.png)

再次查看数据库，不存在数据库文件

![](https://storage.googleapis.com/papyrus_images/0df94971598fb3914c992500754702cddc8ae5bb8a45359cc86e9068b1632a9a.png)

代码主逻辑⬇️：

![removedb 命令对应的方法](https://storage.googleapis.com/papyrus_images/cbe4c4a9d7bba2abfeca859e7953dc245274fee339dd12eb96e501b9dfbf4430.png)

removedb 命令对应的方法

提醒用户确认并删除数据文件⬇️

![内部方法，提醒用户确认并删除文件](https://storage.googleapis.com/papyrus_images/80589ddb4f0852a2ea134cf2389bf04dc4641b00e15ebc59a06bbd0ad2413089.png)

内部方法，提醒用户确认并删除文件

### ⬇️ inspect 方法：

主要作用是检查当前数据库中的数据分布，代码如下图⬇️，主要逻辑处理 `rawdb.InspectDatabase()` 。

![inspect 命令对应的方法](https://storage.googleapis.com/papyrus_images/5014bf72f1d3cab0b198a81228402dc6318516ac0f553d04d3dd63722d3fa090.png)

inspect 命令对应的方法

对比参数查询结果：`左侧是有前缀参数`、`右侧无参数（全数据库）` 。

![使用效果对比](https://storage.googleapis.com/papyrus_images/b1ad66cea8273f0dca7b0e6c1abec7df0ecab9f3c71216feafb0cbccd7fd33cc.png)

使用效果对比

### ⬇️ dbStats 方法：

主要作用查询数据库存储状态,其中最重要的代码逻辑是

1.  `db.Stat()` →
    
2.  ethdb/leveldb/leveldb.go 代码中的 [db.db.GetProperty()](https://github.com/HugePages/go-ethereum/blob/21a09da78fd3e032f36ebd4bf7c3d7944faa92e3/ethdb/leveldb/leveldb.go#L246) →
    
3.  leveldb/db.go 代码中的 [GetProperty()](https://github.com/syndtr/goleveldb/blob/64ee5596c38af10edb6d93e1327b3ed1739747c7/leveldb/db.go#L954)，获取levelDB的统计数据
    

![dbStates方法代码截图](https://storage.googleapis.com/papyrus_images/02324b86d4cc3c56c39f4e8c7f7a41cee21dd6088f03ec1c42d93ed6e5f66782.png)

dbStates方法代码截图

### ⬇️ dbCompact 方法：

`Compact` 主要作用「压缩」数据，对指定范围 start ，limit 两个参数范围内的数据进行处理，本质上是对 `删除的` 数据和`不再使用的版本`数据 进行重排序。（⚠️：此方法会花费较长时间。同时对数据进行加锁）

1.  `db.Compact()` →
    
2.  ethdb/leveldb/leveldb.go 代码中的 [db.db.CompactRange()](https://github.com/HugePages/go-ethereum/blob/21a09da78fd3e032f36ebd4bf7c3d7944faa92e3/ethdb/leveldb/leveldb.go#L257) →
    
3.  leveldb/db\_write.go 代码中的 [CompactRange()](https://github.com/syndtr/goleveldb/blob/64ee5596c38af10edb6d93e1327b3ed1739747c7/leveldb/db_write.go#L403)，进行数据压缩处理
    

![dbCompact方法代码截图](https://storage.googleapis.com/papyrus_images/272f74b7011f2dd15fbf618834e7da797ee96bb8a074060bc4ed13bd89d9a7e3.png)

dbCompact方法代码截图

### ⬇️ dbGet、dbDelete、dbPut 方法：

主要是使用 levelDB 的 db.go 进行操作。

![](https://storage.googleapis.com/papyrus_images/0eea09dd9b313d4a968ad3220e383e70d21fbb096c260102f51595fbc6a5e14f.png)

### ⬇️ dbDumpTrie 方法：

指定根节点进行数据导出操作。

![dbDumpTrie方法代码截图](https://storage.googleapis.com/papyrus_images/f5570bee457e777c026262948746a41764c8389bdb525fb132f7adeef33ccc6b.png)

dbDumpTrie方法代码截图

### ⬇️ freezerInspect 方法：

导出”冷数据“，指定导出的数据类型，开始数据 index，和结束数据 index。

数据类型参数范围是\[bodies diffs hashes headers receipts\]

![](https://storage.googleapis.com/papyrus_images/036ca0315008acc3424709dd7ac9cffa6609ae58fdc3f886801178d2108ad1b5.png)

通过下面命令进行 “凉凉“ 数据进行 dump 操作。

![操作示例](https://storage.googleapis.com/papyrus_images/6f8552d58aa44ac47d74524f19134959d7c7438837a82b2f5b86bcb0f0458635.png)

操作示例

### ⬇️ importLDBdata 方法：

导入指定文件(以RLP格式进行快照)数据到 `eth.Database` ,如果是 `gz` 文件会通过 `gzip` 进行文件操作。

[// ImportLDBData imports a batch of snapshot data into the database](https://github.com/HugePages/go-ethereum/blob/21a09da78fd3e032f36ebd4bf7c3d7944faa92e3/cmd/utils/cmd.go#L387) 可以查看 `utils.ImportLDBData()` 具体实现

![](https://storage.googleapis.com/papyrus_images/fb9c80c8d84b83eb449805fbaa9ffac583981b1e6508d57076516bc2613f60b2.png)

### ⬇️ exportChaindata 方法：

与 import 对应的方法就是数据的导出。导出需要指定数据是preimage还是snapshot，此外需要指定导出文件名及文件后缀名，如果是gz格式，程序会使用gzip进行文件压缩。

调用[ExportChaindata()](https://github.com/HugePages/go-ethereum/blob/21a09da78fd3e032f36ebd4bf7c3d7944faa92e3/cmd/utils/cmd.go#L505)进行数据文件生成

![exportChaindata方法](https://storage.googleapis.com/papyrus_images/5db84ceb467769fded95469626bdbc7e04c8004114b0a16c04acfee2860f8fcc.png)

exportChaindata方法

### ⬇️ showMetaData 方法：

显示levelDB相关元数据信息，比如数据库版本、头信息、快照信息等

![showMetaData方法](https://storage.googleapis.com/papyrus_images/40ebe6cb5c0379b640970b2ac62b80b6c8d626d4f6bc145c464058ff0eb5a18e.png)

showMetaData方法

### ⬇️ freezerMigrate 方法：

迁移”冷数据“，到指定表中`「receipts」`

![](https://storage.googleapis.com/papyrus_images/7140c50d2f16fc030854a5dc941819b1ab77e2513c39a22237f833c232136acd.png)

以上是dbcmd中代码的主要功能。底层依赖ethdb进行操作KV数据库leveldb。

---

*Originally published on [OutOfToken](https://paragraph.com/@lua/go-ethereum-011-cmd-geth-dbcmd-go)*
