.. confval:: rgw_reshard_thread_interval
.. confval:: rgw_reshard_num_logs
+- ``rgw_reshard_progress_judge_interval``: interval of judging if bucket reshard failed in reshard log process state, default: 120 seconds
+
+- ``rgw_reshard_progress_judge_ratio``: ratio of reshard progress judge interval to randomly vary, default: 0.5
+
Admin commands
==============
with_legacy: true
services:
- rgw
+- name: rgw_reshard_progress_judge_interval
+ type: uint
+ level: dev
+ desc: interval (in seconds) of judging if bucket reshard failed in block state
+ default: 120
+ services:
+ - rgw
+- name: rgw_reshard_progress_judge_ratio
+ type: float
+ level: dev
+ desc: ratio of reshard progress judge interval to randomly vary
+ long_desc: Add a random delay to rgw_reshard_progress_judge_interval for deciding when
+ to judge the reshard process. The default setting spreads judge time window of
+ [1, 1.5] * rgw_reshard_progress_judge_interval.
+ default: 0.5
+ services:
+ - rgw
+ see_also:
+ - rgw_reshard_progress_judge_interval
- name: rgw_debug_inject_set_olh_err
type: uint
level: dev
utime_t ut(bucket->get_modification_time());
utime_t ctime_ut(bucket->get_creation_time());
+ utime_t logrecord_ut(bucket->get_info().layout.judge_reshard_lock_time);
formatter->open_object_section("stats");
formatter->dump_string("bucket", bucket->get_name());
formatter->dump_int("index_generation", bucket_info.layout.current_index.gen);
formatter->dump_int("num_shards",
bucket_info.layout.current_index.layout.normal.num_shards);
- formatter->dump_string("reshard_status", to_string(bucket_info.reshard_status));
+ formatter->dump_string("reshard_status", to_string(bucket_info.layout.resharding));
+ logrecord_ut.gmtime(formatter->dump_stream("judge_reshard_lock_time"));
formatter->dump_bool("object_lock_enabled", bucket_info.obj_lock_enabled());
formatter->dump_bool("mfa_enabled", bucket_info.mfa_enabled());
::encode_json("owner", bucket_info.owner, formatter);
*pbs = bs;
}
+ if (target->bucket_info.layout.resharding == rgw::BucketReshardState::InLogrecord) {
+ store->reshard_failed_while_logrecord(target->bucket_info, y, dpp);
+ }
+
return 0;
}
return r;
}
+ if (bucket_info.layout.resharding == rgw::BucketReshardState::InLogrecord) {
+ reshard_failed_while_logrecord(bucket_info, y, dpp);
+ }
+
return 0;
}
+int RGWRados::reshard_failed_while_logrecord(RGWBucketInfo& bucket_info, optional_yield y,
+ const DoutPrefixProvider *dpp)
+{
+ real_time now = real_clock::now();
+ double r = rand() / (double)RAND_MAX;
+ double reshard_progress_judge_interval = cct->_conf.get_val<uint64_t>("rgw_reshard_progress_judge_interval");
+ // avoid getting reshard_lock simultaneously by mass differrent operation
+ reshard_progress_judge_interval +=
+ reshard_progress_judge_interval * cct->_conf.get_val<double>("rgw_reshard_progress_judge_ratio") * r;
+ if (now - bucket_info.layout.judge_reshard_lock_time >= make_timespan(reshard_progress_judge_interval)) {
+
+ map<string, bufferlist> bucket_attrs;
+ int ret = get_bucket_info(&svc, bucket_info.bucket.tenant, bucket_info.bucket.name,
+ bucket_info, nullptr, y, dpp, &bucket_attrs);
+ if (ret < 0) {
+ ldpp_dout(dpp, 0) << __func__ <<
+ " ERROR: failed to refresh bucket info : " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ if (bucket_info.layout.resharding == rgw::BucketReshardState::InLogrecord &&
+ now - bucket_info.layout.judge_reshard_lock_time >= make_timespan(reshard_progress_judge_interval))
+ return reshard_failed_while_logrecord(bucket_info, bucket_attrs, y, dpp);
+ }
+ return 0;
+}
+
+int RGWRados::reshard_failed_while_logrecord(RGWBucketInfo& bucket_info,
+ map<string, bufferlist>& bucket_attrs,
+ optional_yield y,
+ const DoutPrefixProvider *dpp)
+{
+ RGWBucketReshardLock reshard_lock(this->driver, bucket_info, true);
+ int ret = reshard_lock.lock(dpp);
+ if (ret < 0) {
+ ldpp_dout(dpp, 20) << __func__ <<
+ " INFO: failed to take reshard lock for bucket " <<
+ bucket_info.bucket.bucket_id << "; expected if resharding underway" << dendl;
+ // update the judge time
+ bucket_info.layout.judge_reshard_lock_time = real_clock::now();
+ ret = put_bucket_instance_info(bucket_info, false, real_time(), &bucket_attrs, dpp, y);
+ if (ret < 0) {
+ ldpp_dout(dpp, 0) << "RGWReshard::" << __func__ <<
+ " ERROR: error putting bucket instance info: " << cpp_strerror(-ret) << dendl;
+ }
+ } else {
+ ldpp_dout(dpp,20) << __func__ << ": reshard lock success, " <<
+ "that means the reshard has failed for bucekt " << bucket_info.bucket.bucket_id << dendl;
+ // clear the RESHARD_IN_PROGRESS status after reshard failed, also set bucket instance
+ // status to CLS_RGW_RESHARD_NONE
+ ret = RGWBucketReshard::clear_resharding(this->driver, bucket_info, bucket_attrs, dpp, y);
+ reshard_lock.unlock();
+ if (ret < 0) {
+ ldpp_dout(dpp, 0) << __func__ <<
+ " ERROR: failed to clear resharding flags for bucket " <<
+ bucket_info.bucket.bucket_id << dendl;
+ } else {
+ ldpp_dout(dpp, 5) << __func__ <<
+ " INFO: apparently successfully cleared resharding flags for "
+ "bucket " << bucket_info.bucket.bucket_id << dendl;
+ } // if clear resharding succeeded
+ } // if taking of lock succeeded
+ return 0;
+}
int RGWRados::block_while_resharding(RGWRados::BucketShard *bs,
const rgw_obj& obj_instance,
const rgw_obj& obj_instance,
RGWBucketInfo& bucket_info,
std::function<int(BucketShard *)> call, optional_yield y);
+ /* clear the progress flag when reshard failed */
+ int reshard_failed_while_logrecord(RGWBucketInfo& bucket_info, optional_yield y,
+ const DoutPrefixProvider *dpp);
+ int reshard_failed_while_logrecord(RGWBucketInfo& bucket_info,
+ std::map<std::string, bufferlist>& bucket_attrs,
+ optional_yield y,
+ const DoutPrefixProvider *dpp);
int block_while_resharding(RGWRados::BucketShard *bs,
const rgw_obj& obj_instance,
RGWBucketInfo& bucket_info,
bucket_info.layout.target_index = target;
bucket_info.layout.resharding = rgw::BucketReshardState::InLogrecord;
+ // update the judge time meanwhile
+ bucket_info.layout.judge_reshard_lock_time = ceph::real_clock::now();
if (ret = fault.check("set_target_layout");
ret == 0) { // no fault injected, write the bucket instance metadata
ret = store->getRados()->put_bucket_instance_info(bucket_info, false,
#include <boost/algorithm/string.hpp>
#include "rgw_bucket_layout.h"
+#include "include/utime.h"
namespace rgw {
// BucketLayout
void encode(const BucketLayout& l, bufferlist& bl, uint64_t f)
{
- ENCODE_START(2, 1, bl);
+ ENCODE_START(3, 1, bl);
encode(l.resharding, bl);
encode(l.current_index, bl);
encode(l.target_index, bl);
encode(l.logs, bl);
+ encode(l.judge_reshard_lock_time, bl);
ENCODE_FINISH(bl);
}
void decode(BucketLayout& l, bufferlist::const_iterator& bl)
{
- DECODE_START(2, bl);
+ DECODE_START(3, bl);
decode(l.resharding, bl);
decode(l.current_index, bl);
decode(l.target_index, bl);
} else {
decode(l.logs, bl);
}
+ if (struct_v >= 3) {
+ decode(l.judge_reshard_lock_time, bl);
+ }
DECODE_FINISH(bl);
}
void encode_json_impl(const char *name, const BucketLayout& l, ceph::Formatter *f)
for (const auto& log : l.logs) {
encode_json("log", log, f);
}
+ utime_t jt(l.judge_reshard_lock_time);
+ encode_json("judge_reshard_lock_time", jt, f);
f->close_section(); // logs[]
f->close_section();
}
JSONDecoder::decode_json("current_index", l.current_index, obj);
JSONDecoder::decode_json("target_index", l.target_index, obj);
JSONDecoder::decode_json("logs", l.logs, obj);
+ utime_t ut;
+ JSONDecoder::decode_json("judge_reshard_lock_time", ut, obj);
+ l.judge_reshard_lock_time = ut.to_real_time();
}
} // namespace rgw
// generation at the back()
std::vector<bucket_log_layout_generation> logs;
+ // via this time to judge if the bucket is resharding, when the reshard status
+ // of bucket changed or the reshard status is read, this time will be updated
+ ceph::real_time judge_reshard_lock_time;
+
friend std::ostream& operator<<(std::ostream& out, const BucketLayout& l) {
std::stringstream ss;
if (l.target_index) {
}
out << "resharding=" << to_string(l.resharding) <<
", current_index=[" << l.current_index << "], target_index=[" <<
- ss.str() << "], logs.size()=" << l.logs.size();
+ ss.str() << "], logs.size()=" << l.logs.size() <<
+ ", judge_reshard_lock_time=" << l.judge_reshard_lock_time;
return out;
}
encode(empty, bl);
}
ceph::versioned_variant::encode(owner, bl); // v24
-
ENCODE_FINISH(bl);
}