From fcfc69d049ced87a2d33564b1a52350e4f9fcb10 Mon Sep 17 00:00:00 2001 From: Shilpa Jagannath Date: Fri, 31 Mar 2023 15:33:53 -0400 Subject: [PATCH] rgw/archive: avoid duplicating objects when syncing from multiple zones Signed-off-by: Shilpa Jagannath (cherry picked from commit 74014cf8f7b1311ff3ea0a53b901e2cf3c7251c6) --- src/rgw/driver/rados/rgw_cr_rados.cc | 12 +++++++++++- src/rgw/driver/rados/rgw_cr_rados.h | 16 ++++++++++++---- src/rgw/driver/rados/rgw_data_sync.cc | 17 ++++++++++++++--- src/rgw/driver/rados/rgw_rados.cc | 11 ++++++++--- src/rgw/driver/rados/rgw_rados.h | 2 ++ 5 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/rgw/driver/rados/rgw_cr_rados.cc b/src/rgw/driver/rados/rgw_cr_rados.cc index 996a3758f11..270bf5f8d56 100644 --- a/src/rgw/driver/rados/rgw_cr_rados.cc +++ b/src/rgw/driver/rados/rgw_cr_rados.cc @@ -740,7 +740,15 @@ int RGWAsyncFetchRemoteObj::_send_request(const DoutPrefixProvider *dpp) rgw::sal::RadosBucket dest_bucket(store, dest_bucket_info); rgw::sal::RadosObject dest_obj(store, dest_key.value_or(key), &dest_bucket); - + + rgw_obj stat_dest_obj; + + if (!stat_follow_olh) { + stat_dest_obj = dest_obj.get_obj(); + } else { + stat_dest_obj = src_obj; + } + std::string etag; std::optional bytes_transferred; @@ -772,6 +780,8 @@ int RGWAsyncFetchRemoteObj::_send_request(const DoutPrefixProvider *dpp) NULL, /* void *progress_data*); */ dpp, filter.get(), + stat_follow_olh, + stat_dest_obj, source_trace_entry, &zones_trace, &bytes_transferred); diff --git a/src/rgw/driver/rados/rgw_cr_rados.h b/src/rgw/driver/rados/rgw_cr_rados.h index 7bda18878f4..54d1626b08b 100644 --- a/src/rgw/driver/rados/rgw_cr_rados.h +++ b/src/rgw/driver/rados/rgw_cr_rados.h @@ -1069,6 +1069,7 @@ class RGWAsyncFetchRemoteObj : public RGWAsyncRadosRequest { bool copy_if_newer; std::shared_ptr filter; + bool stat_follow_olh; rgw_zone_set_entry source_trace_entry; rgw_zone_set zones_trace; PerfCounters* counters; @@ -1088,9 +1089,11 @@ public: std::optional _versioned_epoch, bool _if_newer, std::shared_ptr _filter, + bool _stat_follow_olh, const rgw_zone_set_entry& source_trace_entry, rgw_zone_set *_zones_trace, - PerfCounters* counters, const DoutPrefixProvider *dpp) + PerfCounters* counters, + const DoutPrefixProvider *dpp) : RGWAsyncRadosRequest(caller, cn), store(_store), source_zone(_source_zone), user_id(_user_id), @@ -1102,6 +1105,7 @@ public: versioned_epoch(_versioned_epoch), copy_if_newer(_if_newer), filter(_filter), + stat_follow_olh(_stat_follow_olh), source_trace_entry(source_trace_entry), counters(counters), dpp(dpp) @@ -1135,6 +1139,7 @@ class RGWFetchRemoteObjCR : public RGWSimpleCoroutine { std::shared_ptr filter; RGWAsyncFetchRemoteObj *req; + bool stat_follow_olh; const rgw_zone_set_entry& source_trace_entry; rgw_zone_set *zones_trace; PerfCounters* counters; @@ -1152,9 +1157,11 @@ public: std::optional _versioned_epoch, bool _if_newer, std::shared_ptr _filter, + bool _stat_follow_olh, const rgw_zone_set_entry& source_trace_entry, rgw_zone_set *_zones_trace, - PerfCounters* counters, const DoutPrefixProvider *dpp) + PerfCounters* counters, + const DoutPrefixProvider *dpp) : RGWSimpleCoroutine(_store->ctx()), cct(_store->ctx()), async_rados(_async_rados), store(_store), source_zone(_source_zone), @@ -1168,6 +1175,7 @@ public: copy_if_newer(_if_newer), filter(_filter), req(NULL), + stat_follow_olh(_stat_follow_olh), source_trace_entry(source_trace_entry), zones_trace(_zones_trace), counters(counters), dpp(dpp) {} @@ -1185,9 +1193,9 @@ public: int send_request(const DoutPrefixProvider *dpp) override { req = new RGWAsyncFetchRemoteObj(this, stack->create_completion_notifier(), store, - source_zone, user_id, src_bucket, dest_placement_rule, dest_bucket_info, + source_zone, user_id, src_bucket, dest_placement_rule, dest_bucket_info, key, dest_key, versioned_epoch, copy_if_newer, filter, - source_trace_entry, zones_trace, counters, dpp); + stat_follow_olh, source_trace_entry, zones_trace, counters, dpp); async_rados->queue(req); return 0; } diff --git a/src/rgw/driver/rados/rgw_data_sync.cc b/src/rgw/driver/rados/rgw_data_sync.cc index a5730e51d03..8cabe23e8a7 100644 --- a/src/rgw/driver/rados/rgw_data_sync.cc +++ b/src/rgw/driver/rados/rgw_data_sync.cc @@ -2786,6 +2786,7 @@ class RGWObjFetchCR : public RGWCoroutine { rgw_obj_key& key; std::optional dest_key; std::optional versioned_epoch; + bool stat_follow_olh; const rgw_zone_set_entry& source_trace_entry; rgw_zone_set *zones_trace; @@ -2815,6 +2816,7 @@ public: rgw_obj_key& _key, std::optional _dest_key, std::optional _versioned_epoch, + bool _stat_follow_olh, const rgw_zone_set_entry& source_trace_entry, rgw_zone_set *_zones_trace) : RGWCoroutine(_sc->cct), sc(_sc), sync_env(_sc->env), @@ -2822,6 +2824,7 @@ public: key(_key), dest_key(_dest_key), versioned_epoch(_versioned_epoch), + stat_follow_olh(_stat_follow_olh), source_trace_entry(source_trace_entry), zones_trace(_zones_trace) { } @@ -2943,11 +2946,12 @@ public: call(new RGWFetchRemoteObjCR(sync_env->async_rados, sync_env->driver, sc->source_zone, nullopt, - sync_pipe.info.source_bs.bucket, + sync_pipe.source_bucket_info.bucket, std::nullopt, sync_pipe.dest_bucket_info, key, dest_key, versioned_epoch, true, std::static_pointer_cast(filter), + stat_follow_olh, source_trace_entry, zones_trace, sync_env->counters, dpp)); } @@ -2975,7 +2979,8 @@ RGWCoroutine *RGWDefaultDataSyncModule::sync_object(const DoutPrefixProvider *dp const rgw_zone_set_entry& source_trace_entry, rgw_zone_set *zones_trace) { - return new RGWObjFetchCR(sc, sync_pipe, key, std::nullopt, versioned_epoch, + bool stat_follow_olh = false; + return new RGWObjFetchCR(sc, sync_pipe, key, std::nullopt, versioned_epoch, stat_follow_olh, source_trace_entry, zones_trace); } @@ -3052,10 +3057,16 @@ RGWCoroutine *RGWArchiveDataSyncModule::sync_object(const DoutPrefixProvider *dp } std::optional dest_key; + bool stat_follow_olh = false; + if (versioned_epoch.value_or(0) == 0) { /* force version if not set */ + stat_follow_olh = true; versioned_epoch = 0; dest_key = key; + if (key.instance.empty()) { + sync_env->driver->getRados()->gen_rand_obj_instance_name(&(*dest_key)); + } } if (key.instance.empty()) { @@ -3064,7 +3075,7 @@ RGWCoroutine *RGWArchiveDataSyncModule::sync_object(const DoutPrefixProvider *dp } return new RGWObjFetchCR(sc, sync_pipe, key, dest_key, versioned_epoch, - source_trace_entry, zones_trace); + stat_follow_olh, source_trace_entry, zones_trace); } RGWCoroutine *RGWArchiveDataSyncModule::remove_object(const DoutPrefixProvider *dpp, RGWDataSyncCtx *sc, rgw_bucket_sync_pipe& sync_pipe, rgw_obj_key& key, diff --git a/src/rgw/driver/rados/rgw_rados.cc b/src/rgw/driver/rados/rgw_rados.cc index c4f34aeed86..4907a20b182 100644 --- a/src/rgw/driver/rados/rgw_rados.cc +++ b/src/rgw/driver/rados/rgw_rados.cc @@ -3904,6 +3904,8 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx, void *progress_data, const DoutPrefixProvider *dpp, RGWFetchObjFilter *filter, + bool stat_follow_olh, + const rgw_obj& stat_dest_obj, const rgw_zone_set_entry& source_trace_entry, rgw_zone_set *zones_trace, std::optional* bytes_transferred) @@ -4005,7 +4007,7 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx, if (copy_if_newer) { /* need to get mtime for destination */ - ret = get_obj_state(dpp, &obj_ctx, dest_bucket_info, dest_obj, &dest_state, &manifest, false, null_yield); + ret = get_obj_state(dpp, &obj_ctx, dest_bucket_info, stat_dest_obj, &dest_state, &manifest, stat_follow_olh, null_yield); if (ret < 0) goto set_err_state; @@ -4209,7 +4211,7 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx, if (copy_if_newer && canceled) { ldpp_dout(dpp, 20) << "raced with another write of obj: " << dest_obj << dendl; obj_ctx.invalidate(dest_obj); /* object was overwritten */ - ret = get_obj_state(dpp, &obj_ctx, dest_bucket_info, dest_obj, &dest_state, &manifest, false, null_yield); + ret = get_obj_state(dpp, &obj_ctx, dest_bucket_info, stat_dest_obj, &dest_state, &manifest, stat_follow_olh, null_yield); if (ret < 0) { ldpp_dout(dpp, 0) << "ERROR: " << __func__ << ": get_err_state() returned ret=" << ret << dendl; goto set_err_state; @@ -4347,6 +4349,9 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx, bool remote_src; bool remote_dest; + bool stat_follow_olh = false; + rgw_obj stat_dest_obj = dest_obj; + append_rand_alpha(cct, dest_obj.get_oid(), shadow_oid, 32); shadow_obj.init_ns(dest_obj.bucket, shadow_oid, shadow_ns); @@ -4370,7 +4375,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx, unmod_ptr, high_precision_time, if_match, if_nomatch, attrs_mod, copy_if_newer, attrs, category, olh_epoch, delete_at, ptag, petag, progress_cb, progress_data, dpp, - nullptr /* filter */, source_trace_entry); + nullptr /* filter */, stat_follow_olh, stat_dest_obj, source_trace_entry); } map src_attrs; diff --git a/src/rgw/driver/rados/rgw_rados.h b/src/rgw/driver/rados/rgw_rados.h index d77dd5c5f4d..e99726132a4 100644 --- a/src/rgw/driver/rados/rgw_rados.h +++ b/src/rgw/driver/rados/rgw_rados.h @@ -1140,6 +1140,8 @@ public: void *progress_data, const DoutPrefixProvider *dpp, RGWFetchObjFilter *filter, + bool stat_follow_olh, + const rgw_obj& stat_dest_obj, const rgw_zone_set_entry& source_trace_entry, rgw_zone_set *zones_trace = nullptr, std::optional* bytes_transferred = 0); -- 2.39.5