Skip to content

Commit 39f4db4

Browse files
Expose the setting of the maximum size of prefill-for-recycle to users (#301)
Signed-off-by: Lucasliang <[email protected]>
1 parent 3c442af commit 39f4db4

File tree

2 files changed

+61
-9
lines changed

2 files changed

+61
-9
lines changed

src/config.rs

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Copyright (c) 2017-present, PingCAP, Inc. Licensed under Apache-2.0.
22

3-
use log::warn;
3+
use log::{info, warn};
44
use serde::{Deserialize, Serialize};
55

66
use crate::pipe_log::Version;
@@ -108,6 +108,13 @@ pub struct Config {
108108
///
109109
/// Default: false
110110
pub prefill_for_recycle: bool,
111+
112+
/// Maximum capacity for preparing log files for recycling when start.
113+
/// If not `None`, its size is equal to `purge-threshold`.
114+
/// Only available for `prefill-for-recycle` is true.
115+
///
116+
/// Default: None
117+
pub prefill_limit: Option<ReadableSize>,
111118
}
112119

113120
impl Default for Config {
@@ -129,6 +136,7 @@ impl Default for Config {
129136
memory_limit: None,
130137
enable_log_recycle: false,
131138
prefill_for_recycle: false,
139+
prefill_limit: None,
132140
};
133141
// Test-specific configurations.
134142
#[cfg(test)]
@@ -180,6 +188,14 @@ impl Config {
180188
"prefill is not allowed when log recycle is disabled"
181189
));
182190
}
191+
if !self.prefill_for_recycle && self.prefill_limit.is_some() {
192+
warn!("prefill-limit will be ignored when prefill is disabled");
193+
self.prefill_limit = None;
194+
}
195+
if self.prefill_for_recycle && self.prefill_limit.is_none() {
196+
info!("prefill-limit will be calibrated to purge-threshold");
197+
self.prefill_limit = Some(self.purge_threshold);
198+
}
183199
#[cfg(not(feature = "swap"))]
184200
if self.memory_limit.is_some() {
185201
warn!("memory-limit will be ignored because swap feature is disabled");
@@ -207,6 +223,25 @@ impl Config {
207223
0
208224
}
209225
}
226+
227+
/// Returns the capacity for preparing log files for recycling when start.
228+
pub(crate) fn prefill_capacity(&self) -> usize {
229+
// Attention please, log files with Version::V1 could not be recycled, so it's
230+
// useless for prefill.
231+
if !self.enable_log_recycle || !self.format_version.has_log_signing() {
232+
return 0;
233+
}
234+
let prefill_limit = self.prefill_limit.unwrap_or(ReadableSize(0)).0;
235+
if self.prefill_for_recycle && prefill_limit >= self.target_file_size.0 {
236+
// Keep same with the maximum setting of `recycle_capacity`.
237+
std::cmp::min(
238+
(prefill_limit / self.target_file_size.0) as usize + 2,
239+
u32::MAX as usize,
240+
)
241+
} else {
242+
0
243+
}
244+
}
210245
}
211246

212247
#[cfg(test)]
@@ -304,4 +339,24 @@ mod tests {
304339
.unwrap()
305340
.contains("tolerate-corrupted-tail-records"));
306341
}
342+
343+
#[test]
344+
fn test_prefill_for_recycle() {
345+
let default_prefill_v1 = r#"
346+
enable-log-recycle = true
347+
prefill-for-recycle = true
348+
"#;
349+
let mut cfg_load: Config = toml::from_str(default_prefill_v1).unwrap();
350+
assert!(cfg_load.sanitize().is_ok());
351+
assert_eq!(cfg_load.prefill_limit.unwrap(), cfg_load.purge_threshold);
352+
353+
let default_prefill_v2 = r#"
354+
enable-log-recycle = true
355+
prefill-for-recycle = false
356+
prefill-limit = "20GB"
357+
"#;
358+
let mut cfg_load: Config = toml::from_str(default_prefill_v2).unwrap();
359+
assert!(cfg_load.sanitize().is_ok());
360+
assert!(cfg_load.prefill_limit.is_none());
361+
}
307362
}

src/file_pipe_log/pipe_builder.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
//! Helper types to recover in-memory states from log files.
44
5-
use std::cmp;
65
use std::fs::{self, File as StdFile};
76
use std::io::Write;
87
use std::marker::PhantomData;
@@ -32,8 +31,8 @@ use super::pipe::{
3231
};
3332
use super::reader::LogItemBatchFileReader;
3433

34+
/// Maximum size for the buffer for prefilling.
3535
const PREFILL_BUFFER_SIZE: usize = ReadableSize::mb(16).0 as usize;
36-
const MAX_PREFILL_SIZE: usize = ReadableSize::gb(12).0 as usize;
3736

3837
/// `ReplayMachine` is a type of deterministic state machine that obeys
3938
/// associative law.
@@ -477,14 +476,12 @@ impl<F: FileSystem> DualPipesBuilder<F> {
477476

478477
fn initialize_files(&mut self) -> Result<()> {
479478
let target_file_size = self.cfg.target_file_size.0 as usize;
480-
let mut target = if self.cfg.prefill_for_recycle {
479+
let mut target = std::cmp::min(
480+
self.cfg.prefill_capacity(),
481481
self.cfg
482482
.recycle_capacity()
483-
.saturating_sub(self.append_files.len())
484-
} else {
485-
0
486-
};
487-
target = cmp::min(target, MAX_PREFILL_SIZE / target_file_size);
483+
.saturating_sub(self.append_files.len()),
484+
);
488485
let to_create = target.saturating_sub(self.recycled_files.len());
489486
if to_create > 0 {
490487
let now = Instant::now();

0 commit comments

Comments
 (0)