aboutsummaryrefslogtreecommitdiffstats
path: root/cmd/geth/chaincmd.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/geth/chaincmd.go')
-rw-r--r--cmd/geth/chaincmd.go63
1 files changed, 59 insertions, 4 deletions
diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go
index 553e5367c..c1bbbd8dc 100644
--- a/cmd/geth/chaincmd.go
+++ b/cmd/geth/chaincmd.go
@@ -20,7 +20,9 @@ import (
"fmt"
"os"
"path/filepath"
+ "runtime"
"strconv"
+ "sync/atomic"
"time"
"github.com/ethereum/go-ethereum/cmd/utils"
@@ -31,6 +33,8 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/logger/glog"
+ "github.com/ethereum/go-ethereum/trie"
+ "github.com/syndtr/goleveldb/leveldb/util"
"gopkg.in/urfave/cli.v1"
)
@@ -81,13 +85,64 @@ func importChain(ctx *cli.Context) error {
}
stack := makeFullNode(ctx)
chain, chainDb := utils.MakeChain(ctx, stack)
+ defer chainDb.Close()
+
+ // Start periodically gathering memory profiles
+ var peakMemAlloc, peakMemSys uint64
+ go func() {
+ stats := new(runtime.MemStats)
+ for {
+ runtime.ReadMemStats(stats)
+ if atomic.LoadUint64(&peakMemAlloc) < stats.Alloc {
+ atomic.StoreUint64(&peakMemAlloc, stats.Alloc)
+ }
+ if atomic.LoadUint64(&peakMemSys) < stats.Sys {
+ atomic.StoreUint64(&peakMemSys, stats.Sys)
+ }
+ time.Sleep(5 * time.Second)
+ }
+ }()
+ // Import the chain
start := time.Now()
- err := utils.ImportChain(chain, ctx.Args().First())
- chainDb.Close()
- if err != nil {
+ if err := utils.ImportChain(chain, ctx.Args().First()); err != nil {
utils.Fatalf("Import error: %v", err)
}
- fmt.Printf("Import done in %v", time.Since(start))
+ fmt.Printf("Import done in %v.\n\n", time.Since(start))
+
+ // Output pre-compaction stats mostly to see the import trashing
+ db := chainDb.(*ethdb.LDBDatabase)
+
+ stats, err := db.LDB().GetProperty("leveldb.stats")
+ if err != nil {
+ utils.Fatalf("Failed to read database stats: %v", err)
+ }
+ fmt.Println(stats)
+ fmt.Printf("Trie cache misses: %d\n", trie.CacheMisses())
+ fmt.Printf("Trie cache unloads: %d\n\n", trie.CacheUnloads())
+
+ // Print the memory statistics used by the importing
+ mem := new(runtime.MemStats)
+ runtime.ReadMemStats(mem)
+
+ fmt.Printf("Object memory: %.3f MB current, %.3f MB peak\n", float64(mem.Alloc)/1024/1024, float64(atomic.LoadUint64(&peakMemAlloc))/1024/1024)
+ fmt.Printf("System memory: %.3f MB current, %.3f MB peak\n", float64(mem.Sys)/1024/1024, float64(atomic.LoadUint64(&peakMemSys))/1024/1024)
+ fmt.Printf("Allocations: %.3f million\n", float64(mem.Mallocs)/1000000)
+ fmt.Printf("GC pause: %v\n\n", time.Duration(mem.PauseTotalNs))
+
+ // Compact the entire database to more accurately measure disk io and print the stats
+ start = time.Now()
+ fmt.Println("Compacting entire database...")
+ if err = db.LDB().CompactRange(util.Range{}); err != nil {
+ utils.Fatalf("Compaction failed: %v", err)
+ }
+ fmt.Printf("Compaction done in %v.\n\n", time.Since(start))
+
+ stats, err = db.LDB().GetProperty("leveldb.stats")
+ if err != nil {
+ utils.Fatalf("Failed to read database stats: %v", err)
+ }
+ fmt.Println(stats)
+
return nil
}