OPTION(rgw_curl_wait_timeout_ms, OPT_INT, 1000) // timeout for certain curl calls
OPTION(rgw_copy_obj_progress, OPT_BOOL, true) // should dump progress during long copy operations?
OPTION(rgw_copy_obj_progress_every_bytes, OPT_INT, 1024 * 1024) // min bytes between copy progress output
+OPTION(rgw_obj_tombstone_cache_size, OPT_INT, 1000) // how many objects in tombstone cache, which is used in multi-zone sync to keep
+ // track of removed objects' mtime
OPTION(rgw_data_log_window, OPT_INT, 30) // data log entries window (in seconds)
OPTION(rgw_data_log_changes_size, OPT_INT, 1000) // number of in-memory entries to hold for data changes log
cr_registry->put();
}
delete binfo_cache;
+ delete obj_tombstone_cache;
}
/**
binfo_cache = new RGWChainedCacheImpl<bucket_info_entry>;
binfo_cache->init(this);
+ bool need_tombstone_cache = !zone_conn_map.empty();
+
+ if (need_tombstone_cache) {
+ obj_tombstone_cache = new tombstone_cache_t(cct->_conf->rgw_obj_tombstone_cache_size);
+ }
+
return ret;
}
if (ret < 0)
return ret;
- if (dest_state->exists) {
+ if (!real_clock::is_zero(dest_state->mtime)) {
dest_mtime_weight.init(dest_state);
pmod = &dest_mtime_weight.mtime;
}
int64_t poolid = ref.ioctx.get_id();
if (r >= 0) {
+ tombstone_cache_t *obj_tombstone_cache = store->get_tombstone_cache();
+ pair<ceph::real_time, uint32_t> tombstone_entry = make_pair<>(state->mtime, state->zone_short_id);
+ if (obj_tombstone_cache) {
+ obj_tombstone_cache->add(obj, tombstone_entry);
+ }
r = index_op.complete_del(poolid, ref.ioctx.get_last_version(), state->mtime, params.remove_objs);
} else {
int ret = index_op.cancel();
if (r == -ENOENT) {
s->exists = false;
s->has_attrs = true;
- s->mtime = real_time();
+ pair<ceph::real_time, uint32_t> tombstone_entry;
+ if (obj_tombstone_cache && obj_tombstone_cache->find(obj, tombstone_entry)) {
+ s->mtime = tombstone_entry.first;
+ s->zone_short_id = tombstone_entry.second;
+ ldout(cct, 20) << __func__ << "(): found obj in tombstone cache: obj=" << obj << " mtime=" << s->mtime << dendl;
+ } else {
+ s->mtime = real_time();
+ }
return 0;
}
if (r < 0)
#include "common/RefCountedObj.h"
#include "common/RWLock.h"
#include "common/ceph_time.h"
+#include "common/lru_map.h"
#include "rgw_common.h"
#include "cls/rgw/cls_rgw_types.h"
#include "cls/version/cls_version_types.h"
using RGWChainedCacheImpl_bucket_info_entry = RGWChainedCacheImpl<bucket_info_entry>;
RGWChainedCacheImpl_bucket_info_entry *binfo_cache;
+ using tombstone_cache_t = lru_map<rgw_obj, pair<ceph::real_time, uint32_t> >;
+ tombstone_cache_t *obj_tombstone_cache;
+
librados::IoCtx gc_pool_ctx; // .rgw.gc
librados::IoCtx objexp_pool_ctx;
max_bucket_id(0), cct(NULL),
next_rados_handle(0),
handle_lock("rados_handle_lock"),
- binfo_cache(NULL),
+ binfo_cache(NULL), obj_tombstone_cache(nullptr),
pools_initialized(false),
quota_handler(NULL),
finisher(NULL),
virtual ~RGWRados() = default;
+ tombstone_cache_t *get_tombstone_cache() {
+ return obj_tombstone_cache;
+ }
+
int get_required_alignment(rgw_bucket& bucket, uint64_t *alignment);
int get_max_chunk_size(rgw_bucket& bucket, uint64_t *max_chunk_size);