diff options
author | rjl493456442 <garyrong0905@gmail.com> | 2019-03-14 14:59:47 +0800 |
---|---|---|
committer | Péter Szilágyi <peterke@gmail.com> | 2019-05-16 15:39:31 +0800 |
commit | b6cac42e9ffc0b19a1e70416db85593f1cb0d30c (patch) | |
tree | 1102c442e3c400ed3388999f6be706e777343664 | |
parent | b69bdc2a4f8efab7cb99934652e2d9b2508c4544 (diff) | |
download | go-tangerine-b6cac42e9ffc0b19a1e70416db85593f1cb0d30c.tar go-tangerine-b6cac42e9ffc0b19a1e70416db85593f1cb0d30c.tar.gz go-tangerine-b6cac42e9ffc0b19a1e70416db85593f1cb0d30c.tar.bz2 go-tangerine-b6cac42e9ffc0b19a1e70416db85593f1cb0d30c.tar.lz go-tangerine-b6cac42e9ffc0b19a1e70416db85593f1cb0d30c.tar.xz go-tangerine-b6cac42e9ffc0b19a1e70416db85593f1cb0d30c.tar.zst go-tangerine-b6cac42e9ffc0b19a1e70416db85593f1cb0d30c.zip |
core/rawdb: add file lock for freezer
-rw-r--r-- | core/rawdb/database.go | 22 | ||||
-rw-r--r-- | core/rawdb/freezer.go | 19 | ||||
-rw-r--r-- | ethdb/database.go | 7 |
3 files changed, 43 insertions, 5 deletions
diff --git a/core/rawdb/database.go b/core/rawdb/database.go index 0f994c3fd..cd1048cbc 100644 --- a/core/rawdb/database.go +++ b/core/rawdb/database.go @@ -17,6 +17,8 @@ package rawdb import ( + "fmt" + "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb/leveldb" "github.com/ethereum/go-ethereum/ethdb/memorydb" @@ -25,7 +27,23 @@ import ( // freezerdb is a databse wrapper that enabled freezer data retrievals. type freezerdb struct { ethdb.KeyValueStore - ethdb.Ancienter + ethdb.AncientStore +} + +// Close implements io.Closer, closing both the fast key-value store as well as +// the slow ancient tables. +func (frdb *freezerdb) Close() error { + var errs []error + if err := frdb.KeyValueStore.Close(); err != nil { + errs = append(errs, err) + } + if err := frdb.AncientStore.Close(); err != nil { + errs = append(errs, err) + } + if len(errs) != 0 { + return fmt.Errorf("%v", errs) + } + return nil } // nofreezedb is a database wrapper that disables freezer data retrievals. @@ -58,7 +76,7 @@ func NewDatabaseWithFreezer(db ethdb.KeyValueStore, freezer string, namespace st return &freezerdb{ KeyValueStore: db, - Ancienter: frdb, + AncientStore: frdb, }, nil } diff --git a/core/rawdb/freezer.go b/core/rawdb/freezer.go index 4f227e3b7..07df4c759 100644 --- a/core/rawdb/freezer.go +++ b/core/rawdb/freezer.go @@ -20,6 +20,7 @@ import ( "errors" "fmt" "math" + "path/filepath" "sync/atomic" "time" @@ -27,6 +28,7 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" + "github.com/prometheus/tsdb/fileutil" ) // errUnknownTable is returned if the user attempts to read from a table that is @@ -57,8 +59,9 @@ const ( // reserving it for go-ethereum. This would also reduce the memory requirements // of Geth, and thus also GC overhead. type freezer struct { - tables map[string]*freezerTable // Data tables for storing everything - frozen uint64 // Number of blocks already frozen + tables map[string]*freezerTable // Data tables for storing everything + frozen uint64 // Number of blocks already frozen + instanceLock fileutil.Releaser // File-system lock to prevent double opens } // newFreezer creates a chain freezer that moves ancient chain data into @@ -69,9 +72,14 @@ func newFreezer(datadir string, namespace string) (*freezer, error) { readMeter = metrics.NewRegisteredMeter(namespace+"ancient/read", nil) writeMeter = metrics.NewRegisteredMeter(namespace+"ancient/write", nil) ) + lock, _, err := fileutil.Flock(filepath.Join(datadir, "LOCK")) + if err != nil { + return nil, err + } // Open all the supported data tables freezer := &freezer{ - tables: make(map[string]*freezerTable), + tables: make(map[string]*freezerTable), + instanceLock: lock, } for _, name := range []string{"hashes", "headers", "bodies", "receipts", "diffs"} { table, err := newTable(datadir, name, readMeter, writeMeter) @@ -79,6 +87,7 @@ func newFreezer(datadir string, namespace string) (*freezer, error) { for _, table := range freezer.tables { table.Close() } + lock.Release() return nil, err } freezer.tables[name] = table @@ -95,6 +104,7 @@ func newFreezer(datadir string, namespace string) (*freezer, error) { for _, table := range freezer.tables { table.Close() } + lock.Release() return nil, err } } @@ -109,6 +119,9 @@ func (f *freezer) Close() error { errs = append(errs, err) } } + if err := f.instanceLock.Release(); err != nil { + errs = append(errs, err) + } if errs != nil { return fmt.Errorf("%v", errs) } diff --git a/ethdb/database.go b/ethdb/database.go index 764e304e3..01483f3d4 100644 --- a/ethdb/database.go +++ b/ethdb/database.go @@ -80,6 +80,13 @@ type AncientReader interface { Ancienter } +// AncientStore contains all the methods required to allow handling different +// ancient data stores backing immutable chain data store. +type AncientStore interface { + Ancienter + io.Closer +} + // Database contains all the methods required by the high level database to not // only access the key-value data store but also the chain freezer. type Database interface { |