feat: support request-level insert WAL skipping (#9088)

* refactor: add skip_wal fields to internal write requests

Signed-off-by: WenyXu <wenymedia@gmail.com>

* chore(deps): update greptime-proto for insert skip_wal

Signed-off-by: WenyXu <wenymedia@gmail.com>

* feat(mito): support request-level WAL skipping

Signed-off-by: WenyXu <wenymedia@gmail.com>

* feat(metric-engine): handle request-level WAL policies

Signed-off-by: WenyXu <wenymedia@gmail.com>

* feat: propagate insert WAL policy through query context

Signed-off-by: WenyXu <wenymedia@gmail.com>

* feat: support session-level insert WAL policy via SET

Signed-off-by: WenyXu <wenymedia@gmail.com>

* fix(metric-engine): require uniform WAL policy in batch puts

Signed-off-by: WenyXu <wenymedia@gmail.com>

* test(metric-engine): simplify WAL policy coverage

Signed-off-by: WenyXu <wenymedia@gmail.com>

* refactor(servers): simplify gRPC hint extraction

Signed-off-by: WenyXu <wenymedia@gmail.com>

* test: flatten Mito and Metric WAL scenario orchestration

Signed-off-by: WenyXu <wenymedia@gmail.com>

* refactor: separate WAL and memtable-only mutations

Signed-off-by: WenyXu <wenymedia@gmail.com>

* refactor: carry skip-WAL policy in table insert requests

Signed-off-by: WenyXu <wenymedia@gmail.com>

* test: flatten skip-WAL policy cases

Signed-off-by: WenyXu <wenymedia@gmail.com>

* refactor: clarify WAL notifier naming

Signed-off-by: WenyXu <wenymedia@gmail.com>

* chore: pin merged skip-WAL proto revision

Signed-off-by: WenyXu <wenymedia@gmail.com>

---------

Signed-off-by: WenyXu <wenymedia@gmail.com>
This commit is contained in:
Weny Xu
2026-09-10 11:40:51 +00:00
committed by GitHub
parent 536f42e4a2
commit fa128adb8e
46 changed files with 1750 additions and 98 deletions
+49
View File
@@ -153,6 +153,15 @@ impl QueryContextBuilder {
self
}
pub fn skip_wal(mut self, skip_wal: bool) -> Self {
self.mutable_session_data
.get_or_insert_default()
.write()
.unwrap()
.skip_wal = skip_wal;
self
}
pub fn read_preference(mut self, read_preference: ReadPreference) -> Self {
self.mutable_session_data
.get_or_insert_default()
@@ -348,6 +357,15 @@ impl QueryContext {
self.mutable_session_data.write().unwrap().timezone = timezone;
}
/// Returns whether ordinary inserts in this request should skip WAL.
pub fn skip_wal(&self) -> bool {
self.mutable_session_data.read().unwrap().skip_wal
}
pub fn set_skip_wal(&self, skip_wal: bool) {
self.mutable_session_data.write().unwrap().skip_wal = skip_wal;
}
pub fn read_preference(&self) -> ReadPreference {
self.mutable_session_data.read().unwrap().read_preference
}
@@ -739,6 +757,37 @@ mod test {
assert_eq!(fork.current_schema(), "private");
}
#[test]
fn test_skip_wal_default_builder_and_fork() {
let default_context = QueryContext::with(DEFAULT_CATALOG_NAME, "public");
assert!(!default_context.skip_wal());
assert!(!QueryContextBuilder::default().build().skip_wal());
let context = QueryContextBuilder::default().skip_wal(true).build();
assert!(context.skip_wal());
let fork = context.fork();
assert!(fork.skip_wal());
fork.set_skip_wal(false);
assert!(context.skip_wal());
assert!(!fork.skip_wal());
context.set_skip_wal(false);
fork.set_skip_wal(true);
assert!(!context.skip_wal());
assert!(fork.skip_wal());
}
#[test]
fn test_skip_wal_is_not_serialized_in_query_context() {
let context = QueryContextBuilder::default().skip_wal(true).build();
let api_context: api::v1::QueryContext = context.into();
assert!(
!api_context
.extensions
.contains_key(crate::hints::INSERT_SKIP_WAL_HINT)
);
let restored: QueryContext = api_context.into();
assert!(!restored.skip_wal());
}
#[test]
fn test_api_query_context_roundtrip_with_sequences() {
let api_ctx = api::v1::QueryContext {
+3
View File
@@ -23,6 +23,9 @@ pub const SUPPORT_FLIGHT_METRICS_BEFORE_BATCH_EXTENSION_KEY: &str =
"query.support_flight_metrics_before_batch";
pub const LIVE_ANALYZE_METRICS_EXTENSION_KEY: &str = "query.live_analyze_metrics";
/// Skip WAL for this insert only; never persisted as a table option.
pub const INSERT_SKIP_WAL_HINT: &str = "insert_skip_wal";
pub const READ_PREFERENCE_HINT: &str = "read_preference";
pub const RESERVED_EXTENSION_KEYS: [&str; 4] = [
REMOTE_QUERY_ID_EXTENSION_KEY,
+3
View File
@@ -60,6 +60,8 @@ pub(crate) struct MutableInner {
timezone: Timezone,
query_timeout: Option<Duration>,
read_preference: ReadPreference,
/// Request-level WAL policy for ordinary inserts.
skip_wal: bool,
#[debug(skip)]
pub(crate) cursors: HashMap<String, Arc<RecordBatchStreamCursor>>,
/// Warning messages for MySQL SHOW WARNINGS support
@@ -74,6 +76,7 @@ impl Default for MutableInner {
timezone: get_timezone(None).clone(),
query_timeout: None,
read_preference: ReadPreference::Leader,
skip_wal: false,
cursors: HashMap::with_capacity(0),
warnings: VecDeque::new(),
}