-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Description
Bug Report
similar with #18403, if there are lots pending tasks in cleanup_worker and lots regions need to be compacted,
TiKV may find there are some large regions that can not be split,
that is, all the mvcc versions accumulated in these regions are all belongs to a same row, in this case, TiKV will init a Task::Compact task to the cleanup_worker
tikv/components/raftstore/src/store/peer.rs
Lines 4562 to 4588 in 0a97ca8
| .map_err(|e| { | |
| // If the error of prepropose contains str `NO_VALID_SPLIT_KEY`, it may mean the | |
| // split_key of the split request is the region start key which | |
| // means we may have so many potential duplicate mvcc versions | |
| // that we can not manage to get a valid split key. So, we | |
| // trigger a compaction to handle it. | |
| if e.to_string().contains(NO_VALID_SPLIT_KEY) { | |
| let safe_ts = (|| { | |
| fail::fail_point!("safe_point_inject", |t| { | |
| t.unwrap().parse::<u64>().unwrap() | |
| }); | |
| poll_ctx.safe_point.load(Ordering::Relaxed) | |
| })(); | |
| if safe_ts <= self.last_record_safe_point { | |
| debug!( | |
| "skip schedule compact range due to safe_point not updated"; | |
| "region_id" => self.region_id, | |
| "safe_point" => safe_ts, | |
| ); | |
| return e; | |
| } | |
| let start_key = enc_start_key(self.region()); | |
| let end_key = enc_end_key(self.region()); | |
| let mut all_scheduled = true; | |
| for cf in [CF_WRITE, CF_DEFAULT] { |
and for cleanup_worker, if it is busy processing pending tasks, the duplicated Task::Compact maybe send to cleanup_worker again and again(interval 10s) until the first Task::Compact finished and clear the redundant old mvcc versions.
Mar 21, 2025 @ 08:03:14.277 | tikv | error | [split_observer.rs:148] ["failed to handle split req"] [err="\"no valid key found for split.\""] [region_id=157887931] [thread_id=106]
Mar 21, 2025 @ 08:03:24.268 | tikv | error | [split_observer.rs:148] ["failed to handle split req"] [err="\"no valid key found for split.\""] [region_id=157887931] [thread_id=106]
Mar 21, 2025 @ 08:03:34.277 [split_observer.rs:148] ["failed to handle split req"] [err="\"no valid key found for split.\""] [region_id=157887931] [thread_id=105]
At this time, these duplicate Task::Compact will still be in the pending tasks of cleanup_worker, and when it is its turn, because we do not check the redundant mvccs here, we directly send the manual compact task to rocksdb.
tikv/components/raftstore/src/store/worker/compact.rs
Lines 380 to 409 in 0a97ca8
| Task::Compact { | |
| cf_name, | |
| start_key, | |
| end_key, | |
| bottommost_level_force, | |
| } => { | |
| let cf = &cf_name; | |
| if cf != CF_LOCK { | |
| // check whether the config changed for ignoring manual compaction | |
| if let Some(incoming) = self.cfg_tracker.any_new() { | |
| self.skip_compact = incoming.skip_manual_compaction_in_clean_up_worker; | |
| } | |
| if self.skip_compact { | |
| info!( | |
| "skip compact range"; | |
| "range_start" => start_key.as_ref().map(|k| log_wrappers::Value::key(k)), | |
| "range_end" => end_key.as_ref().map(|k|log_wrappers::Value::key(k)), | |
| "cf" => cf_name, | |
| ); | |
| return; | |
| } | |
| } | |
| if let Err(e) = self.compact_range_cf( | |
| cf, | |
| start_key.as_deref(), | |
| end_key.as_deref(), | |
| bottommost_level_force, | |
| ) { | |
| error!("execute compact range failed"; "cf" => cf, "err" => %e); | |
| } |
However, in fact, the duplicate manual::compact task can no longer do anything at this time, but it will take up the time of the cleanup-worker to handle and wait the compaction job finished, thereby blocking the execution of the other tasks that do need compaction.
What version of TiKV are you using?
master
Steps to reproduce
A big cluster and enable TTL, meanwhile, update some keys frequently
What did you expect?
big region that belongs to one row could be compaction in time