feat: cli tool to repair partition columns mismatch (#7605)

* feat: cli tool to repair partition columns mismatch

Signed-off-by: luofucong <luofc@foxmail.com>

* Apply suggestions from code review

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* fix: harden partition column repair

Signed-off-by: MichaelScofield <MichaelScofield@users.noreply.github.com>

---------

Signed-off-by: luofucong <luofc@foxmail.com>
Signed-off-by: MichaelScofield <MichaelScofield@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
LFC
2026-02-09 10:58:25 +08:00
committed by GitHub
parent 8026b23834
commit fcfab97d8c
8 changed files with 357 additions and 16 deletions

View File

@@ -21,6 +21,7 @@ pub mod store;
use std::fmt::{Display, Formatter};
use api::v1::meta::{KeyValue as PbKeyValue, ResponseHeader as PbResponseHeader};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone)]
pub struct ResponseHeader(PbResponseHeader);
@@ -48,7 +49,7 @@ impl ResponseHeader {
}
}
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct KeyValue {
pub key: Vec<u8>,
pub value: Vec<u8>,

View File

@@ -35,7 +35,7 @@ use crate::kv_backend::KvBackendRef;
use crate::range_stream::{DEFAULT_PAGE_SIZE, PaginationStream};
use crate::rpc::KeyValue;
use crate::rpc::store::{BatchPutRequest, RangeRequest};
use crate::snapshot::file::{Document, KeyValue as FileKeyValue};
use crate::snapshot::file::Document;
/// The format of the backup file.
#[derive(Debug, PartialEq, Eq, Display, Clone, Copy)]
@@ -164,7 +164,7 @@ pub struct MetadataSnapshotManager {
const MAX_REQUEST_SIZE: usize = 1024 * 1024;
/// Returns true if the key is an internal key.
fn is_internal_key(kv: &FileKeyValue) -> bool {
fn is_internal_key(kv: &KeyValue) -> bool {
kv.key.starts_with(ELECTION_KEY.as_bytes()) || kv.key.starts_with(CANDIDATES_ROOT.as_bytes())
}
@@ -197,7 +197,7 @@ impl MetadataSnapshotManager {
let mut total_request_size = 0;
let mut count = 0;
let now = Instant::now();
for FileKeyValue { key, value } in metadata_content.into_iter() {
for KeyValue { key, value } in metadata_content.into_iter() {
count += 1;
let key_size = key.len();
let value_size = value.len();
@@ -277,7 +277,7 @@ impl MetadataSnapshotManager {
let now = Instant::now();
let req = RangeRequest::new().with_range(vec![0], vec![0]);
let stream = PaginationStream::new(self.kv_backend.clone(), req, DEFAULT_PAGE_SIZE, |kv| {
Ok(FileKeyValue {
Ok(KeyValue {
key: kv.key,
value: kv.value,
})

View File

@@ -20,6 +20,7 @@ use snafu::ResultExt;
use crate::error::{
DeserializeFlexbuffersSnafu, ReadFlexbuffersSnafu, Result, SerializeFlexbuffersSnafu,
};
use crate::rpc::KeyValue;
use crate::snapshot::FileFormat;
/// The layout of the backup file.
@@ -118,13 +119,6 @@ impl MetadataContent {
}
}
/// The key-value pair of the backup file.
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub(crate) struct KeyValue {
pub key: Vec<u8>,
pub value: Vec<u8>,
}
#[cfg(test)]
mod tests {
use super::*;