From d43e31c7edbbeab2aa452d5efc97fa03e60a6443 Mon Sep 17 00:00:00 2001
From: LFC <990479+MichaelScofield@users.noreply.github.com>
Date: Wed, 4 Sep 2024 18:10:07 +0800
Subject: [PATCH] feat: schedule compaction when adding sst files by editing
region (#4648)
* feat: schedule compaction when adding sst files by editing region
* add minimum time interval for two successive compactions
* resolve PR comments
---
config/config.md | 2 +
config/datanode.example.toml | 4 ++
config/standalone.example.toml | 4 ++
src/mito2/src/compaction.rs | 8 ++-
src/mito2/src/config.rs | 6 ++
src/mito2/src/engine/edit_region_test.rs | 88 ++++++++++++++++++++++-
src/mito2/src/engine/flush_test.rs | 6 +-
src/mito2/src/engine/listener.rs | 3 +
src/mito2/src/region.rs | 13 ++++
src/mito2/src/region/opener.rs | 28 ++++----
src/mito2/src/worker.rs | 7 ++
src/mito2/src/worker/handle_catchup.rs | 1 +
src/mito2/src/worker/handle_compaction.rs | 34 ++++++++-
src/mito2/src/worker/handle_create.rs | 1 +
src/mito2/src/worker/handle_flush.rs | 21 +-----
src/mito2/src/worker/handle_manifest.rs | 7 ++
src/mito2/src/worker/handle_open.rs | 1 +
tests-integration/tests/http.rs | 1 +
18 files changed, 193 insertions(+), 42 deletions(-)
diff --git a/config/config.md b/config/config.md
index 83bc85612c..f0ee9e54f8 100644
--- a/config/config.md
+++ b/config/config.md
@@ -129,6 +129,7 @@
| `region_engine.mito.scan_parallelism` | Integer | `0` | Parallelism to scan a region (default: 1/4 of cpu cores). - `0`: using the default value (1/4 of cpu cores). - `1`: scan in current thread. - `n`: scan in parallelism n. |
| `region_engine.mito.parallel_scan_channel_size` | Integer | `32` | Capacity of the channel to send data from parallel scan tasks to the main task. |
| `region_engine.mito.allow_stale_entries` | Bool | `false` | Whether to allow stale WAL entries read during replay. |
+| `region_engine.mito.min_compaction_interval` | String | `0m` | Minimum time interval between two compactions. To align with the old behavior, the default value is 0 (no restrictions). |
| `region_engine.mito.index` | -- | -- | The options for index in Mito engine. |
| `region_engine.mito.index.aux_path` | String | `""` | Auxiliary directory path for the index in filesystem, used to store intermediate files for creating the index and staging files for searching the index, defaults to `{data_home}/index_intermediate`. The default name for this directory is `index_intermediate` for backward compatibility.
This path contains two subdirectories: - `__intm`: for storing intermediate files used during creating index. - `staging`: for storing staging files used during searching index. |
| `region_engine.mito.index.staging_size` | String | `2GB` | The max capacity of the staging directory. |
@@ -431,6 +432,7 @@
| `region_engine.mito.scan_parallelism` | Integer | `0` | Parallelism to scan a region (default: 1/4 of cpu cores). - `0`: using the default value (1/4 of cpu cores). - `1`: scan in current thread. - `n`: scan in parallelism n. |
| `region_engine.mito.parallel_scan_channel_size` | Integer | `32` | Capacity of the channel to send data from parallel scan tasks to the main task. |
| `region_engine.mito.allow_stale_entries` | Bool | `false` | Whether to allow stale WAL entries read during replay. |
+| `region_engine.mito.min_compaction_interval` | String | `0m` | Minimum time interval between two compactions. To align with the old behavior, the default value is 0 (no restrictions). |
| `region_engine.mito.index` | -- | -- | The options for index in Mito engine. |
| `region_engine.mito.index.aux_path` | String | `""` | Auxiliary directory path for the index in filesystem, used to store intermediate files for creating the index and staging files for searching the index, defaults to `{data_home}/index_intermediate`. The default name for this directory is `index_intermediate` for backward compatibility.
This path contains two subdirectories: - `__intm`: for storing intermediate files used during creating index. - `staging`: for storing staging files used during searching index. |
| `region_engine.mito.index.staging_size` | String | `2GB` | The max capacity of the staging directory. |
diff --git a/config/datanode.example.toml b/config/datanode.example.toml
index 8b55d6e533..07c1df3e2a 100644
--- a/config/datanode.example.toml
+++ b/config/datanode.example.toml
@@ -455,6 +455,10 @@ parallel_scan_channel_size = 32
## Whether to allow stale WAL entries read during replay.
allow_stale_entries = false
+## Minimum time interval between two compactions.
+## To align with the old behavior, the default value is 0 (no restrictions).
+min_compaction_interval = "0m"
+
## The options for index in Mito engine.
[region_engine.mito.index]
diff --git a/config/standalone.example.toml b/config/standalone.example.toml
index b065e1a09d..f36c0e2904 100644
--- a/config/standalone.example.toml
+++ b/config/standalone.example.toml
@@ -493,6 +493,10 @@ parallel_scan_channel_size = 32
## Whether to allow stale WAL entries read during replay.
allow_stale_entries = false
+## Minimum time interval between two compactions.
+## To align with the old behavior, the default value is 0 (no restrictions).
+min_compaction_interval = "0m"
+
## The options for index in Mito engine.
[region_engine.mito.index]
diff --git a/src/mito2/src/compaction.rs b/src/mito2/src/compaction.rs
index 9ee2252f2d..0f33471b21 100644
--- a/src/mito2/src/compaction.rs
+++ b/src/mito2/src/compaction.rs
@@ -160,8 +160,12 @@ impl CompactionScheduler {
self.listener.clone(),
);
self.region_status.insert(region_id, status);
- self.schedule_compaction_request(request, compact_options)
- .await
+ let result = self
+ .schedule_compaction_request(request, compact_options)
+ .await;
+
+ self.listener.on_compaction_scheduled(region_id);
+ result
}
/// Notifies the scheduler that the compaction job is finished successfully.
diff --git a/src/mito2/src/config.rs b/src/mito2/src/config.rs
index 7af36ab896..bbdff81ff6 100644
--- a/src/mito2/src/config.rs
+++ b/src/mito2/src/config.rs
@@ -122,6 +122,11 @@ pub struct MitoConfig {
/// Memtable config
pub memtable: MemtableConfig,
+
+ /// Minimum time interval between two compactions.
+ /// To align with the old behavior, the default value is 0 (no restrictions).
+ #[serde(with = "humantime_serde")]
+ pub min_compaction_interval: Duration,
}
impl Default for MitoConfig {
@@ -152,6 +157,7 @@ impl Default for MitoConfig {
inverted_index: InvertedIndexConfig::default(),
fulltext_index: FulltextIndexConfig::default(),
memtable: MemtableConfig::default(),
+ min_compaction_interval: Duration::from_secs(0),
};
// Adjust buffer and cache size according to system memory if we can.
diff --git a/src/mito2/src/engine/edit_region_test.rs b/src/mito2/src/engine/edit_region_test.rs
index b13691fb85..51f2a976b3 100644
--- a/src/mito2/src/engine/edit_region_test.rs
+++ b/src/mito2/src/engine/edit_region_test.rs
@@ -15,6 +15,7 @@
use std::sync::{Arc, Mutex};
use std::time::Duration;
+use common_time::util::current_time_millis;
use object_store::ObjectStore;
use store_api::region_engine::RegionEngine;
use store_api::region_request::RegionRequest;
@@ -22,6 +23,7 @@ use store_api::storage::RegionId;
use tokio::sync::{oneshot, Barrier};
use crate::config::MitoConfig;
+use crate::engine::flush_test::MockTimeProvider;
use crate::engine::listener::EventListener;
use crate::engine::MitoEngine;
use crate::manifest::action::RegionEdit;
@@ -29,6 +31,84 @@ use crate::region::MitoRegionRef;
use crate::sst::file::{FileId, FileMeta};
use crate::test_util::{CreateRequestBuilder, TestEnv};
+#[tokio::test]
+async fn test_edit_region_schedule_compaction() {
+ let mut env = TestEnv::new();
+
+ struct EditRegionListener {
+ tx: Mutex