From a537029a6574359115c505857336f9b04ff19352 Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Fri, 29 Mar 2019 10:27:56 -0400 Subject: [PATCH] rgw: data sync checks empty next_marker for datalog RGWReadRemoteDataLogShardCR tracks the marker and next_marker separately, because next_marker will be empty when it reaches the end this allows RGWDataSyncShardCR to avoid clearing its sync_marker and restarting datalog listing from the beginning Fixes: http://tracker.ceph.com/issues/39033 Signed-off-by: Casey Bodley (cherry picked from commit 2ff63778342282ab5c676529f6e7d90f30e6da1a) Conflicts: src/rgw/rgw_data_sync.cc: no sync tracing --- src/rgw/rgw_data_sync.cc | 50 ++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/src/rgw/rgw_data_sync.cc b/src/rgw/rgw_data_sync.cc index 1efb1876d3e60..4e94b75434470 100644 --- a/src/rgw/rgw_data_sync.cc +++ b/src/rgw/rgw_data_sync.cc @@ -308,24 +308,24 @@ struct read_remote_data_log_response { class RGWReadRemoteDataLogShardCR : public RGWCoroutine { RGWDataSyncEnv *sync_env; - RGWRESTReadResource *http_op; + RGWRESTReadResource *http_op = nullptr; int shard_id; - string *pmarker; + const std::string& marker; + string *pnext_marker; list *entries; bool *truncated; read_remote_data_log_response response; public: - RGWReadRemoteDataLogShardCR(RGWDataSyncEnv *_sync_env, - int _shard_id, string *_pmarker, list *_entries, bool *_truncated) : RGWCoroutine(_sync_env->cct), - sync_env(_sync_env), - http_op(NULL), - shard_id(_shard_id), - pmarker(_pmarker), - entries(_entries), - truncated(_truncated) { + RGWReadRemoteDataLogShardCR(RGWDataSyncEnv *_sync_env, int _shard_id, + const std::string& marker, string *pnext_marker, + list *_entries, + bool *_truncated) + : RGWCoroutine(_sync_env->cct), sync_env(_sync_env), + shard_id(_shard_id), marker(marker), pnext_marker(pnext_marker), + entries(_entries), truncated(_truncated) { } ~RGWReadRemoteDataLogShardCR() override { if (http_op) { @@ -340,7 +340,7 @@ public: snprintf(buf, sizeof(buf), "%d", shard_id); rgw_http_param_pair pairs[] = { { "type" , "data" }, { "id", buf }, - { "marker", pmarker->c_str() }, + { "marker", marker.c_str() }, { "extra-info", "true" }, { NULL, NULL } }; @@ -366,7 +366,7 @@ public: } entries->clear(); entries->swap(response.entries); - *pmarker = response.marker; + *pnext_marker = response.marker; *truncated = response.truncated; return set_cr_done(); } @@ -1112,6 +1112,7 @@ class RGWDataSyncShardCR : public RGWCoroutine { RGWDataSyncShardMarkerTrack *marker_tracker; + std::string next_marker; list log_entries; list::iterator log_iter; bool truncated; @@ -1158,7 +1159,7 @@ class RGWDataSyncShardCR : public RGWCoroutine { public: RGWDataSyncShardCR(RGWDataSyncEnv *_sync_env, rgw_pool& _pool, - uint32_t _shard_id, rgw_data_sync_marker& _marker, bool *_reset_backoff) : RGWCoroutine(_sync_env->cct), + uint32_t _shard_id, const rgw_data_sync_marker& _marker, bool *_reset_backoff) : RGWCoroutine(_sync_env->cct), sync_env(_sync_env), pool(_pool), shard_id(_shard_id), @@ -1389,7 +1390,8 @@ public: #define INCREMENTAL_MAX_ENTRIES 100 ldout(sync_env->cct, 20) << __func__ << ":" << __LINE__ << ": shard_id=" << shard_id << " sync_marker=" << sync_marker.marker << dendl; spawned_keys.clear(); - yield call(new RGWReadRemoteDataLogShardCR(sync_env, shard_id, &sync_marker.marker, &log_entries, &truncated)); + yield call(new RGWReadRemoteDataLogShardCR(sync_env, shard_id, sync_marker.marker, + &next_marker, &log_entries, &truncated)); if (retcode < 0) { ldout(sync_env->cct, 0) << "ERROR: failed to read remote data log info: ret=" << retcode << dendl; stop_spawned_services(); @@ -1432,11 +1434,17 @@ public: } /* not waiting for child here */ } - } - ldout(sync_env->cct, 20) << __func__ << ":" << __LINE__ << ": shard_id=" << shard_id << " sync_marker=" << sync_marker.marker << " truncated=" << truncated << dendl; - if (!truncated) { - yield wait(get_idle_interval()); - } + } + ldout(sync_env->cct, 20) << __func__ << ":" << __LINE__ << ": shard_id=" << shard_id << " sync_marker=" << sync_marker.marker + << " next_marker=" << next_marker << " truncated=" << truncated << dendl; + if (!truncated) { + yield wait(get_idle_interval()); + } + if (!next_marker.empty()) { + sync_marker.marker = next_marker; + } else if (!log_entries.empty()) { + sync_marker.marker = log_entries.back().log_id; + } } while (true); } return 0; @@ -2088,6 +2096,7 @@ class RGWReadPendingBucketShardsCoroutine : public RGWCoroutine { rgw_data_sync_marker* sync_marker; int count; + std::string next_marker; list log_entries; bool truncated; @@ -2123,7 +2132,8 @@ int RGWReadPendingBucketShardsCoroutine::operate() marker = sync_marker->marker; count = 0; do{ - yield call(new RGWReadRemoteDataLogShardCR(sync_env, shard_id, &marker, &log_entries, &truncated)); + yield call(new RGWReadRemoteDataLogShardCR(sync_env, shard_id, marker, + &next_marker, &log_entries, &truncated)); if (retcode == -ENOENT) { break; -- 2.39.5