mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-08-29 15:11:09 +02:00
channeldb: added channeldb versioning
In this commit the upgrade mechanism for database was added which makes he current schema rigid and upgradeable. Additional bucket 'metaBucket' was added which stores key that house meta-data related to the current/version state of the database. 'createChannelDB' was modified to create this new bucket+key during initializing. Also backup logic was added which makes a complete copy of the current database during migration process and restore the previous version of database if migration failed.
This commit is contained in:
committed by
Olaoluwa Osuntokun
parent
2bf5794645
commit
c53ea091dd
90
channeldb/meta.go
Normal file
90
channeldb/meta.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package channeldb
|
||||
|
||||
import (
|
||||
"github.com/boltdb/bolt"
|
||||
)
|
||||
|
||||
var (
|
||||
// metaBucket stores all the meta information concerning the state of
|
||||
// the database.
|
||||
metaBucket = []byte("metadata")
|
||||
|
||||
// dbVersionKey is a boltdb key and it's used for storing/retrieveing
|
||||
// current database version.
|
||||
dbVersionKey = []byte("dbp")
|
||||
)
|
||||
|
||||
// Meta structure holds the database meta information.
|
||||
type Meta struct {
|
||||
dbVersionNumber uint32
|
||||
}
|
||||
|
||||
// FetchMeta fetches the meta data from boltdb and returns filled meta
|
||||
// structure. If transaction object is specified then it will be used rather
|
||||
// than initiation creation of new one.
|
||||
func (d *DB) FetchMeta(tx *bolt.Tx) (*Meta, error) {
|
||||
meta := &Meta{}
|
||||
fetchMeta := func(tx *bolt.Tx) error {
|
||||
if metaBucket := tx.Bucket(metaBucket); metaBucket != nil {
|
||||
fetchDbVersion(metaBucket, meta)
|
||||
return nil
|
||||
} else {
|
||||
return ErrMetaNotFound
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
if tx == nil {
|
||||
err = d.store.View(fetchMeta)
|
||||
} else {
|
||||
err = fetchMeta(tx)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return meta, nil
|
||||
}
|
||||
|
||||
// PutMeta gets as input meta structure and put it into boltdb. If transaction
|
||||
// object is specified then it will be used rather than initiation creation of
|
||||
// new one.
|
||||
func (d *DB) PutMeta(meta *Meta, tx *bolt.Tx) error {
|
||||
putMeta := func(tx *bolt.Tx) error {
|
||||
metaBucket := tx.Bucket(metaBucket)
|
||||
if metaBucket == nil {
|
||||
return ErrMetaNotFound
|
||||
}
|
||||
|
||||
if err := putDbVersion(metaBucket, meta); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
if tx == nil {
|
||||
return d.store.Update(putMeta)
|
||||
} else {
|
||||
return putMeta(tx)
|
||||
}
|
||||
}
|
||||
|
||||
func putDbVersion(metaBucket *bolt.Bucket, meta *Meta) error {
|
||||
scratch := make([]byte, 4)
|
||||
byteOrder.PutUint32(scratch, meta.dbVersionNumber)
|
||||
if err := metaBucket.Put(dbVersionKey, scratch); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func fetchDbVersion(metaBucket *bolt.Bucket, meta *Meta) {
|
||||
if data := metaBucket.Get(dbVersionKey); data != nil {
|
||||
meta.dbVersionNumber = byteOrder.Uint32(data)
|
||||
} else {
|
||||
meta.dbVersionNumber = getLatestDBVersion(DBVersions)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user