Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(metactl): when restoring a cluster from backup data, it does not require to specify grpc addresses #9878

Merged
merged 2 commits into from
Feb 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/doc/10-deploy/06-metasrv/30-metasrv-backup-restore.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,14 @@ cat "<output_fn>" | ./target/debug/databend-metactl --import --raft-dir "<your_m
## Import data as a new databend-meta cluster

With specifies the `--initial-cluster` argument, the `databend-metactl` can import the data as a new cluster.
The `--initial-cluster` format is: `node_id=raft_advertise_host:raft_api_port,grpc_api_addr`, each node config is separated by space, the meaning of `raft_advertise_host`,`raft_api_port`,`grpc_api_addr` is the same in raft config.
The `--initial-cluster` format is: `node_id=raft_advertise_host:raft_api_port`, each node config is separated by space, the meaning of `raft_advertise_host`,`raft_api_port` is the same in raft config.

E.g.:

```
/target/debug/databend-metactl --import --raft-dir ./.databend/new_meta1 --id=1 --db meta.db --initial-cluster 1=localhost:29103,0.0.0.0:19191 2=localhost:29203,0.0.0.0:29191 3=localhost:29303,0.0.0.0:39191
/target/debug/databend-metactl --import --raft-dir ./.databend/new_meta2 --id=2 --db meta.db --initial-cluster 1=localhost:29103,0.0.0.0:19191 2=localhost:29203,0.0.0.0:29191 3=localhost:29303,0.0.0.0:39191
/target/debug/databend-metactl --import --raft-dir ./.databend/new_meta3 --id=3 --db meta.db --initial-cluster 1=localhost:29103,0.0.0.0:19191 2=localhost:29203,0.0.0.0:29191 3=localhost:29303,0.0.0.0:39191
/target/debug/databend-metactl --import --raft-dir ./.databend/new_meta1 --id=1 --db meta.db --initial-cluster 1=localhost:29103 2=localhost:29203 3=localhost:29303
/target/debug/databend-metactl --import --raft-dir ./.databend/new_meta2 --id=2 --db meta.db --initial-cluster 1=localhost:29103 2=localhost:29203 3=localhost:29303
/target/debug/databend-metactl --import --raft-dir ./.databend/new_meta3 --id=3 --db meta.db --initial-cluster 1=localhost:29103 2=localhost:29203 3=localhost:29303
```

The script above imports the exported data from `meta.db` and initializes the three cluster nodes: id 1, which raft directory is `./.databend/new_meta1`, and so are id 2 and 3 with different raft directory.
Expand Down
9 changes: 4 additions & 5 deletions src/binaries/meta/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,10 @@ async fn main() -> anyhow::Result<()> {

info!("Join result: {:?}", join_res);

if join_res.is_err() {
info!(
"Already in cluster, register node to update raft_api_advertise_host_endpoint and grpc_api_advertise_host"
);

info!(
"Register node to update raft_api_advertise_host_endpoint and grpc_api_advertise_address"
);
{
info!("Wait for active leader to register node");
let wait = meta_node.raft.wait(Some(Duration::from_secs(20)));
let metrics = wait
Expand Down
40 changes: 26 additions & 14 deletions src/binaries/metactl/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,32 +144,44 @@ fn import_from(restore: String) -> anyhow::Result<Option<LogId>> {
}
}

/// Build `Node` for cluster with new addresses configured.
///
/// Raw config is: `<NodeId>=<raft-api-host>:<raft-api-port>[,...]`, e.g. `1=localhost:29103` or `1=localhost:29103,0.0.0.0:19191`
/// The second part is obsolete grpc api address and will be just ignored. Databend-meta loads Grpc address from config file when starting up.
fn build_nodes(initial_cluster: Vec<String>, id: u64) -> anyhow::Result<BTreeMap<NodeId, Node>> {
eprintln!("init-cluster: id={}, {:?}", id, initial_cluster);

let mut nodes = BTreeMap::new();
for peer in initial_cluster {
eprintln!("peer:{}", peer);
let node_info: Vec<&str> = peer.split('=').collect();
if node_info.len() != 2 {
return Err(anyhow::anyhow!("invalid peer str: {}", peer));
}
let id = u64::from_str(node_info[0])?;

let addrs: Vec<&str> = node_info[1].split(',').collect();
if addrs.len() != 2 {
let id_addrs: Vec<&str> = peer.split('=').collect();
if id_addrs.len() != 2 {
return Err(anyhow::anyhow!("invalid peer str: {}", peer));
}
let url = Url::parse(&format!("http://{}", addrs[0]))?;
if url.host_str().is_none() || url.port().is_none() {
return Err(anyhow::anyhow!("invalid peer raft addr: {}", addrs[0]));
let id = u64::from_str(id_addrs[0])?;

let addrs: Vec<&str> = id_addrs[1].split(',').collect();
if addrs.len() > 2 || addrs.is_empty() {
return Err(anyhow::anyhow!(
"require 1 or 2 addresses in peer str: {}",
peer
));
}
let endpoint = Endpoint {
addr: url.host_str().unwrap().to_string(),
port: url.port().unwrap() as u32,
let url = Url::parse(&format!("http://{}", addrs[0]))?;
let endpoint = match (url.host_str(), url.port()) {
(Some(addr), Some(port)) => Endpoint {
addr: addr.to_string(),
port: port as u32,
},
_ => {
return Err(anyhow::anyhow!("invalid peer raft addr: {}", addrs[0]));
}
};
let node = Node::new(id, endpoint.clone()).with_grpc_advertise_address(Some(&addrs[1]));

let node = Node::new(id, endpoint.clone());
eprintln!("new cluster node:{}", node);

nodes.insert(id, node);
}

Expand Down
3 changes: 2 additions & 1 deletion tests/metactl/test-metactl-restore-new-cluster.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ rm -fr .databend/
echo " === import old meta node data to new cluster"
./target/debug/databend-metactl --import --raft-dir ./.databend/new_meta1 --id=4 --db meta.db --initial-cluster 4=localhost:29103,127.0.0.1:19191 5=localhost:29203,127.0.0.1:29191 6=localhost:29303,127.0.0.1:39191
./target/debug/databend-metactl --import --raft-dir ./.databend/new_meta2 --id=5 --db meta.db --initial-cluster 4=localhost:29103,127.0.0.1:19191 5=localhost:29203,127.0.0.1:29191 6=localhost:29303,127.0.0.1:39191
./target/debug/databend-metactl --import --raft-dir ./.databend/new_meta3 --id=6 --db meta.db --initial-cluster 4=localhost:29103,127.0.0.1:19191 5=localhost:29203,127.0.0.1:29191 6=localhost:29303,127.0.0.1:39191
# test cluster config without grpc address
./target/debug/databend-metactl --import --raft-dir ./.databend/new_meta3 --id=6 --db meta.db --initial-cluster 4=localhost:29103 5=localhost:29203 6=localhost:29303

echo " === check if state machine is complete by checking key 'LastMembership'"
if ./target/debug/databend-metactl --export --raft-dir ./.databend/new_meta1 | grep LastMembership; then
Expand Down