-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Store the database in a role specific subdirectory #8658
Conversation
If there is already a database in the basedir, it will be migrated (moved) into the role-subdirectory. fixes paritytech#6880
There's one issue when the client is started in a different role then the database (before migration to the subdirectory), the db gets moved to the subdirectory of the client, not the db. And opening the database later will fail. Unfortunately there's no stable way of finding out the DatabaseType in the client before it is opened. But the migration of the database to the subdir must be in this early phase, as the later code must not depend or know any special paths or directory layouts. I tried to implement a |
Ready for review. |
We better rely on directory names for migration-detection
Hey, is anyone still working on this? Due to the inactivity this issue has been automatically marked as stale. It will be closed if no further activity occurs. Thank you for your contributions. |
This issue just needs a review. |
@@ -65,3 +65,39 @@ pub fn run_dev_node_for_a_while(base_path: &Path) { | |||
kill(Pid::from_raw(cmd.id().try_into().unwrap()), SIGINT).unwrap(); | |||
assert!(wait_for(&mut cmd, 40).map(|x| x.success()).unwrap_or_default()); | |||
} | |||
|
|||
/// Run the node for a while (30 seconds) | |||
pub fn run_node_with_args_for_a_while(base_path: &Path, args: &[&str]) { |
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.
run_dev_node_for_a_while
could be implemented in terms of run_node_with_args_for_a_while
now
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.
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.
Or the caller can just pass &[--dev]
as args to run_node_with_args_for_a_while
}) | ||
}; | ||
|
||
if let Some(p) = db_conf.path() { |
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.
It looks like the following migration code belongs in sc-client
or sc-client-db
. Right before opening the database. Cli should not be concerned with database migration. It would also remove the dependency on sc-client-db
.
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.
Sure, this was the first thing I tried, but I actually struggled at this problem a bit, because the migration code needs to know the Role
in which the client was started and the DatabaseType
to be sure not to move the db to the wrong directory.
When I tried to inject the Role
from the Cli to the client I had a hard time with the compiler. That's why I chose it the other way around. But maybe moving the Role
enum to sc-client would work.
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.
Role is passed down as db_type
here
substrate/client/db/src/utils.rs
Line 208 in 1d5abf0
pub fn open_database<Block: BlockT>( |
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.
Not really, there's two distinct (and overlapping) terms.
There's Role
from https://github.com/paritytech/substrate/blob/master/client/network/src/config.rs#L148
and DatabaseType
from https://github.com/paritytech/substrate/blob/master/client/db/src/utils.rs#L91
Role is coming from the cli as parameter and DatabaseType is determined from the database.
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.
As far as understand, db_type
that's passed to open_database
is derived from the CLI argument. The CLI argument selects type of backend to use. Light backend opens the database as light here: https://github.com/paritytech/substrate/blob/master/client/db/src/light.rs#L76
And full backend opens it as full here: https://github.com/paritytech/substrate/blob/master/client/db/src/lib.rs#L1082
open_database
does indeed check that expected db_type
matches the one in the database. But you can still use expected db_type
in the same way you use role w.r.t. migration.
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.
But the check for the correct database happens after the migration was applied and the database was opened, so on a mismatch I have to roll back the directories and 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.
If you check the database type before migration there should be no mismatch.
I'm suggesting moving your migration code inside the open_database
function.
Basically move all of the code from open_database
to a helper function, e.g. open_database_at
So that the new version of open_database
would do something like this:
- Check the base path for an existing database. Try to open it with
open_database_at
, which will validate expected db_type. If it succeeds, close the database and do the migration. - Append "full" or "light" to base path. Open it with
open_database_at
and return
A bit of refactoring might be required to extract the meat of open_database
to a helper function that does the heavy lifting of actually opening the database.
} | ||
|
||
if crate::utils::open_database::<Block>(&config, DatabaseType::Light).is_ok() { | ||
return Ok(DatabaseType::Light); |
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.
This method of detecting database type is a bit hacky. It relies on the fact that the databases have different number of columns. Also unlike rocksdb, paritydb does not care if you don't open all of the columns. So it is important to try for full database first, before trying as light. Could you please add a comment to that extend?
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.
Skimming through code I just read that open_database also call
substrate/client/db/src/utils.rs
Line 290 in b7409a2
pub fn check_database_type( |
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.
Right, there's already a method for it
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.
This was the best way I could find to differentiate them, will add a comment for full disclosure.
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.
If you move migration code to sc-client-db
you can just use utils::check_database_type
instead.
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.
On the other hand utils::check_database_type
requires the database to be open already, which in turn requires specifying a DatabaseType
. So I guess the current approach is fine after all.
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 remember, that was the problem.
Thanks for the PR an apologies for the late review. Totally agree that the databases should be separated. |
There had been some refactorings in master since this PR was created, so I had to rework some stuff. I'm nearly finished but it still needs some tweaks on the tests. I'm in holiday for three weeks now but I'll create a new PR based on master when I'm back. Cu... |
This is a cleaned up version of paritytech#8658 fixing paritytech#6880 polkadot companion: paritytech/polkadot#2923
Back from honeymoon, I created a new PR #9645 based on current master. |
* Store the database in a role specific subdirectory This is a cleaned up version of #8658 fixing #6880 polkadot companion: paritytech/polkadot#2923 * Disable prometheus in tests * Also change p2p port * Fix migration logic * Use different identification file for rocks and parity db Add tests for paritydb migration
If there is already a database in the basedir, it will be migrated
(moved) into the role-subdirectory.
fixes #6880
polkadot companion: paritytech/polkadot#2923
TODO: