-
Notifications
You must be signed in to change notification settings - Fork 598
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
feat(storage): Splitting table change log from HummockVersion on CN side #20050
base: main
Are you sure you want to change the base?
Conversation
…nto li0k/storage_divide_table_change_log
…nto li0k/storage_divide_table_change_log
guard: Arc::new(PinnedVersionGuard::new( | ||
version_id, | ||
self.guard.pinned_version_manager_tx.clone(), | ||
)), | ||
table_change_log: Arc::new(RwLock::new(t)), | ||
version: Arc::new(LocalHummockVersion::from(version)), |
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 just want to leave a note here.
This LocalHummockVersion::from
is an addtional HummockVersion
conversion introduced by this PR. However I don't think it will have significant performance implications, as it primarily involves move semantics.
let change_log = { | ||
let table_change_logs = version.table_change_log().read(); | ||
if let Some(change_log) = table_change_logs.get(&options.table_id) { | ||
change_log.filter_epoch(epoch_range).cloned().collect_vec() |
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 cloned() is an additional cost introduced in this PR.
If multiple iter_log are running simultaneously, will the memory usage be substantial?
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.
cc @wenym1 , suggests that iter_log
is executed less frequently and that this clone is acceptable.
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 current usage of iter_log
, we only do iter_log on a single epoch, so this vector should be small.
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
…nto li0k/storage_divide_table_change_log
…nto li0k/storage_divide_table_change_log
interfaces are affected:
cc @wenym1 |
…nto li0k/storage_divide_table_change_log
…nto li0k/storage_divide_table_change_log
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.
Rest LGTM. Thanks for the PR.
let change_log = { | ||
let table_change_logs = version.table_change_log().read(); | ||
if let Some(change_log) = table_change_logs.get(&options.table_id) { | ||
change_log.filter_epoch(epoch_range).cloned().collect_vec() |
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 current usage of iter_log
, we only do iter_log on a single epoch, so this vector should be small.
.build_sst_delta_infos(version_delta) | ||
.into_iter(), | ||
let mut version_to_apply = pinned_version.version().clone(); | ||
let table_change_log_to_apply = pinned_version.take_change_log(); |
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.
Instead of take_change_log
, we can have method change_log_write_lock
to return the write lock on the table_change_log
. And then in new_pin_version_with_table_change_log
, we don't have to pass the table_change_log_to_apply
again. We can use the original table_change_log
wrapped by Arc
and simply clone the Arc
.
Besides, it seems that the parameter pinned_version
of the current method is not necessary to take the ownership. We can change to pass &PinnedVersion
, so that the caller can avoid doing clone on it.
…nto li0k/storage_divide_table_change_log
…nto li0k/storage_divide_table_change_log
@@ -476,10 +473,26 @@ impl HummockVersion { | |||
state_table_info_delta: Default::default(), | |||
} | |||
} | |||
|
|||
pub fn split_change_log(mut self) -> (LocalHummockVersion, HashMap<TableId, TableChangeLog>) { | |||
let table_change_log = std::mem::take(&mut self.table_change_log); |
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.
Here after std::mem::take(&mut self.table_change_log)
, the epochs
in self.table_change_log
becomes empty. But we still need to use the epochs
in LocalHummockVersion
pub state_table_info: HummockVersionStateTableInfo, | ||
} | ||
|
||
pub type HummockVersion = HummockVersionCommon<SstableInfo>; | ||
pub type HummockVersion = HummockVersionCommon<SstableInfo, SstableInfo>; |
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.
pub type HummockVersion = HummockVersionCommon<SstableInfo, SstableInfo>; | |
pub type HummockVersion = HummockVersionCommon<SstableInfo>; |
pub state_table_info_delta: HashMap<TableId, StateTableInfoDelta>, | ||
} | ||
|
||
pub type HummockVersionDelta = HummockVersionDeltaCommon<SstableInfo>; | ||
pub type HummockVersionDelta = HummockVersionDeltaCommon<SstableInfo, SstableInfo>; |
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.
pub type HummockVersionDelta = HummockVersionDeltaCommon<SstableInfo, SstableInfo>; | |
pub type HummockVersionDelta = HummockVersionDeltaCommon<SstableInfo>; |
}) | ||
} | ||
|
||
pub fn new_with_change_log( |
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.
We can use self.table_change_log.clone()
instead of passing from outside.
let mut table_change_log_to_apply_guard = | ||
pinned_version.table_change_log_write_lock(); | ||
// let mut table_change_log_to_apply_guard = table_change_log_to_apply.write(); | ||
for version_delta in &version_deltas { |
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.
for version_delta in &version_deltas { | |
for version_delta in version_deltas { |
And then below we use do
let local_hummock_version_delta = LocalHummockVersionDelta::from(version_delta);
version_to_apply | ||
.build_sst_delta_infos(version_delta) | ||
.into_iter(), | ||
let mut version_to_apply = pinned_version.deref().clone(); |
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.
let mut version_to_apply = pinned_version.deref().clone(); | |
let mut version_to_apply = (**pinned_version).clone(); |
I hereby agree to the terms of the RisingWave Labs, Inc. Contributor License Agreement.
What's changed and what's your intention?
This PR optimize clone behavior on the CN side. Previously, the hummock event handler copied the hummock version every time it applied a delta, and the overhead of cloning could cause performance problems.issues.
risingwave/src/storage/src/hummock/event_handler/hummock_event_handler.rs
Line 529 in 95abcc9
This PR split the table change log from the hummock version to avoid copying all table change logs at each version delta.
Key changes include:
Enhancements to
HummockVersion
andHummockVersionDelta
:L
toHummockVersionCommon
andHummockVersionDeltaCommon
to improve type safety and flexibility. Split table_change_log into separate fields and protect them with RwLock. (src/storage/hummock_sdk/src/version.rs
,src/storage/hummock_sdk/src/compaction_group/hummock_version_ext.rs
)New Methods and Type Changes:
change_log_into_iter
method toTableChangeLogCommon
to allow iteration over change logs. (src/storage/hummock_sdk/src/change_log.rs
)Type Aliases:
HummockVersionCommon
andHummockVersionDeltaCommon
. (src/storage/hummock_sdk/src/time_travel.rs
,src/storage/hummock_sdk/src/version.rs
)Import Adjustments:
src/storage/hummock_sdk/src/compaction_group/hummock_version_ext.rs
,src/storage/hummock_sdk/src/version.rs
,src/storage/src/hummock/event_handler/hummock_event_handler.rs
)Checklist
Documentation
Release note