Merge pull request #1508 from karalabe/database-caching
cmd, core, eth, ethdb: cache flag to allocate memory for db internal use
This commit is contained in:
commit
b403b9e4c3
@ -281,6 +281,7 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
|
|||||||
utils.BootnodesFlag,
|
utils.BootnodesFlag,
|
||||||
utils.DataDirFlag,
|
utils.DataDirFlag,
|
||||||
utils.BlockchainVersionFlag,
|
utils.BlockchainVersionFlag,
|
||||||
|
utils.CacheFlag,
|
||||||
utils.JSpathFlag,
|
utils.JSpathFlag,
|
||||||
utils.ListenPortFlag,
|
utils.ListenPortFlag,
|
||||||
utils.MaxPeersFlag,
|
utils.MaxPeersFlag,
|
||||||
@ -501,7 +502,7 @@ func blockRecovery(ctx *cli.Context) {
|
|||||||
cfg := utils.MakeEthConfig(ClientIdentifier, nodeNameVersion, ctx)
|
cfg := utils.MakeEthConfig(ClientIdentifier, nodeNameVersion, ctx)
|
||||||
utils.CheckLegalese(cfg.DataDir)
|
utils.CheckLegalese(cfg.DataDir)
|
||||||
|
|
||||||
blockDb, err := ethdb.NewLDBDatabase(filepath.Join(cfg.DataDir, "blockchain"))
|
blockDb, err := ethdb.NewLDBDatabase(filepath.Join(cfg.DataDir, "blockchain"), cfg.DatabaseCache)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Fatalln("could not open db:", err)
|
glog.Fatalln("could not open db:", err)
|
||||||
}
|
}
|
||||||
|
@ -126,6 +126,11 @@ var (
|
|||||||
Name: "natspec",
|
Name: "natspec",
|
||||||
Usage: "Enable NatSpec confirmation notice",
|
Usage: "Enable NatSpec confirmation notice",
|
||||||
}
|
}
|
||||||
|
CacheFlag = cli.IntFlag{
|
||||||
|
Name: "cache",
|
||||||
|
Usage: "Megabytes of memory allocated to internal caching",
|
||||||
|
Value: 0,
|
||||||
|
}
|
||||||
|
|
||||||
// miner settings
|
// miner settings
|
||||||
MinerThreadsFlag = cli.IntFlag{
|
MinerThreadsFlag = cli.IntFlag{
|
||||||
@ -384,6 +389,7 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
|
|||||||
GenesisNonce: ctx.GlobalInt(GenesisNonceFlag.Name),
|
GenesisNonce: ctx.GlobalInt(GenesisNonceFlag.Name),
|
||||||
GenesisFile: ctx.GlobalString(GenesisFileFlag.Name),
|
GenesisFile: ctx.GlobalString(GenesisFileFlag.Name),
|
||||||
BlockChainVersion: ctx.GlobalInt(BlockchainVersionFlag.Name),
|
BlockChainVersion: ctx.GlobalInt(BlockchainVersionFlag.Name),
|
||||||
|
DatabaseCache: ctx.GlobalInt(CacheFlag.Name),
|
||||||
SkipBcVersionCheck: false,
|
SkipBcVersionCheck: false,
|
||||||
NetworkId: ctx.GlobalInt(NetworkIdFlag.Name),
|
NetworkId: ctx.GlobalInt(NetworkIdFlag.Name),
|
||||||
LogFile: ctx.GlobalString(LogFileFlag.Name),
|
LogFile: ctx.GlobalString(LogFileFlag.Name),
|
||||||
@ -425,15 +431,17 @@ func SetupLogger(ctx *cli.Context) {
|
|||||||
|
|
||||||
// MakeChain creates a chain manager from set command line flags.
|
// MakeChain creates a chain manager from set command line flags.
|
||||||
func MakeChain(ctx *cli.Context) (chain *core.ChainManager, blockDB, stateDB, extraDB common.Database) {
|
func MakeChain(ctx *cli.Context) (chain *core.ChainManager, blockDB, stateDB, extraDB common.Database) {
|
||||||
dd := ctx.GlobalString(DataDirFlag.Name)
|
datadir := ctx.GlobalString(DataDirFlag.Name)
|
||||||
|
cache := ctx.GlobalInt(CacheFlag.Name)
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
if blockDB, err = ethdb.NewLDBDatabase(filepath.Join(dd, "blockchain")); err != nil {
|
if blockDB, err = ethdb.NewLDBDatabase(filepath.Join(datadir, "blockchain"), cache); err != nil {
|
||||||
Fatalf("Could not open database: %v", err)
|
Fatalf("Could not open database: %v", err)
|
||||||
}
|
}
|
||||||
if stateDB, err = ethdb.NewLDBDatabase(filepath.Join(dd, "state")); err != nil {
|
if stateDB, err = ethdb.NewLDBDatabase(filepath.Join(datadir, "state"), cache); err != nil {
|
||||||
Fatalf("Could not open database: %v", err)
|
Fatalf("Could not open database: %v", err)
|
||||||
}
|
}
|
||||||
if extraDB, err = ethdb.NewLDBDatabase(filepath.Join(dd, "extra")); err != nil {
|
if extraDB, err = ethdb.NewLDBDatabase(filepath.Join(datadir, "extra"), cache); err != nil {
|
||||||
Fatalf("Could not open database: %v", err)
|
Fatalf("Could not open database: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) {
|
|||||||
b.Fatalf("cannot create temporary directory: %v", err)
|
b.Fatalf("cannot create temporary directory: %v", err)
|
||||||
}
|
}
|
||||||
defer os.RemoveAll(dir)
|
defer os.RemoveAll(dir)
|
||||||
db, err = ethdb.NewLDBDatabase(dir)
|
db, err = ethdb.NewLDBDatabase(dir, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("cannot create temporary database: %v", err)
|
b.Fatalf("cannot create temporary database: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,7 @@ type Config struct {
|
|||||||
|
|
||||||
BlockChainVersion int
|
BlockChainVersion int
|
||||||
SkipBcVersionCheck bool // e.g. blockchain export
|
SkipBcVersionCheck bool // e.g. blockchain export
|
||||||
|
DatabaseCache int
|
||||||
|
|
||||||
DataDir string
|
DataDir string
|
||||||
LogFile string
|
LogFile string
|
||||||
@ -261,7 +262,7 @@ func New(config *Config) (*Ethereum, error) {
|
|||||||
|
|
||||||
newdb := config.NewDB
|
newdb := config.NewDB
|
||||||
if newdb == nil {
|
if newdb == nil {
|
||||||
newdb = func(path string) (common.Database, error) { return ethdb.NewLDBDatabase(path) }
|
newdb = func(path string) (common.Database, error) { return ethdb.NewLDBDatabase(path, config.DatabaseCache) }
|
||||||
}
|
}
|
||||||
blockDb, err := newdb(filepath.Join(config.DataDir, "blockchain"))
|
blockDb, err := newdb(filepath.Join(config.DataDir, "blockchain"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package ethdb
|
package ethdb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -36,6 +37,14 @@ import (
|
|||||||
|
|
||||||
var OpenFileLimit = 64
|
var OpenFileLimit = 64
|
||||||
|
|
||||||
|
// cacheRatio specifies how the total alloted cache is distributed between the
|
||||||
|
// various system databases.
|
||||||
|
var cacheRatio = map[string]float64{
|
||||||
|
"blockchain": 1.0 / 13.0,
|
||||||
|
"extra": 2.0 / 13.0,
|
||||||
|
"state": 10.0 / 13.0,
|
||||||
|
}
|
||||||
|
|
||||||
type LDBDatabase struct {
|
type LDBDatabase struct {
|
||||||
fn string // filename for reporting
|
fn string // filename for reporting
|
||||||
db *leveldb.DB // LevelDB instance
|
db *leveldb.DB // LevelDB instance
|
||||||
@ -57,14 +66,24 @@ type LDBDatabase struct {
|
|||||||
// NewLDBDatabase returns a LevelDB wrapped object. LDBDatabase does not persist data by
|
// NewLDBDatabase returns a LevelDB wrapped object. LDBDatabase does not persist data by
|
||||||
// it self but requires a background poller which syncs every X. `Flush` should be called
|
// it self but requires a background poller which syncs every X. `Flush` should be called
|
||||||
// when data needs to be stored and written to disk.
|
// when data needs to be stored and written to disk.
|
||||||
func NewLDBDatabase(file string) (*LDBDatabase, error) {
|
func NewLDBDatabase(file string, cache int) (*LDBDatabase, error) {
|
||||||
// Open the db
|
// Calculate the cache allowance for this particular database
|
||||||
db, err := leveldb.OpenFile(file, &opt.Options{OpenFilesCacheCapacity: OpenFileLimit})
|
cache = int(float64(cache) * cacheRatio[filepath.Base(file)])
|
||||||
// check for corruption and attempt to recover
|
if cache < 16 {
|
||||||
if _, iscorrupted := err.(*errors.ErrCorrupted); iscorrupted {
|
cache = 16
|
||||||
|
}
|
||||||
|
glog.V(logger.Info).Infof("Alloted %dMB cache to %s", cache, file)
|
||||||
|
|
||||||
|
// Open the db and recover any potential corruptions
|
||||||
|
db, err := leveldb.OpenFile(file, &opt.Options{
|
||||||
|
OpenFilesCacheCapacity: OpenFileLimit,
|
||||||
|
BlockCacheCapacity: cache / 2 * opt.MiB,
|
||||||
|
WriteBuffer: cache / 4 * opt.MiB, // Two of these are used internally
|
||||||
|
})
|
||||||
|
if _, corrupted := err.(*errors.ErrCorrupted); corrupted {
|
||||||
db, err = leveldb.RecoverFile(file, nil)
|
db, err = leveldb.RecoverFile(file, nil)
|
||||||
}
|
}
|
||||||
// (re) check for errors and abort if opening of the db failed
|
// (Re)check for errors and abort if opening of the db failed
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,7 @@ func newDb() *LDBDatabase {
|
|||||||
if common.FileExist(file) {
|
if common.FileExist(file) {
|
||||||
os.RemoveAll(file)
|
os.RemoveAll(file)
|
||||||
}
|
}
|
||||||
|
db, _ := NewLDBDatabase(file, 0)
|
||||||
db, _ := NewLDBDatabase(file)
|
|
||||||
|
|
||||||
return db
|
return db
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user