Skip to content
This repository has been archived by the owner on Jun 23, 2022. It is now read-only.

feat(disk_balance): close origin replica and update replica dir #668

Merged
merged 104 commits into from
Feb 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
09f8d1e
add status and check
foreverneverer Nov 5, 2020
184cd01
add status and check
foreverneverer Nov 5, 2020
8b3c5de
add status and check
foreverneverer Nov 5, 2020
bdbe60c
init
foreverneverer Nov 5, 2020
4cae974
init
foreverneverer Nov 5, 2020
ceaa229
init
foreverneverer Nov 5, 2020
9c991db
init
foreverneverer Nov 5, 2020
7e1a32a
init
foreverneverer Nov 5, 2020
9919654
init
foreverneverer Nov 6, 2020
d11af56
init
foreverneverer Nov 9, 2020
8a20639
init
foreverneverer Nov 9, 2020
e20dabd
Merge branch 'disk_balance_check' into disk_balance_copy
foreverneverer Nov 9, 2020
4d9c466
init
foreverneverer Nov 9, 2020
e0ad25d
init
foreverneverer Nov 9, 2020
7ebcbdb
upate test
foreverneverer Nov 9, 2020
ac23e6e
Merge branch 'disk_balance_check' into disk_balance_copy
foreverneverer Nov 9, 2020
517f612
refactor
foreverneverer Nov 9, 2020
1c9f422
refactor
foreverneverer Nov 9, 2020
4bc3912
refactor
foreverneverer Nov 9, 2020
8bed904
refactor
foreverneverer Nov 9, 2020
c0acb54
Merge branch 'disk_balance_check' into disk_balance_copy
foreverneverer Nov 9, 2020
57ccf5c
refactor
foreverneverer Nov 9, 2020
2d856c4
refactor
foreverneverer Nov 9, 2020
aa52004
refactor
foreverneverer Nov 9, 2020
08d1668
refactor
foreverneverer Nov 9, 2020
cf2d251
refactor
foreverneverer Nov 9, 2020
4427f30
refactor
foreverneverer Nov 9, 2020
84d0048
refactor
foreverneverer Nov 9, 2020
1b4c499
refactor
foreverneverer Nov 9, 2020
98e191e
refactor
foreverneverer Nov 9, 2020
44a6ff9
Merge branch 'disk_balance_check' into disk_balance_copy
foreverneverer Nov 9, 2020
57a7040
refactor
foreverneverer Nov 9, 2020
8b1016b
refactor
foreverneverer Nov 9, 2020
faac05c
refactor
foreverneverer Nov 9, 2020
864a778
refactor
foreverneverer Nov 9, 2020
8b612f9
refactor
foreverneverer Nov 10, 2020
494b79c
refactor
foreverneverer Nov 10, 2020
628ee2f
refactor
foreverneverer Nov 10, 2020
a2b149e
refactor
foreverneverer Nov 10, 2020
1624659
refactor
foreverneverer Nov 10, 2020
640e990
refactor
foreverneverer Nov 10, 2020
61d4bef
refactor
foreverneverer Nov 10, 2020
a37314b
refactor
foreverneverer Nov 10, 2020
6ca8e90
refactor
foreverneverer Nov 11, 2020
cc56670
refactor
foreverneverer Nov 11, 2020
b8bb0fe
refactor
foreverneverer Nov 11, 2020
dfe25db
Merge branch 'disk_balance_check' into disk_balance_copy
foreverneverer Nov 11, 2020
e395cc9
refactor
foreverneverer Nov 11, 2020
92ff672
refactor
foreverneverer Nov 11, 2020
f6139a3
refactor
foreverneverer Nov 11, 2020
e1d06f0
refactor
foreverneverer Nov 11, 2020
7cbe4a4
refactor
foreverneverer Nov 11, 2020
1a239f0
refactor
foreverneverer Nov 11, 2020
85d772d
refactor
foreverneverer Nov 11, 2020
bf0dbf3
Merge branch 'master' into disk_balance_check
foreverneverer Nov 11, 2020
a5ad732
refactor
foreverneverer Nov 11, 2020
22d8521
refactor
foreverneverer Nov 11, 2020
e8d1786
refactor
foreverneverer Nov 11, 2020
09842fd
test ok
foreverneverer Nov 11, 2020
3bc7660
init
foreverneverer Nov 11, 2020
854cff6
init
foreverneverer Nov 11, 2020
2508a0d
Merge branch 'disk_balance_copy' into disk_balance_close
foreverneverer Nov 11, 2020
56c5880
init
foreverneverer Nov 11, 2020
417ccfd
init
foreverneverer Nov 12, 2020
222e9b7
init
foreverneverer Nov 12, 2020
8914521
delete
foreverneverer Nov 12, 2020
8e28a1c
Merge branch 'disk_balance_check' into disk_balance_copy
foreverneverer Nov 12, 2020
7e0d7b9
Merge branch 'disk_balance_copy' into disk_balance_close
foreverneverer Nov 12, 2020
a862769
delete
foreverneverer Nov 12, 2020
97b53ba
Merge branch 'disk_balance_check' into disk_balance_copy
foreverneverer Nov 12, 2020
28244ef
delete
foreverneverer Nov 12, 2020
960f464
merge
foreverneverer Nov 25, 2020
2acb5c0
merge
foreverneverer Nov 26, 2020
81b1385
merge test
foreverneverer Nov 26, 2020
689e5b3
merge test
foreverneverer Nov 26, 2020
d76e920
merge test
foreverneverer Nov 27, 2020
3508a7f
update merge test 2
foreverneverer Nov 27, 2020
3572a54
update merge test 2
foreverneverer Nov 30, 2020
b5ae7c3
update merge test 2
foreverneverer Nov 30, 2020
76faca3
Merge branch 'master' into disk_balance_close
foreverneverer Nov 30, 2020
669c3e1
update review
foreverneverer Nov 30, 2020
08abc15
Merge branch 'master' of github.com:XiaoMi/rdsn into disk_balance_close
foreverneverer Nov 30, 2020
56d28d5
Merge branch 'disk_balance_close' of github.com:Shuo-Jia/rdsn into di…
foreverneverer Nov 30, 2020
98e84f9
update review
foreverneverer Nov 30, 2020
3c7341a
update review
foreverneverer Nov 30, 2020
c05568c
update review
foreverneverer Nov 30, 2020
bb93a0a
update review
foreverneverer Nov 30, 2020
40ae775
refactor gc
foreverneverer Dec 3, 2020
846d64c
refactor gc
foreverneverer Dec 3, 2020
a46febb
Merge branch 'master' into disk_balance_close
foreverneverer Dec 3, 2020
1a49590
Merge branch 'master' into disk_balance_close
hycdong Dec 7, 2020
b44cd42
fix review
foreverneverer Dec 9, 2020
bea380b
Merge branch 'disk_balance_close' of github.com:Shuo-Jia/rdsn into di…
foreverneverer Dec 9, 2020
88dbc83
fix review
foreverneverer Dec 9, 2020
6d0b3db
fix review
foreverneverer Dec 9, 2020
505b951
fix review
foreverneverer Dec 10, 2020
c4eabea
fix review
foreverneverer Dec 10, 2020
0758af4
fix review
foreverneverer Dec 10, 2020
6bdccd7
init
foreverneverer Dec 11, 2020
a61e211
init
foreverneverer Dec 11, 2020
1c5d527
init
foreverneverer Dec 11, 2020
7503ae0
update review
foreverneverer Feb 1, 2021
c37de7a
update review
foreverneverer Feb 2, 2021
9703915
merge master
foreverneverer Feb 20, 2021
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
2 changes: 2 additions & 0 deletions src/common/fs_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <dsn/utility/filesystem.h>
#include <thread>
#include <dsn/dist/fmt_logging.h>
#include <dsn/utility/fail_point.h>

namespace dsn {
namespace replication {
Expand Down Expand Up @@ -76,6 +77,7 @@ unsigned dir_node::remove(const gpid &pid)

void dir_node::update_disk_stat()
{
FAIL_POINT_INJECT_F("update_disk_stat", [](string_view) {});
dsn::utils::filesystem::disk_space_info info;
if (dsn::utils::filesystem::get_disk_space_info(full_dir, info)) {
disk_capacity_mb = info.capacity / 1024 / 1024;
Expand Down
18 changes: 2 additions & 16 deletions src/common/replication_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,8 @@ replication_options::replication_options()
checkpoint_max_interval_hours = 2;

gc_disabled = false;
gc_interval_ms = 30 * 1000; // 30 seconds
gc_memory_replica_interval_ms = 10 * 60 * 1000; // 10 minutes
gc_disk_error_replica_interval_seconds = 7 * 24 * 3600; // 1 week
gc_disk_garbage_replica_interval_seconds = 24 * 3600; // 1 day
gc_interval_ms = 30 * 1000; // 30 seconds
gc_memory_replica_interval_ms = 10 * 60 * 1000; // 10 minutes

disk_stat_disabled = false;
disk_stat_interval_seconds = 600;
Expand Down Expand Up @@ -357,18 +355,6 @@ void replication_options::initialize()
gc_memory_replica_interval_ms,
"after closing a healthy replica (due to LB), the replica will remain in memory for this "
"long (ms) for quick recover");
gc_disk_error_replica_interval_seconds =
(int)dsn_config_get_value_uint64("replication",
"gc_disk_error_replica_interval_seconds",
gc_disk_error_replica_interval_seconds,
"error replica are deleted after they have been closed "
"and lasted on disk this long (seconds)");
gc_disk_garbage_replica_interval_seconds =
(int)dsn_config_get_value_uint64("replication",
"gc_disk_garbage_replica_interval_seconds",
gc_disk_garbage_replica_interval_seconds,
"garbage replica are deleted after they have been closed "
"and lasted on disk this long (seconds)");

disk_stat_disabled = dsn_config_get_value_bool(
"replication", "disk_stat_disabled", disk_stat_disabled, "whether to disable disk stat");
Expand Down
2 changes: 0 additions & 2 deletions src/common/replication_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,6 @@ class replication_options
bool gc_disabled;
int32_t gc_interval_ms;
int32_t gc_memory_replica_interval_ms;
int32_t gc_disk_error_replica_interval_seconds;
int32_t gc_disk_garbage_replica_interval_seconds;

bool disk_stat_disabled;
int32_t disk_stat_interval_seconds;
Expand Down
123 changes: 123 additions & 0 deletions src/replica/disk_cleaner.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/

#include <dsn/utility/flags.h>
#include <dsn/utility/filesystem.h>
#include <dsn/dist/fmt_logging.h>
#include <dsn/c/api_layer1.h>

#include "disk_cleaner.h"

namespace dsn {
namespace replication {

DSN_DEFINE_uint64(
"replication",
gc_disk_error_replica_interval_seconds,
7 * 24 * 3600 /*7day*/,
"Duration of error replica being removed, which is in a directory with '.err' suffixed");
DSN_DEFINE_uint64(
"replication",
gc_disk_garbage_replica_interval_seconds,
24 * 3600 /*1day*/,
"Duration of garbaged replica being removed, which is in a directory with '.gar' suffixed");

DSN_DEFINE_uint64("replication",
gc_disk_migration_tmp_replica_interval_seconds,
neverchanje marked this conversation as resolved.
Show resolved Hide resolved
24 * 3600 /*1day*/,
"Duration of disk-migration tmp replica being removed, which is in a directory "
"with '.tmp' suffixed");
DSN_DEFINE_uint64("replication",
gc_disk_migration_origin_replica_interval_seconds,
7 * 24 * 3600 /*7day*/,
"Duration of disk-migration origin replica being removed, which is in a "
"directory with '.ori' suffixed");

const std::string kFolderSuffixErr = ".err";
const std::string kFolderSuffixGar = ".gar";
const std::string kFolderSuffixBak = ".bak";
const std::string kFolderSuffixOri = ".ori";
const std::string kFolderSuffixTmp = ".tmp";

error_s disk_remove_useless_dirs(const std::vector<std::string> &data_dirs,
/*output*/ disk_cleaning_report &report)
{
std::vector<std::string> sub_list;
for (auto &dir : data_dirs) {
std::vector<std::string> tmp_list;
if (!dsn::utils::filesystem::get_subdirectories(dir, tmp_list, false)) {
dwarn_f("gc_disk: failed to get subdirectories in {}", dir);
return error_s::make(ERR_OBJECT_NOT_FOUND, "failed to get subdirectories");
}
sub_list.insert(sub_list.end(), tmp_list.begin(), tmp_list.end());
}
for (auto &fpath : sub_list) {
auto name = dsn::utils::filesystem::get_file_name(fpath);
if (!is_data_dir_removable(name)) {
continue;
}
std::string folder_suffix = name.substr(name.length() - 4);

time_t mt;
if (!dsn::utils::filesystem::last_write_time(fpath, mt)) {
dwarn_f("gc_disk: failed to get last write time of {}", fpath);
continue;
}

auto last_write_time = (uint64_t)mt;
uint64_t current_time_ms = dsn_now_ms();
uint64_t remove_interval_seconds = current_time_ms / 1000;

// don't delete ".bak" directory because it is backed by administrator.
if (folder_suffix == kFolderSuffixErr) {
report.error_replica_count++;
remove_interval_seconds = FLAGS_gc_disk_error_replica_interval_seconds;
} else if (folder_suffix == kFolderSuffixGar) {
report.garbage_replica_count++;
remove_interval_seconds = FLAGS_gc_disk_garbage_replica_interval_seconds;
} else if (folder_suffix == kFolderSuffixTmp) {
report.disk_migrate_tmp_count++;
remove_interval_seconds = FLAGS_gc_disk_migration_tmp_replica_interval_seconds;
} else if (folder_suffix == kFolderSuffixOri) {
report.disk_migrate_origin_count++;
remove_interval_seconds = FLAGS_gc_disk_migration_origin_replica_interval_seconds;
}

if (last_write_time + remove_interval_seconds <= current_time_ms / 1000) {
if (!dsn::utils::filesystem::remove_path(fpath)) {
dwarn_f("gc_disk: failed to delete directory '{}', time_used_ms = {}",
fpath,
dsn_now_ms() - current_time_ms);
} else {
dwarn_f("gc_disk: replica_dir_op succeed to delete directory '{}'"
", time_used_ms = {}",
fpath,
dsn_now_ms() - current_time_ms);
report.remove_dir_count++;
}
} else {
ddebug_f("gc_disk: reserve directory '{}', wait_seconds = {}",
fpath,
last_write_time + remove_interval_seconds - current_time_ms / 1000);
}
}
return error_s::ok();
}
} // namespace replication
} // namespace dsn
73 changes: 73 additions & 0 deletions src/replica/disk_cleaner.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
#pragma once

#include <vector>
#include <dsn/utility/errors.h>
#include <dsn/perf_counter/perf_counter_wrapper.h>

namespace dsn {
namespace replication {
DSN_DECLARE_uint64(gc_disk_error_replica_interval_seconds);
DSN_DECLARE_uint64(gc_disk_garbage_replica_interval_seconds);
DSN_DECLARE_uint64(gc_disk_migration_tmp_replica_interval_seconds);
DSN_DECLARE_uint64(gc_disk_migration_origin_replica_interval_seconds);

// the invalid folder suffix, server will check disk folder and deal with them
extern const std::string kFolderSuffixErr; // replica error dir
extern const std::string kFolderSuffixGar; // replica closed and assign garbage dir
extern const std::string kFolderSuffixBak; // replica backup dir which can be restored
extern const std::string kFolderSuffixOri; // replica disk migration origin dir
extern const std::string kFolderSuffixTmp; // replica disk migration temp dir

struct disk_cleaning_report
{
int remove_dir_count{0};

int garbage_replica_count{0};
int error_replica_count{0};
int disk_migrate_tmp_count{0};
int disk_migrate_origin_count{0};
};

// Removes the useless data from data directories.
extern error_s disk_remove_useless_dirs(const std::vector<std::string> &data_dirs,
/*output*/ disk_cleaning_report &report);

inline bool is_data_dir_removable(const std::string &dir)
{
if (dir.length() < 4) {
return false;
}
const std::string folder_suffix = dir.substr(dir.length() - 4);
return (folder_suffix == kFolderSuffixErr || folder_suffix == kFolderSuffixGar ||
folder_suffix == kFolderSuffixTmp || folder_suffix == kFolderSuffixOri);
}

// Note: ".bak" is invalid but not allow delete, because it can be backed by administrator.
inline bool is_data_dir_invalid(const std::string &dir)
{
if (dir.length() < 4) {
return false;
}
const std::string folder_suffix = dir.substr(dir.length() - 4);
return is_data_dir_removable(dir) || folder_suffix == kFolderSuffixBak;
}
} // namespace replication
} // namespace dsn
18 changes: 14 additions & 4 deletions src/replica/replica.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,10 +386,13 @@ bool replica::verbose_commit_log() const { return _stub->_verbose_commit_log; }

void replica::close()
{
dassert(status() == partition_status::PS_ERROR || status() == partition_status::PS_INACTIVE,
"%s: invalid state %s when calling replica::close",
name(),
enum_to_string(status()));
dassert_replica(status() == partition_status::PS_ERROR ||
status() == partition_status::PS_INACTIVE ||
_disk_migrator->status() >= disk_migration_status::MOVED,
"invalid state(partition_status={}, migration_status={}) when calling "
"replica close",
enum_to_string(status()),
enum_to_string(_disk_migrator->status()));
foreverneverer marked this conversation as resolved.
Show resolved Hide resolved

uint64_t start_time = dsn_now_ms();

Expand Down Expand Up @@ -436,6 +439,13 @@ void replica::close()
}
}

if (_disk_migrator->status() == disk_migration_status::MOVED) {
// this will update disk_migration_status::MOVED->disk_migration_status::CLOSED
_disk_migrator->update_replica_dir();
} else if (_disk_migrator->status() == disk_migration_status::CLOSED) {
foreverneverer marked this conversation as resolved.
Show resolved Hide resolved
_disk_migrator.reset();
}

_counter_private_log_size.clear();

// duplication_impl may have ongoing tasks.
Expand Down
Loading