[fix](clone) Fix clone and alter tablet use same tablet path #34889 (#36858)

cherry pick from #34889
This commit is contained in:
deardeng
2024-06-30 20:40:54 +08:00
committed by GitHub
parent 07278e9dcb
commit 92cbbd2b75
8 changed files with 253 additions and 38 deletions

View File

@ -155,12 +155,7 @@ EngineCloneTask::EngineCloneTask(const TCloneReq& clone_req, const TMasterInfo&
}
Status EngineCloneTask::execute() {
// register the tablet to avoid it is deleted by gc thread during clone process
if (!StorageEngine::instance()->tablet_manager()->register_clone_tablet(_clone_req.tablet_id)) {
return Status::InternalError("tablet {} is under clone", _clone_req.tablet_id);
}
Status st = _do_clone();
StorageEngine::instance()->tablet_manager()->unregister_clone_tablet(_clone_req.tablet_id);
StorageEngine::instance()->tablet_manager()->update_partitions_visible_version(
{{_clone_req.partition_id, _clone_req.version}});
return st;
@ -174,6 +169,13 @@ Status EngineCloneTask::_do_clone() {
Status status = Status::OK();
string src_file_path;
TBackend src_host;
RETURN_IF_ERROR(StorageEngine::instance()->tablet_manager()->register_transition_tablet(
_clone_req.tablet_id, "clone"));
Defer defer {[&]() {
StorageEngine::instance()->tablet_manager()->unregister_transition_tablet(
_clone_req.tablet_id, "clone");
}};
// Check local tablet exist or not
TabletSharedPtr tablet =
StorageEngine::instance()->tablet_manager()->get_tablet(_clone_req.tablet_id);
@ -184,14 +186,8 @@ Status EngineCloneTask::_do_clone() {
if (tablet && tablet->tablet_state() == TABLET_NOTREADY) {
LOG(WARNING) << "tablet state is not ready when clone, need to drop old tablet, tablet_id="
<< tablet->tablet_id();
// can not drop tablet when under clone. so unregister clone tablet firstly.
StorageEngine::instance()->tablet_manager()->unregister_clone_tablet(_clone_req.tablet_id);
RETURN_IF_ERROR(StorageEngine::instance()->tablet_manager()->drop_tablet(
tablet->tablet_id(), tablet->replica_id(), false));
if (!StorageEngine::instance()->tablet_manager()->register_clone_tablet(
_clone_req.tablet_id)) {
return Status::InternalError("tablet {} is under clone", _clone_req.tablet_id);
}
tablet.reset();
}
bool is_new_tablet = tablet == nullptr;
@ -274,8 +270,21 @@ Status EngineCloneTask::_do_clone() {
<< ". signature: " << _signature;
WARN_IF_ERROR(io::global_local_filesystem()->delete_directory(tablet_dir),
"failed to delete useless clone dir ");
WARN_IF_ERROR(DataDir::delete_tablet_parent_path_if_empty(tablet_dir),
"failed to delete parent dir");
}};
bool exists = true;
Status exists_st = io::global_local_filesystem()->exists(tablet_dir, &exists);
if (!exists_st) {
LOG(WARNING) << "cant get path=" << tablet_dir << " state, st=" << exists_st;
return exists_st;
}
if (exists) {
LOG(WARNING) << "before clone dest path=" << tablet_dir << " exist, remote it first";
RETURN_IF_ERROR(io::global_local_filesystem()->delete_directory(tablet_dir));
}
bool allow_incremental_clone = false;
RETURN_IF_ERROR_(status,
_make_and_download_snapshots(*store, tablet_dir, &src_host, &src_file_path,