Compare commits

..

4 Commits

Author SHA1 Message Date
houseme cdef5f9ea5 fix(heal): cleanup consumed MRF replay journals
Do not retain Accepted or Merged replay intents as startup anchors after they have been handed to the heal manager. Only refused or still-pending replay records keep the journal on disk until a successor snapshot can persist them.

This keeps successor snapshots limited to the pending queue, which lets successful replay remove both authoritative and legacy journal paths and restores the crash-boundary tests around successor flush.

Co-Authored-By: heihutu <heihutu@gmail.com>

Co-Authored-By: zhi22915 <qiuzgang@gmail.com>
(cherry picked from commit d5b8f49c9d)
2026-09-08 02:10:01 +08:00
houseme 01cb31e4ba Merge branch 'main' into houseme/fix/object-version-limit-constants 2026-09-08 00:42:49 +08:00
houseme ea945c50f2 fix(error): merge equivalent api message branches
Combine the MaxVersionsExceeded and internal IO message branches so Clippy no longer flags identical if blocks while preserving the existing response messages.

Co-Authored-By: heihutu <heihutu@gmail.com>

Co-Authored-By: zhi22915 <qiuzgang@gmail.com>
2026-09-08 00:20:26 +08:00
houseme 7c9b81909e refactor: share object version limit constants
Co-Authored-By: heihutu <heihutu@gmail.com>

Co-Authored-By: zhi22915 <qiuzgang@gmail.com>
2026-09-07 23:54:02 +08:00
7 changed files with 31 additions and 38 deletions
Generated
+1
View File
@@ -9906,6 +9906,7 @@ dependencies = [
"regex",
"rmp",
"rmp-serde",
"rustfs-config",
"rustfs-utils",
"s3s",
"serde",
+7 -2
View File
@@ -100,5 +100,10 @@ pub const DEFAULT_API_MAX_CONNECTIONS: usize = 0;
/// Example: RUSTFS_API_OBJECT_MAX_VERSIONS=50000
pub const ENV_API_OBJECT_MAX_VERSIONS: &str = "RUSTFS_API_OBJECT_MAX_VERSIONS";
/// Default for `RUSTFS_API_OBJECT_MAX_VERSIONS`.
pub const DEFAULT_API_OBJECT_MAX_VERSIONS: u64 = 9_223_372_036_854_775_807;
/// Default and maximum accepted value for `RUSTFS_API_OBJECT_MAX_VERSIONS`.
#[cfg(target_pointer_width = "64")]
pub const DEFAULT_API_OBJECT_MAX_VERSIONS: usize = 9_223_372_036_854_775_807;
/// Default and maximum accepted value for `RUSTFS_API_OBJECT_MAX_VERSIONS`.
#[cfg(not(target_pointer_width = "64"))]
pub const DEFAULT_API_OBJECT_MAX_VERSIONS: usize = usize::MAX;
+1
View File
@@ -44,6 +44,7 @@ tokio = { workspace = true, features = ["io-util", "macros", "sync", "fs", "rt-m
xxhash-rust = { workspace = true, features = ["xxh64", "xxh3"] }
bytes = { workspace = true, features = ["serde"] }
rustfs-utils = { workspace = true, features = ["hash", "http"] }
rustfs-config = { workspace = true, features = ["constants"] }
byteorder = { workspace = true }
tracing.workspace = true
thiserror.workspace = true
+2 -6
View File
@@ -70,12 +70,8 @@ const _XL_FLAG_INLINE_DATA: u8 = 1 << 2;
const META_DATA_READ_DEFAULT: usize = 4 << 10;
const MSGP_UINT32_SIZE: usize = 5;
/// Default max object versions per object, aligned with MinIO's default.
pub const DEFAULT_OBJECT_MAX_VERSIONS: usize = if usize::BITS >= 64 {
9_223_372_036_854_775_807
} else {
usize::MAX
};
/// Default max object versions per object.
pub const DEFAULT_OBJECT_MAX_VERSIONS: usize = rustfs_config::DEFAULT_API_OBJECT_MAX_VERSIONS;
static OBJECT_MAX_VERSIONS: AtomicUsize = AtomicUsize::new(DEFAULT_OBJECT_MAX_VERSIONS);
+4 -7
View File
@@ -68,17 +68,14 @@ pub(super) fn rules() -> Vec<Rule> {
)
},
Rule {
anchors: strings(["Storage inventory probe failed; current drive health is unknown"]),
anchors: strings(["reporting peer disks offline after consecutive storage_info failures"]),
..base(
"peer-disks-offline",
P2Degraded,
"disk",
"peer 存储清单探测失败",
any([
contains("Storage inventory probe failed; current drive health is unknown"),
contains("reporting peer disks offline after consecutive storage_info failures"),
]),
"某 peer 的 storage_info 探测失败,当前磁盘健康状态未知。",
"peer 磁盘被整体判定离线",
contains("reporting peer disks offline after consecutive storage_info failures"),
"对某 peer 连续 storage_info 失败,判定其磁盘整体离线。",
"检查该 peer 节点存活与 RPC 端口可达。",
)
},
+1 -5
View File
@@ -110,7 +110,7 @@ fn every_rule_has_a_positive_sample() {
("remote-peer-faulty", msg("Remote peer health check failed for node2: marking as faulty")),
(
"peer-disks-offline",
msg("Storage inventory probe failed; current drive health is unknown"),
msg("reporting peer disks offline after consecutive storage_info failures"),
),
("drive-faulty-error", msg("remote drive is faulty")),
(
@@ -318,10 +318,6 @@ fn smoke_samples_hit_exact_rule_sets() {
&["disk-marked-faulty"],
);
exact(&msg("erasure write quorum (required=8, achieved=5)"), &["ec-write-quorum"]);
exact(
&msg("reporting peer disks offline after consecutive storage_info failures"),
&["peer-disks-offline"],
);
exact(
&Sample {
message: "Metacache listing quorum failed",
+15 -18
View File
@@ -17,7 +17,7 @@ use crate::{
startup_runtime_hooks::{init_profiling_runtime, install_default_crypto_provider, log_startup_runtime_diagnostics},
startup_tls_material::init_outbound_tls_material,
};
use rustfs_config::ENV_API_OBJECT_MAX_VERSIONS;
use rustfs_config::{DEFAULT_API_OBJECT_MAX_VERSIONS, ENV_API_OBJECT_MAX_VERSIONS};
use rustfs_utils::EnvParseOutcome;
use std::io::{Error, Result};
@@ -32,13 +32,8 @@ pub(crate) async fn init_startup_runtime_foundation(config: &Config) -> Result<(
fn init_object_max_versions_config() -> Result<()> {
let limit = match rustfs_utils::get_env_parse_outcome::<u64>(ENV_API_OBJECT_MAX_VERSIONS) {
EnvParseOutcome::Absent => rustfs_filemeta::DEFAULT_OBJECT_MAX_VERSIONS,
EnvParseOutcome::Invalid => {
return Err(Error::other(format!(
"{ENV_API_OBJECT_MAX_VERSIONS} must be a positive integer no greater than {}",
usize::MAX
)));
}
EnvParseOutcome::Absent => DEFAULT_API_OBJECT_MAX_VERSIONS,
EnvParseOutcome::Invalid => return Err(object_max_versions_config_error()),
EnvParseOutcome::Parsed(value) => object_max_versions_limit_from_u64(value)?,
};
@@ -47,18 +42,20 @@ fn init_object_max_versions_config() -> Result<()> {
fn object_max_versions_limit_from_u64(value: u64) -> Result<usize> {
if value == 0 {
return Err(Error::other(format!(
"{ENV_API_OBJECT_MAX_VERSIONS} must be a positive integer no greater than {}",
usize::MAX
)));
return Err(object_max_versions_config_error());
}
usize::try_from(value).map_err(|_| {
Error::other(format!(
"{ENV_API_OBJECT_MAX_VERSIONS} must be a positive integer no greater than {}",
usize::MAX
))
})
let limit = usize::try_from(value).map_err(|_| object_max_versions_config_error())?;
if limit > DEFAULT_API_OBJECT_MAX_VERSIONS {
return Err(object_max_versions_config_error());
}
Ok(limit)
}
fn object_max_versions_config_error() -> Error {
Error::other(format!(
"{ENV_API_OBJECT_MAX_VERSIONS} must be a positive integer no greater than {DEFAULT_API_OBJECT_MAX_VERSIONS}"
))
}
#[cfg(test)]