static RGWMetadataTopHandler md_top_handler;
RGWMetadataManager::RGWMetadataManager(CephContext *_cct, RGWRados *_store)
- : cct(_cct), store(_store), md_log(nullptr)
+ : cct(_cct), store(_store)
{
}
}
handlers.clear();
- delete md_log;
}
int RGWMetadataManager::init(const std::string& current_period)
{
- md_log = new RGWMetadataLog(cct, store, current_period);
+ current_log = get_log(current_period);
return 0;
}
-int RGWMetadataManager::store_md_log_entries(list<cls_log_entry>& entries, int shard_id, librados::AioCompletion *completion)
+RGWMetadataLog* RGWMetadataManager::get_log(const std::string& period)
{
+ // construct the period's log in place if it doesn't exist
+ auto insert = md_logs.emplace(std::piecewise_construct,
+ std::forward_as_tuple(period),
+ std::forward_as_tuple(cct, store, period));
+ return &insert.first->second;
+}
+
+int RGWMetadataManager::store_md_log_entries(list<cls_log_entry>& entries,
+ const std::string& period, int shard_id,
+ librados::AioCompletion *completion)
+{
+ auto md_log = get_log(period);
return md_log->store_entries_in_shard(entries, shard_id, completion);
}
bufferlist logbl;
::encode(log_data, logbl);
- int ret = md_log->add_entry(handler, section, key, logbl);
+ assert(current_log); // must have called init()
+ int ret = current_log->add_entry(handler, section, key, logbl);
if (ret < 0)
return ret;
bufferlist logbl;
::encode(log_data, logbl);
- int r = md_log->add_entry(handler, section, key, logbl);
+ assert(current_log); // must have called init()
+ int r = current_log->add_entry(handler, section, key, logbl);
if (ret < 0)
return ret;
map<string, RGWMetadataHandler *> handlers;
CephContext *cct;
RGWRados *store;
- RGWMetadataLog *md_log;
+
+ // maintain a separate metadata log for each period
+ std::map<std::string, RGWMetadataLog> md_logs;
+ // use the current period's log for mutating operations
+ RGWMetadataLog* current_log = nullptr;
void parse_metadata_key(const string& metadata_key, string& type, string& entry);
int init(const std::string& current_period);
+ /// find or create the metadata log for the given period
+ RGWMetadataLog* get_log(const std::string& period);
+
int register_handler(RGWMetadataHandler *handler);
RGWMetadataHandler *get_handler(const string& type);
- int store_md_log_entries(list<cls_log_entry>& entries, int shard_id, librados::AioCompletion *completion);
+ int store_md_log_entries(list<cls_log_entry>& entries, const std::string& period,
+ int shard_id, librados::AioCompletion *completion);
int put_entry(RGWMetadataHandler *handler, const string& key, bufferlist& bl, bool exclusive,
RGWObjVersionTracker *objv_tracker, time_t mtime, map<string, bufferlist> *pattrs = NULL);
int lock_exclusive(string& metadata_key, utime_t duration, string& owner_id);
int unlock(string& metadata_key, string& owner_id);
- RGWMetadataLog *get_log() { return md_log; }
-
- int get_log_shard_id(const string& section, const string& key, int *shard_id) {
+ int get_log_shard_id(const string& section, const std::string& period,
+ const string& key, int *shard_id) {
RGWMetadataHandler *handler = get_handler(section);
if (!handler) {
return -EINVAL;
}
-
+ auto md_log = get_log(period);
*shard_id = md_log->get_log_shard_id(handler, section, key);
-
return 0;
}
};
return -EINVAL;
}
- auto mdlog = store->meta_mgr->get_log();
+ auto mdlog = store->meta_mgr->get_log(get_id());
const auto num_shards = cct->_conf->rgw_md_log_max_shards;
std::vector<std::string> markers;
class RGWMetaNotifier : public RGWRadosThread {
RGWMetaNotifierManager notify_mgr;
+ RGWMetadataLog *const log;
uint64_t interval_msec() {
return cct->_conf->rgw_md_notify_interval_msec;
}
public:
- RGWMetaNotifier(RGWRados *_store) : RGWRadosThread(_store), notify_mgr(_store) {}
+ RGWMetaNotifier(RGWRados *_store, RGWMetadataLog* log)
+ : RGWRadosThread(_store), notify_mgr(_store), log(log) {}
int process();
};
{
set<int> shards;
- RGWMetadataLog *log = store->meta_mgr->get_log();
-
log->read_clear_modified(shards);
if (shards.empty()) {
period_history.reset(new RGWPeriodHistory(cct, period_puller.get(),
current_period));
- ret = meta_mgr->init(current_period.get_id());
- if (ret < 0) {
- lderr(cct) << "ERROR: failed to initialize metadata log: "
- << cpp_strerror(-ret) << dendl;
- return ret;
- }
-
if (need_watch_notify()) {
ret = init_watch();
if (ret < 0) {
obj_expirer->start_processor();
}
- meta_notifier = new RGWMetaNotifier(this);
+ ret = meta_mgr->init(current_period.get_id());
+ if (ret < 0) {
+ lderr(cct) << "ERROR: failed to initialize metadata log: "
+ << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ auto md_log = meta_mgr->get_log(current_period.get_id());
+
+ meta_notifier = new RGWMetaNotifier(this, md_log);
if (is_meta_master()) {
meta_notifier->start();
}