forked from databendlabs/databend
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature: metasrv has to be compatible with 20220413-34e89c99e4e356327…
…18e9227f6549b3090eb0fb9 Let metasvr be able to load the log-entry format before commit 34e89c9, in which the `Cmd` format changed. To solve th compatible issue, an intermedia type is introduced, which is a super set of the old and new type. When loading a record, first load it into the superset type, then reduce to the latest type. - fix: databendlabs#4890
- Loading branch information
1 parent
d09955c
commit 223e6cf
Showing
6 changed files
with
412 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
// Copyright 2021 Datafuse Labs. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
use openraft::NodeId; | ||
use serde::Deserialize; | ||
use serde::Serialize; | ||
|
||
use crate::CreateShareReq; | ||
use crate::DatabaseMeta; | ||
use crate::DropShareReq; | ||
use crate::KVMeta; | ||
use crate::MatchSeq; | ||
use crate::Node; | ||
use crate::Operation; | ||
use crate::TableMeta; | ||
use crate::UpsertTableOptionReq; | ||
|
||
/// Compatible with changes made in 34e89c99e4e35632718e9227f6549b3090eb0fb9 on 20220413 | ||
/// This struct can deserialize json built by the binary before and after this commit. | ||
/// | ||
/// - 20220413: In this commit: | ||
/// - It replaced variant struct with standalone struct. | ||
/// - The standalone struct has a `if_not_exists` or `if_not_exists`. | ||
/// | ||
/// Compatibility: | ||
/// - Json layout for variant struct and standalone struct is the same. | ||
/// - `if_exist` and `if_not_exist` only affects client response, but not meta data. | ||
/// Thus it is safe to give it a default value. | ||
/// | ||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] | ||
#[allow(clippy::large_enum_variant)] | ||
pub enum Cmd { | ||
IncrSeq { | ||
key: String, | ||
}, | ||
|
||
AddNode { | ||
node_id: NodeId, | ||
node: Node, | ||
}, | ||
|
||
CreateDatabase { | ||
// latest add | ||
if_not_exists: Option<bool>, | ||
tenant: String, | ||
// 20220413 | ||
name: Option<String>, | ||
// latest add | ||
db_name: Option<String>, | ||
meta: DatabaseMeta, | ||
}, | ||
|
||
DropDatabase { | ||
// latest add | ||
if_exists: Option<bool>, | ||
tenant: String, | ||
// 20220413 | ||
name: Option<String>, | ||
// latest add | ||
db_name: Option<String>, | ||
}, | ||
|
||
CreateTable { | ||
// latest add | ||
if_not_exists: Option<bool>, | ||
tenant: String, | ||
db_name: String, | ||
table_name: String, | ||
table_meta: TableMeta, | ||
}, | ||
|
||
DropTable { | ||
// latest add | ||
if_exists: Option<bool>, | ||
tenant: String, | ||
db_name: String, | ||
table_name: String, | ||
}, | ||
|
||
RenameTable { | ||
// latest add | ||
if_exists: Option<bool>, | ||
tenant: String, | ||
db_name: String, | ||
table_name: String, | ||
new_db_name: String, | ||
new_table_name: String, | ||
}, | ||
// latest add | ||
CreateShare(CreateShareReq), | ||
// latest add | ||
DropShare(DropShareReq), | ||
|
||
UpsertTableOptions(UpsertTableOptionReq), | ||
|
||
UpsertKV { | ||
key: String, | ||
seq: MatchSeq, | ||
value: Operation<Vec<u8>>, | ||
value_meta: Option<KVMeta>, | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// Copyright 2021 Datafuse Labs. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
//! Provides backward compatibility. | ||
//! | ||
//! Changed meta data types is loaded into a type that is compatible with all old versions. | ||
//! And then reduce the compatible version to the latest version. | ||
//! | ||
//! To guarantee compatibility: | ||
//! - Field type must not change: Changing `x: String` to `x: i64` makes compatibility impassible to achieve. | ||
//! - Only add or remove fields. | ||
//! | ||
//! E.g. `A` is defined as: | ||
//! ```ignore | ||
//! #[derive(Serialize, Deserialize)] | ||
//! struct A { | ||
//! i: u64, | ||
//! } | ||
//! ``` | ||
//! | ||
//! An upgrade may introduce another field `j`, and remove `i`. | ||
//! The upgraded message `B` will be: | ||
//!```ignore | ||
//! #[derive(Serialize)] | ||
//! struct Foo { | ||
//! j: u64, | ||
//! } | ||
//!``` | ||
//! | ||
//! To be compatible with `A` and `B`, the max compatible `C` should be: | ||
//!```ignore | ||
//! #[derive(Serialize, Deserialize)] | ||
//! struct Compatible { | ||
//! i: Option<u64>, | ||
//! j: Option<u64>, | ||
//! } | ||
//!``` | ||
//! | ||
//! This way `Compatible` is able to load both `{"i": 1}` or `{"j": 2}`. | ||
//! The complete example is: | ||
//! ```ignore | ||
//! #[derive(Debug, Serialize, Deserialize)] | ||
//! struct A { | ||
//! pub i: u64, | ||
//! } | ||
//! | ||
//! #[derive(Debug, Serialize)] | ||
//! struct B { | ||
//! pub j: u64, | ||
//! } | ||
//! | ||
//! #[derive(Debug, Serialize, Deserialize)] | ||
//! struct Compatible { | ||
//! pub i: Option<u64>, | ||
//! pub j: Option<u64>, | ||
//! } | ||
//! | ||
//! impl<'de> Deserialize<'de> for B { | ||
//! fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | ||
//! where | ||
//! D: Deserializer<'de>, | ||
//! { | ||
//! let c: Compatible = de::Deserialize::deserialize(deserializer)?; | ||
//! | ||
//! if c.i.is_some() { | ||
//! println!("loaded from serialized A, convert to B"); | ||
//! Ok(B { j: c.i.unwrap() }) | ||
//! } else { | ||
//! println!("loaded from serialized B"); | ||
//! Ok(B { j: c.j.unwrap() }) | ||
//! } | ||
//! } | ||
//! } | ||
//! ``` | ||
pub(crate) mod cmd_20220413; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.