From 0106acbf7ea5fbb2e718457fa11faeaecee7c59e Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Thu, 20 Jun 2019 10:17:38 -0400 Subject: Avoid a read-write transaction on DB init Instead, use a less expensive read-only transaction to see if the DB is ready for use (it probably is), and only fire the expensive RW transaction if absolutely necessary. Signed-off-by: Matthew Heon --- libpod/boltdb_state.go | 70 ++++++++++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 31 deletions(-) (limited to 'libpod') diff --git a/libpod/boltdb_state.go b/libpod/boltdb_state.go index 63e40a98f..12c364993 100644 --- a/libpod/boltdb_state.go +++ b/libpod/boltdb_state.go @@ -73,42 +73,50 @@ func NewBoltState(path string, runtime *Runtime) (State, error) { // As such, just a db.Close() is fine here. defer db.Close() - // Perform initial database setup - err = db.Update(func(tx *bolt.Tx) error { - if _, err := tx.CreateBucketIfNotExists(idRegistryBkt); err != nil { - return errors.Wrapf(err, "error creating id-registry bucket") - } - if _, err := tx.CreateBucketIfNotExists(nameRegistryBkt); err != nil { - return errors.Wrapf(err, "error creating name-registry bucket") - } - if _, err := tx.CreateBucketIfNotExists(nsRegistryBkt); err != nil { - return errors.Wrapf(err, "error creating ns-registry bucket") - } - if _, err := tx.CreateBucketIfNotExists(ctrBkt); err != nil { - return errors.Wrapf(err, "error creating containers bucket") - } - if _, err := tx.CreateBucketIfNotExists(allCtrsBkt); err != nil { - return errors.Wrapf(err, "error creating all containers bucket") - } - if _, err := tx.CreateBucketIfNotExists(podBkt); err != nil { - return errors.Wrapf(err, "error creating pods bucket") - } - if _, err := tx.CreateBucketIfNotExists(allPodsBkt); err != nil { - return errors.Wrapf(err, "error creating all pods bucket") - } - if _, err := tx.CreateBucketIfNotExists(volBkt); err != nil { - return errors.Wrapf(err, "error creating volume bucket") - } - if _, err := tx.CreateBucketIfNotExists(allVolsBkt); err != nil { - return errors.Wrapf(err, "error creating all volumes bucket") + createBuckets := [][]byte{ + idRegistryBkt, + nameRegistryBkt, + nsRegistryBkt, + ctrBkt, + allCtrsBkt, + podBkt, + allPodsBkt, + volBkt, + allVolsBkt, + runtimeConfigBkt, + } + + // Does the DB need an update? + needsUpdate := false + err = db.View(func(tx *bolt.Tx) error { + for _, bkt := range createBuckets { + if test := tx.Bucket(bkt); test == nil { + needsUpdate = true + break + } } - if _, err := tx.CreateBucketIfNotExists(runtimeConfigBkt); err != nil { - return errors.Wrapf(err, "error creating runtime-config bucket") + return nil + }) + if err != nil { + return nil, errors.Wrapf(err, "error checking DB schema") + } + + if !needsUpdate { + state.valid = true + return state, nil + } + + // Ensure schema is properly created in DB + err = db.Update(func(tx *bolt.Tx) error { + for _, bkt := range createBuckets { + if _, err := tx.CreateBucketIfNotExists(bkt); err != nil { + return errors.Wrapf(err, "error creating bucket %s", string(bkt)) + } } return nil }) if err != nil { - return nil, errors.Wrapf(err, "error creating initial database layout") + return nil, errors.Wrapf(err, "error creating buckets for DB") } state.valid = true -- cgit v1.2.3-54-g00ecf