channeldb: add NoMigration mode

In case the channeldb package is used as a library in external tools, it
can be useful to allow read-only access to a DB. This allows such a
tool to access a DB even if not all migrations were executed, which can
be useful for recovery purposes.
To make it possible to even start the DB with a read-only backend, we
need to disable the automatic migration step.
This commit is contained in:
Oliver Gugger
2021-12-13 10:53:58 +01:00
parent a8f75e0221
commit b147d589c1
5 changed files with 33 additions and 13 deletions

View File

@@ -263,15 +263,17 @@ func Open(dbPath string, modifiers ...OptionModifier) (*DB, error) {
// CreateWithBackend creates channeldb instance using the passed kvdb.Backend.
// Any necessary schemas migrations due to updates will take place as necessary.
func CreateWithBackend(backend kvdb.Backend, modifiers ...OptionModifier) (*DB, error) {
if err := initChannelDB(backend); err != nil {
return nil, err
}
opts := DefaultOptions()
for _, modifier := range modifiers {
modifier(&opts)
}
if !opts.NoMigration {
if err := initChannelDB(backend); err != nil {
return nil, err
}
}
chanDB := &DB{
Backend: backend,
channelStateDB: &ChannelStateDB{
@@ -291,16 +293,18 @@ func CreateWithBackend(backend kvdb.Backend, modifiers ...OptionModifier) (*DB,
chanDB.graph, err = NewChannelGraph(
backend, opts.RejectCacheSize, opts.ChannelCacheSize,
opts.BatchCommitInterval, opts.PreAllocCacheNumNodes,
opts.UseGraphCache,
opts.UseGraphCache, opts.NoMigration,
)
if err != nil {
return nil, err
}
// Synchronize the version of database and apply migrations if needed.
if err := chanDB.syncVersions(dbVersions); err != nil {
backend.Close()
return nil, err
if !opts.NoMigration {
if err := chanDB.syncVersions(dbVersions); err != nil {
backend.Close()
return nil, err
}
}
return chanDB, nil

View File

@@ -189,10 +189,12 @@ type ChannelGraph struct {
// returned instance has its own unique reject cache and channel cache.
func NewChannelGraph(db kvdb.Backend, rejectCacheSize, chanCacheSize int,
batchCommitInterval time.Duration, preAllocCacheNumNodes int,
useGraphCache bool) (*ChannelGraph, error) {
useGraphCache, noMigrations bool) (*ChannelGraph, error) {
if err := initChannelGraph(db); err != nil {
return nil, err
if !noMigrations {
if err := initChannelGraph(db); err != nil {
return nil, err
}
}
g := &ChannelGraph{

View File

@@ -77,7 +77,7 @@ func MakeTestGraph(modifiers ...OptionModifier) (*ChannelGraph, func(), error) {
graph, err := NewChannelGraph(
backend, opts.RejectCacheSize, opts.ChannelCacheSize,
opts.BatchCommitInterval, opts.PreAllocCacheNumNodes,
true,
true, false,
)
if err != nil {
backendCleanup()

View File

@@ -50,6 +50,11 @@ type Options struct {
// path finding.
UseGraphCache bool
// NoMigration specifies that underlying backend was opened in read-only
// mode and migrations shouldn't be performed. This can be useful for
// applications that use the channeldb package as a library.
NoMigration bool
// clock is the time source used by the database.
clock clock.Clock
@@ -71,6 +76,7 @@ func DefaultOptions() Options {
ChannelCacheSize: DefaultChannelCacheSize,
PreAllocCacheNumNodes: DefaultPreAllocCacheNumNodes,
UseGraphCache: true,
NoMigration: false,
clock: clock.NewDefaultClock(),
}
}
@@ -136,6 +142,14 @@ func OptionSetBatchCommitInterval(interval time.Duration) OptionModifier {
}
}
// OptionNoMigration allows the database to be opened in read only mode by
// disabling migrations.
func OptionNoMigration(b bool) OptionModifier {
return func(o *Options) {
o.NoMigration = b
}
}
// OptionClock sets a non-default clock dependency.
func OptionClock(clock clock.Clock) OptionModifier {
return func(o *Options) {

View File

@@ -175,7 +175,7 @@ func makeTestGraph(useCache bool) (*channeldb.ChannelGraph, kvdb.Backend,
graph, err := channeldb.NewChannelGraph(
backend, opts.RejectCacheSize, opts.ChannelCacheSize,
opts.BatchCommitInterval, opts.PreAllocCacheNumNodes,
useCache,
useCache, false,
)
if err != nil {
cleanUp()