core/rawdb, ethdb/pebble: avoid fsync db in tests (#27836)

Adds an option to disable fsync for database operations.
This is to make tests faster.
pull/27994/head
Martin Holst Swende 1 year ago committed by GitHub
parent 5c7136adb4
commit f0f8703bf2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      core/blockchain_repair_test.go
  2. 1
      core/blockchain_sethead_test.go
  3. 2
      core/blockchain_snapshot_test.go
  4. 7
      core/rawdb/database.go
  5. 4
      core/rawdb/databases_64bit.go
  6. 15
      ethdb/pebble/pebble.go

@ -1767,6 +1767,7 @@ func testRepairWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme s
db, err := rawdb.Open(rawdb.OpenOptions{ db, err := rawdb.Open(rawdb.OpenOptions{
Directory: datadir, Directory: datadir,
AncientsDirectory: ancient, AncientsDirectory: ancient,
Ephemeral: true,
}) })
if err != nil { if err != nil {
t.Fatalf("Failed to create persistent database: %v", err) t.Fatalf("Failed to create persistent database: %v", err)
@ -1847,6 +1848,7 @@ func testRepairWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme s
db, err = rawdb.Open(rawdb.OpenOptions{ db, err = rawdb.Open(rawdb.OpenOptions{
Directory: datadir, Directory: datadir,
AncientsDirectory: ancient, AncientsDirectory: ancient,
Ephemeral: true,
}) })
if err != nil { if err != nil {
t.Fatalf("Failed to reopen persistent database: %v", err) t.Fatalf("Failed to reopen persistent database: %v", err)
@ -1968,6 +1970,7 @@ func testIssue23496(t *testing.T, scheme string) {
db, err = rawdb.Open(rawdb.OpenOptions{ db, err = rawdb.Open(rawdb.OpenOptions{
Directory: datadir, Directory: datadir,
AncientsDirectory: ancient, AncientsDirectory: ancient,
Ephemeral: true,
}) })
if err != nil { if err != nil {
t.Fatalf("Failed to reopen persistent database: %v", err) t.Fatalf("Failed to reopen persistent database: %v", err)

@ -1971,6 +1971,7 @@ func testSetHeadWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme
db, err := rawdb.Open(rawdb.OpenOptions{ db, err := rawdb.Open(rawdb.OpenOptions{
Directory: datadir, Directory: datadir,
AncientsDirectory: ancient, AncientsDirectory: ancient,
Ephemeral: true,
}) })
if err != nil { if err != nil {
t.Fatalf("Failed to create persistent database: %v", err) t.Fatalf("Failed to create persistent database: %v", err)

@ -68,6 +68,7 @@ func (basic *snapshotTestBasic) prepare(t *testing.T) (*BlockChain, []*types.Blo
db, err := rawdb.Open(rawdb.OpenOptions{ db, err := rawdb.Open(rawdb.OpenOptions{
Directory: datadir, Directory: datadir,
AncientsDirectory: ancient, AncientsDirectory: ancient,
Ephemeral: true,
}) })
if err != nil { if err != nil {
t.Fatalf("Failed to create persistent database: %v", err) t.Fatalf("Failed to create persistent database: %v", err)
@ -258,6 +259,7 @@ func (snaptest *crashSnapshotTest) test(t *testing.T) {
newdb, err := rawdb.Open(rawdb.OpenOptions{ newdb, err := rawdb.Open(rawdb.OpenOptions{
Directory: snaptest.datadir, Directory: snaptest.datadir,
AncientsDirectory: snaptest.ancient, AncientsDirectory: snaptest.ancient,
Ephemeral: true,
}) })
if err != nil { if err != nil {
t.Fatalf("Failed to reopen persistent database: %v", err) t.Fatalf("Failed to reopen persistent database: %v", err)

@ -352,6 +352,9 @@ type OpenOptions struct {
Cache int // the capacity(in megabytes) of the data caching Cache int // the capacity(in megabytes) of the data caching
Handles int // number of files to be open simultaneously Handles int // number of files to be open simultaneously
ReadOnly bool ReadOnly bool
// Ephemeral means that filesystem sync operations should be avoided: data integrity in the face of
// a crash is not important. This option should typically be used in tests.
Ephemeral bool
} }
// openKeyValueDatabase opens a disk-based key-value database, e.g. leveldb or pebble. // openKeyValueDatabase opens a disk-based key-value database, e.g. leveldb or pebble.
@ -374,7 +377,7 @@ func openKeyValueDatabase(o OpenOptions) (ethdb.Database, error) {
if o.Type == dbPebble || existingDb == dbPebble { if o.Type == dbPebble || existingDb == dbPebble {
if PebbleEnabled { if PebbleEnabled {
log.Info("Using pebble as the backing database") log.Info("Using pebble as the backing database")
return NewPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly) return NewPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly, o.Ephemeral)
} else { } else {
return nil, errors.New("db.engine 'pebble' not supported on this platform") return nil, errors.New("db.engine 'pebble' not supported on this platform")
} }
@ -387,7 +390,7 @@ func openKeyValueDatabase(o OpenOptions) (ethdb.Database, error) {
// on supported platforms and LevelDB on anything else. // on supported platforms and LevelDB on anything else.
if PebbleEnabled { if PebbleEnabled {
log.Info("Defaulting to pebble as the backing database") log.Info("Defaulting to pebble as the backing database")
return NewPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly) return NewPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly, o.Ephemeral)
} else { } else {
log.Info("Defaulting to leveldb as the backing database") log.Info("Defaulting to leveldb as the backing database")
return NewLevelDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly) return NewLevelDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly)

@ -28,8 +28,8 @@ const PebbleEnabled = true
// NewPebbleDBDatabase creates a persistent key-value database without a freezer // NewPebbleDBDatabase creates a persistent key-value database without a freezer
// moving immutable chain segments into cold storage. // moving immutable chain segments into cold storage.
func NewPebbleDBDatabase(file string, cache int, handles int, namespace string, readonly bool) (ethdb.Database, error) { func NewPebbleDBDatabase(file string, cache int, handles int, namespace string, readonly, ephemeral bool) (ethdb.Database, error) {
db, err := pebble.New(file, cache, handles, namespace, readonly) db, err := pebble.New(file, cache, handles, namespace, readonly, ephemeral)
if err != nil { if err != nil {
return nil, err return nil, err
} }

@ -84,6 +84,8 @@ type Database struct {
writeDelayStartTime time.Time // The start time of the latest write stall writeDelayStartTime time.Time // The start time of the latest write stall
writeDelayCount atomic.Int64 // Total number of write stall counts writeDelayCount atomic.Int64 // Total number of write stall counts
writeDelayTime atomic.Int64 // Total time spent in write stalls writeDelayTime atomic.Int64 // Total time spent in write stalls
writeOptions *pebble.WriteOptions
} }
func (d *Database) onCompactionBegin(info pebble.CompactionInfo) { func (d *Database) onCompactionBegin(info pebble.CompactionInfo) {
@ -118,7 +120,7 @@ func (d *Database) onWriteStallEnd() {
// New returns a wrapped pebble DB object. The namespace is the prefix that the // New returns a wrapped pebble DB object. The namespace is the prefix that the
// metrics reporting should use for surfacing internal stats. // metrics reporting should use for surfacing internal stats.
func New(file string, cache int, handles int, namespace string, readonly bool) (*Database, error) { func New(file string, cache int, handles int, namespace string, readonly bool, ephemeral bool) (*Database, error) {
// Ensure we have some minimal caching and file guarantees // Ensure we have some minimal caching and file guarantees
if cache < minCache { if cache < minCache {
cache = minCache cache = minCache
@ -142,9 +144,10 @@ func New(file string, cache int, handles int, namespace string, readonly bool) (
memTableSize = maxMemTableSize memTableSize = maxMemTableSize
} }
db := &Database{ db := &Database{
fn: file, fn: file,
log: logger, log: logger,
quitChan: make(chan chan error), quitChan: make(chan chan error),
writeOptions: &pebble.WriteOptions{Sync: !ephemeral},
} }
opt := &pebble.Options{ opt := &pebble.Options{
// Pebble has a single combined cache area and the write // Pebble has a single combined cache area and the write
@ -279,7 +282,7 @@ func (d *Database) Put(key []byte, value []byte) error {
if d.closed { if d.closed {
return pebble.ErrClosed return pebble.ErrClosed
} }
return d.db.Set(key, value, pebble.Sync) return d.db.Set(key, value, d.writeOptions)
} }
// Delete removes the key from the key-value store. // Delete removes the key from the key-value store.
@ -535,7 +538,7 @@ func (b *batch) Write() error {
if b.db.closed { if b.db.closed {
return pebble.ErrClosed return pebble.ErrClosed
} }
return b.b.Commit(pebble.Sync) return b.b.Commit(b.db.writeOptions)
} }
// Reset resets the batch for reuse. // Reset resets the batch for reuse.

Loading…
Cancel
Save