-
Notifications
You must be signed in to change notification settings - Fork 628
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
[reshardingV3] State ShardUIdMapping - initial implementation #12084
Conversation
There is
and it might not be possible to scan child shard only. |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #12084 +/- ##
=======================================
Coverage 71.69% 71.70%
=======================================
Files 825 825
Lines 165834 165850 +16
Branches 165834 165850 +16
=======================================
+ Hits 118902 118921 +19
+ Misses 41751 41745 -6
- Partials 5181 5184 +3
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
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.
Looks good, I left a few comments!
7d1841c
to
85574b2
Compare
8a4ffea
to
be91b49
Compare
@@ -337,6 +397,7 @@ impl Store { | |||
} | |||
|
|||
pub fn iter_prefix<'a>(&'a self, col: DBCol, key_prefix: &'a [u8]) -> DBIterator<'a> { | |||
assert!(col != DBCol::State, "can't iter prefix of State column"); |
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.
Luckily, that is not currently used for State column
@@ -355,6 +418,7 @@ impl Store { | |||
col: DBCol, | |||
key_prefix: &'a [u8], | |||
) -> impl Iterator<Item = io::Result<(Box<[u8]>, T)>> + 'a { | |||
assert!(col != DBCol::State, "can't iter prefix ser of State column"); |
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.
Luckily, that is not currently used for State column
@@ -595,6 +658,7 @@ impl StoreUpdate { | |||
/// Deletes the given key range from the database including `from` | |||
/// and excluding `to` keys. | |||
pub fn delete_range(&mut self, column: DBCol, from: &[u8], to: &[u8]) { | |||
assert!(column != DBCol::State, "can't range delete State column"); |
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.
Luckily, that is not currently used for State column
@wacban @shreyan-gupta I will go offline in a moment. Feel free to merge / take it over, I can continue moving it forward in 10 days. |
eaf0e57
to
8fcc38a
Compare
8fcc38a
to
c8da0e9
Compare
c8da0e9
to
69ea15d
Compare
core/store/src/lib.rs
Outdated
fn get_impl_state(&self, key: &[u8]) -> io::Result<Option<DBSlice<'_>>> { | ||
let shard_uid = retrieve_shard_uid_from_db_key(key)?; | ||
let mapped_shard_uid = self | ||
.get_ser::<ShardUId>(DBCol::ShardUIdMapping, &shard_uid.to_bytes())? |
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.
Could we do the mapping in core/store/src/adapter/trie_store.rs ?
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.
Having TrieStoreAdapter
is now so nice :)
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.
looks good overall
Can you add some test where you:
write and read some data
set the mapping
write and read some data using the old shard uid
write and read some data using the new shard uid (and check that it was mapped)
@@ -186,6 +186,7 @@ fn copy_state_from_store( | |||
|
|||
let Some(trie_changes) = trie_changes else { continue }; | |||
for op in trie_changes.insertions() { | |||
// TODO(reshardingV3) Handle shard_uid not mapped there |
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 todo will be tricky, we will need to be careful when adding and removing a mapping. It's good that you spotted it.
unrelated to this PR:
I wonder if we can keep the original shard uids when moving data to cold storage. This would keep the cold storage sharded (as it is today).
core/store/src/columns.rs
Outdated
@@ -444,7 +450,8 @@ impl DBCol { | |||
| DBCol::StateChangesForSplitStates | |||
| DBCol::StateHeaders | |||
| DBCol::TransactionResultForBlock | |||
| DBCol::Transactions => true, | |||
| DBCol::Transactions | |||
| DBCol::ShardUIdMapping => true, |
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.
Can you explain how will the mapping work on split storage nodes? I can't say if this is good or not without the full picture. For early MVP it doesn't matter too much so feel free to just leave a TODO here and proceed.
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.
My understanding was we want to copy ShardUIdMapping
to cold storage because cold_store.get(state_key)
would not work otherwise. Marked it as TODO to understand it deeper after early MVP.
let mapped_shard_uid = self.read_shard_uid_mapping_from_db(shard_uid)?; | ||
let key = get_key_from_shard_uid_and_hash(mapped_shard_uid, hash); |
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.
nice
Ah I just saw your zulip post that the write path will be done separately, ignore my comment about testing it. Just have a look at my comments and fix the CI and we should be good to go. |
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.
LGTM, thanks!
The [previous PR](#12084) introduced mapping for read operations. This PR extends that functionality to write operations and adds some testing for State mapping. Following the [Zulip discussion](https://near.zulipchat.com/#narrow/stream/407288-core.2Fresharding/topic/State.20mapping/near/476959235), we decided to implement a panic inside the `TrieStoreUpdateAdapter` methods. Other strategies considered were: 1. Propagating the error instead of panicking: This was rejected because the error would need to be propagated through multiple layers that currently don't expect errors. Additionally, an error here would indicate a misconfiguration in the database, justifying the use of panic. 2. Performing the mapping later in `TrieStoreUpdateAdapter::commit()`: This would require iterating through all `DBOp`s, parsing each operation, extracting the `shard_uid` from the database key, mapping it, and re-encoding. This approach would make `TrieStoreUpdateAdapter` dependent on the internal workings of `DBTransaction`. Also, `StoreUpdate::merge()` makes me feel uneasy. --------- Co-authored-by: Waclaw Banasik <[email protected]>
Tracking issue: #12050
Summary
Currently the changes should be almost no-op, as we do not explicitly save anything to
DBCol::ShardUIdMapping
.The only difference is that we make an additional read from
DBCol::ShardUIdMapping
column every time we accessState
column.The main logic is in
Store::get_impl_state()
.These changes implement mapping for reads, writes will be handled in the next PR.
Changes:
DBCol::ShardUIdMapping
that is initially empty and will be populated on future resharding events.Store
to createStoreUpdate
.Store::get_impl_state()
- specialget()
implementation for the State column.Next steps (see tracking issue #12050):
copy_state_from_store
incold_storage.rs
.