From: Zhi Zhang Date: Tue, 12 Sep 2017 06:49:31 +0000 (+0800) Subject: tools/ceph-objectstore-tool: split filestore directories offline to target hash level X-Git-Tag: v13.0.1~884^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=e71659b11a54ea3abdb047d2ec480bd855acee4a;p=ceph-ci.git tools/ceph-objectstore-tool: split filestore directories offline to target hash level Currently ceph-objectstore-tool can only split dirs that already meet the usual object number criteria. It won't reduce the cost of online split for those dirs that would meet the criteria online. This change uses 'arg1' option for apply-layout-settings to specify the target hash level wants to split to. Then dirs will be split offline no matters how many objects they have. This also helps those pools that forgot to do pre-splitting at their creation time. Signed-off-by: Zhi Zhang --- diff --git a/src/os/filestore/CollectionIndex.h b/src/os/filestore/CollectionIndex.h index 7c57a38b564..c5d120e1acc 100644 --- a/src/os/filestore/CollectionIndex.h +++ b/src/os/filestore/CollectionIndex.h @@ -191,7 +191,7 @@ protected: uint64_t expected_num_objs ///< [in] expected number of objects this collection has ) { ceph_abort(); return 0; } - virtual int apply_layout_settings() { ceph_abort(); return 0; } + virtual int apply_layout_settings(int target_level) { ceph_abort(); return 0; } /// Read index-wide settings (should be called after construction) virtual int read_settings() { return 0; } diff --git a/src/os/filestore/FileStore.cc b/src/os/filestore/FileStore.cc index a056972d8a8..ed1e6c3eb7f 100644 --- a/src/os/filestore/FileStore.cc +++ b/src/os/filestore/FileStore.cc @@ -5952,9 +5952,10 @@ uint64_t FileStore::estimate_objects_overhead(uint64_t num_objects) return res; } -int FileStore::apply_layout_settings(const coll_t &cid) +int FileStore::apply_layout_settings(const coll_t &cid, int target_level) { - dout(20) << __FUNC__ << ": " << cid << dendl; + dout(20) << __FUNC__ << ": " << cid << " target level: " + << target_level << dendl; Index index; int r = get_index(cid, &index); if (r < 0) { @@ -5963,7 +5964,7 @@ int FileStore::apply_layout_settings(const coll_t &cid) return r; } - return index->apply_layout_settings(); + return index->apply_layout_settings(target_level); } diff --git a/src/os/filestore/FileStore.h b/src/os/filestore/FileStore.h index 617796c533f..a4e7d066d6c 100644 --- a/src/os/filestore/FileStore.h +++ b/src/os/filestore/FileStore.h @@ -733,7 +733,7 @@ public: void dump_stop(); void dump_transactions(vector& ls, uint64_t seq, OpSequencer *osr); - virtual int apply_layout_settings(const coll_t &cid); + virtual int apply_layout_settings(const coll_t &cid, int target_level); private: void _inject_failure(); diff --git a/src/os/filestore/HashIndex.cc b/src/os/filestore/HashIndex.cc index e0d38f4bdc2..a36a164b03a 100644 --- a/src/os/filestore/HashIndex.cc +++ b/src/os/filestore/HashIndex.cc @@ -307,8 +307,9 @@ int HashIndex::_split( &mkdirred); } -int HashIndex::split_dirs(const vector &path) { - dout(20) << __func__ << " " << path << dendl; +int HashIndex::split_dirs(const vector &path, int target_level) { + dout(20) << __func__ << " " << path << " target level: " + << target_level << dendl; subdir_info_s info; int r = get_info(path, &info); if (r < 0) { @@ -317,9 +318,10 @@ int HashIndex::split_dirs(const vector &path) { return r; } - if (must_split(info)) { + if (must_split(info, target_level)) { dout(1) << __func__ << " " << path << " has " << info.objs - << " objects, starting split." << dendl; + << " objects, " << info.hash_level + << " level, starting split." << dendl; r = initiate_split(path, info); if (r < 0) { dout(10) << "error initiating split on " << path << ": " @@ -348,7 +350,7 @@ int HashIndex::split_dirs(const vector &path) { it != subdirs.end(); ++it) { vector subdir_path(path); subdir_path.push_back(*it); - r = split_dirs(subdir_path); + r = split_dirs(subdir_path, target_level); if (r < 0) { return r; } @@ -357,16 +359,17 @@ int HashIndex::split_dirs(const vector &path) { return r; } -int HashIndex::apply_layout_settings() { +int HashIndex::apply_layout_settings(int target_level) { vector path; dout(10) << __func__ << " split multiple = " << split_multiplier << " merge threshold = " << merge_threshold << " split rand factor = " << cct->_conf->filestore_split_rand_factor + << " target level = " << target_level << dendl; int r = write_settings(); if (r < 0) return r; - return split_dirs(path); + return split_dirs(path, target_level); } int HashIndex::_init() { @@ -741,10 +744,13 @@ bool HashIndex::must_merge(const subdir_info_s &info) { info.subdirs == 0); } -bool HashIndex::must_split(const subdir_info_s &info) { +bool HashIndex::must_split(const subdir_info_s &info, int target_level) { + // target_level is used for ceph-objectstore-tool to split dirs offline. + // if it is set (defalult is 0) and current hash level < target_level, + // this dir would be split no matters how many objects it has. return (info.hash_level < (unsigned)MAX_HASH_LEVEL && - info.objs > ((unsigned)(abs(merge_threshold) * split_multiplier + settings.split_rand_factor) * 16)); - + ((target_level > 0 && info.hash_level < (unsigned)target_level) || + (info.objs > ((unsigned)(abs(merge_threshold) * split_multiplier + settings.split_rand_factor) * 16)))); } int HashIndex::initiate_merge(const vector &path, subdir_info_s info) { diff --git a/src/os/filestore/HashIndex.h b/src/os/filestore/HashIndex.h index 216659bff4d..db76abbb4d4 100644 --- a/src/os/filestore/HashIndex.h +++ b/src/os/filestore/HashIndex.h @@ -189,7 +189,7 @@ public: ) override; /// @see CollectionIndex - int apply_layout_settings() override; + int apply_layout_settings(int target_level) override; protected: int _init() override; @@ -272,7 +272,8 @@ private: /// Encapsulates logic for when to merge. bool must_split( - const subdir_info_s &info ///< [in] Info to check + const subdir_info_s &info, ///< [in] Info to check + int target_level = 0 ); /// @return True if info must be split, False otherwise /// Initiates merge @@ -436,7 +437,7 @@ private: int recursive_create_path(vector& path, int level); /// split each dir below the given path - int split_dirs(const vector &path); + int split_dirs(const vector &path, int target_level = 0); int write_settings(); }; diff --git a/src/tools/ceph_objectstore_tool.cc b/src/tools/ceph_objectstore_tool.cc index a1b78a9db3e..e39ba10f198 100644 --- a/src/tools/ceph_objectstore_tool.cc +++ b/src/tools/ceph_objectstore_tool.cc @@ -2446,7 +2446,8 @@ int mydump_journal(Formatter *f, string journalpath, bool m_journal_dio) } int apply_layout_settings(ObjectStore *os, const OSDSuperblock &superblock, - const string &pool_name, const spg_t &pgid, bool dry_run) + const string &pool_name, const spg_t &pgid, bool dry_run, + int target_level) { int r = 0; @@ -2496,7 +2497,7 @@ int apply_layout_settings(ObjectStore *os, const OSDSuperblock &superblock, cerr << "Would apply layout settings to " << coll << std::endl; } else { cerr << "Finished " << done << "/" << total << " collections" << "\r"; - r = fs->apply_layout_settings(coll); + r = fs->apply_layout_settings(coll, target_level); if (r < 0) { cerr << "Error applying layout settings to " << coll << std::endl; return r; @@ -2566,7 +2567,8 @@ int main(int argc, char **argv) positional.add_options() ("object", po::value(&object), "'' for pgmeta_oid, object name or ghobject in json") ("objcmd", po::value(&objcmd), "command [(get|set)-bytes, (get|set|rm)-(attr|omap), (get|set)-omaphdr, list-attrs, list-omap, remove]") - ("arg1", po::value(&arg1), "arg1 based on cmd") + ("arg1", po::value(&arg1), "arg1 based on cmd, " + "for apply-layout-settings: target hash level split to") ("arg2", po::value(&arg2), "arg2 based on cmd") ("test-align", po::value(&testalign)->default_value(0), "hidden align option for testing") ; @@ -2907,7 +2909,11 @@ int main(int argc, char **argv) } if (op == "apply-layout-settings") { - ret = apply_layout_settings(fs, superblock, pool, pgid, dry_run); + int target_level = 0; + if (vm.count("arg1") && isdigit(arg1[0])) { + target_level = atoi(arg1.c_str()); + } + ret = apply_layout_settings(fs, superblock, pool, pgid, dry_run, target_level); goto out; }