diff options
author | Matthew Heon <mheon@redhat.com> | 2019-06-20 10:17:38 -0400 |
---|---|---|
committer | Matthew Heon <matthew.heon@pm.me> | 2019-06-25 13:03:08 -0400 |
commit | 65fb42ad55647ebceb8057c4562da0d39da1382d (patch) | |
tree | 316f450557b6a9237496f4d250747d56db3d1258 | |
parent | 5995f1c9b954cb998572e9e26176b312bbdbfd02 (diff) | |
download | podman-65fb42ad55647ebceb8057c4562da0d39da1382d.tar.gz podman-65fb42ad55647ebceb8057c4562da0d39da1382d.tar.bz2 podman-65fb42ad55647ebceb8057c4562da0d39da1382d.zip |
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 <mheon@redhat.com>
-rw-r--r-- | libpod/boltdb_state.go | 70 |
1 files changed, 39 insertions, 31 deletions
diff --git a/libpod/boltdb_state.go b/libpod/boltdb_state.go index b154d8bda..fdae08bf3 100644 --- a/libpod/boltdb_state.go +++ b/libpod/boltdb_state.go @@ -71,42 +71,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 |