1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
use super::Result;
use crate::store::SplitCheckTask;
use configuration::{ConfigChange, ConfigManager, Configuration};
use engine_traits::{config as engine_config, PerfLevel};
use serde::{Deserialize, Serialize};
use tikv_util::box_err;
use tikv_util::config::ReadableSize;
use tikv_util::worker::Scheduler;
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Configuration)]
#[serde(default)]
#[serde(rename_all = "kebab-case")]
pub struct Config {
pub split_region_on_table: bool,
pub batch_split_limit: u64,
pub region_max_size: ReadableSize,
pub region_split_size: ReadableSize,
pub region_max_keys: u64,
pub region_split_keys: u64,
#[config(skip)]
pub consistency_check_method: ConsistencyCheckMethod,
#[serde(with = "engine_config::perf_level_serde")]
#[config(skip)]
pub perf_level: PerfLevel,
}
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum ConsistencyCheckMethod {
Raw = 0,
Mvcc = 1,
}
pub const SPLIT_SIZE_MB: u64 = 96;
pub const SPLIT_KEYS: u64 = 960000;
pub const BATCH_SPLIT_LIMIT: u64 = 10;
impl Default for Config {
fn default() -> Config {
let split_size = ReadableSize::mb(SPLIT_SIZE_MB);
Config {
split_region_on_table: false,
batch_split_limit: BATCH_SPLIT_LIMIT,
region_split_size: split_size,
region_max_size: split_size / 2 * 3,
region_split_keys: SPLIT_KEYS,
region_max_keys: SPLIT_KEYS / 2 * 3,
consistency_check_method: ConsistencyCheckMethod::Mvcc,
perf_level: PerfLevel::EnableCount,
}
}
}
impl Config {
pub fn validate(&self) -> Result<()> {
if self.region_max_size.0 < self.region_split_size.0 {
return Err(box_err!(
"region max size {} must >= split size {}",
self.region_max_size.0,
self.region_split_size.0
));
}
if self.region_max_keys < self.region_split_keys {
return Err(box_err!(
"region max keys {} must >= split keys {}",
self.region_max_keys,
self.region_split_keys
));
}
Ok(())
}
}
pub struct SplitCheckConfigManager(pub Scheduler<SplitCheckTask>);
impl ConfigManager for SplitCheckConfigManager {
fn dispatch(
&mut self,
change: ConfigChange,
) -> std::result::Result<(), Box<dyn std::error::Error>> {
self.0.schedule(SplitCheckTask::ChangeConfig(change))?;
Ok(())
}
}
impl std::ops::Deref for SplitCheckConfigManager {
type Target = Scheduler<SplitCheckTask>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_config_validate() {
let mut cfg = Config::default();
cfg.validate().unwrap();
cfg = Config::default();
cfg.region_max_size = ReadableSize(10);
cfg.region_split_size = ReadableSize(20);
assert!(cfg.validate().is_err());
cfg = Config::default();
cfg.region_max_keys = 10;
cfg.region_split_keys = 20;
assert!(cfg.validate().is_err());
}
}