-
Notifications
You must be signed in to change notification settings - Fork 117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Migrate from boltdb to sql #585
Conversation
0322c84
to
0c26796
Compare
79160c1
to
1bb62b7
Compare
0247b6e
to
cfc3c0c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cACK, not super expert in db migrations
will do another review run soon so I can also provide a tACK
@@ -192,13 +192,13 @@ func NewClient(dbDir string, cfg *ClientConfig) (*Client, func(), error) { | |||
} | |||
|
|||
// FetchSwaps returns all loop in and out swaps currently in the database. | |||
func (s *Client) FetchSwaps() ([]*SwapInfo, error) { | |||
loopOutSwaps, err := s.Store.FetchLoopOutSwaps() | |||
func (s *Client) FetchSwaps(ctx context.Context) ([]*SwapInfo, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
weird that we didn't have a ctx before. Isn't it like a rule-of-thumb to have a context with timeout when dispatching db calls?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for adding timeout, perhaps something large like 30s would be a good start.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bhandras do you mean on every call to add a timeout to the context?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I mean is that we could perhaps wrap the ctx
to a timeout context (per call to the store), to avoid hanging if the DB is for any reason unresponsive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure, but think the sql driver handles that? There are some timeout settings we pass in sqlite for example
|
||
// If the migration was successfull we'll rename the bolt db to | ||
// loop.db.bk. | ||
err = os.Rename( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is keeping the backup what usually happens with migrations?
what if db was super big and keeping a duplicate causes problems?
(e.g a user with many swaps)
is the following a possible scenario:
- user upgrades & triggers migration
- migration completes but now they suddenly reached 99% storage capacity
- service outage
or what if migration fails without completing, possibly exhausting all of storage space?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. My rationale is to have a backup in case something goes wrong. IMO that's important for client side migration. Users can then delete their database on their own.
Should the user run out of space the migration would fail on the migration step before and loopd wouldn't start and the db wouldn't rename, so a user could expand their db. There would be no fallback just an exit from loopd.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @sputn1ck, it's important to keep the old DB around. It's also likely not large enough to cause any issues regarding storage space and if it is, then the migration above will already fail since this is just a rename.
loopdb/migrate.go
Outdated
|
||
// For each loop out, create a new loop out in the toStore. | ||
for _, loopOut := range loopOuts { | ||
err := m.toStore.CreateLoopOut(ctx, loopOut.Hash, loopOut.Contract) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order to speed this up, we want to be able to batch all the insertion here. Otherwise, you're doing a single db transaction for each swap. Instead a series of swaps can be created, within a single DB transaction.
fe55f1c
to
148e9e4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome work! First pass looks really good already! Very close 🚀
@@ -28,10 +31,11 @@ require ( | |||
github.com/stretchr/testify v1.8.1 | |||
github.com/urfave/cli v1.22.9 | |||
golang.org/x/net v0.7.0 | |||
google.golang.org/grpc v1.41.0 | |||
google.golang.org/grpc v1.45.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The bump is because of golang-migrate
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm actually not sure where the bump comes from.
@@ -192,13 +192,13 @@ func NewClient(dbDir string, cfg *ClientConfig) (*Client, func(), error) { | |||
} | |||
|
|||
// FetchSwaps returns all loop in and out swaps currently in the database. | |||
func (s *Client) FetchSwaps() ([]*SwapInfo, error) { | |||
loopOutSwaps, err := s.Store.FetchLoopOutSwaps() | |||
func (s *Client) FetchSwaps(ctx context.Context) ([]*SwapInfo, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for adding timeout, perhaps something large like 30s would be a good start.
@sputn1ck, remember to re-request review from reviewers when ready |
This commit adds a context to our loopdb interface, which we should use in the sqlite migration.
This commit adds a batch insert to the interface. This greatly reduces the time the migration will take. It is not implemented for the boltdb, as we will not be supporting migrating to the boltdb.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tACK, LGTM! Excellent work @sputn1ck 🎉 🎉 🎉
Please don't forget to update the release notes as well.
) | ||
|
||
// migrateBoltdb migrates the boltdb to sqlite. | ||
func migrateBoltdb(ctx context.Context, cfg *Config) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps as a separate PR we can also add the option to migrate sqlite to postgres. Not needed now since there're no users yet on sqlite.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes I thought about that as well, shouldn't be too much extra work
This commit adds a nil check to the boltdb liquidity test. There was a difference between the sqlite and boltdb implementation. This test covers that.
This commit adds a postgres store to the loopdb package. Ths postgres migrator uses a replacer filesystem to replace the sqlite types to postgres types in the migration.
This commit adds a migrator to the loopdb package that manages migrating between 2 databases
This commit adds the ability to choose between different sql stores for loopd. The default is sqlite, but it can be changed to postgres.
This PR adds the migration from boltdb to a local sqlite db or a postgres db. This will make it easier for future improvements such as taproots assets and other protocol changes.
Currently the migration is only done once from boltdb to the specified sql store. We should add a migrate command to loop which will allow the migration from sqlite to postgres and back.
TODO