基于H版本ceph修改:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
diff --git a/src/test/encoding/ceph_dencoder.cc b/src/test/encoding/ceph_dencoder.cc index 7e10565..129d399 100644 --- a/src/test/encoding/ceph_dencoder.cc +++ b/src/test/encoding/ceph_dencoder.cc @@ -46,9 +46,12 @@ void usage(ostream &out) out < < "\n"; out << " count_tests print number of generated test objects (to stdout)\n"; out << " select_test <n> select generated test object as in-memory object\n"; + out < < " editsb <oldest_map> <input sb file/> <output sb file> edit OSDSuperblock oldest_map section\n"; } struct Dencoder { virtual ~Dencoder() {} + virtual void editsb(epoch_t oldest) {} virtual string decode(bufferlist bl, uint64_t seek) = 0; virtual void encode(bufferlist& out, uint64_t features) = 0; virtual void dump(ceph::Formatter *f) = 0; @@ -147,6 +150,15 @@ public: } }; +class DencoderOSDSuperblock : public DencoderImplNoFeature<osdsuperblock> { +public: + DencoderOSDSuperblock() + : DencoderImplNoFeature</osdsuperblock><osdsuperblock>(false) {} + void editsb(epoch_t oldest) { m_object->oldest_map = oldest; } +}; + template<class T> class DencoderImplFeatureful : public DencoderBase<t> { public: @@ -401,6 +413,49 @@ int main(int argc, const char **argv) } int n = atoi(*i); err = den->select_generated(n); + } else if (*i++ == string("editsb")) { + if (args.size() < 4) { + usage(cerr); + exit(1); + } + // new oldest_map epoch value + epoch_t oldest(atoi(*i++)); + // input file + int r = encbl.read_file(*i++, &err); + if (r < 0) { + cerr << "error reading " << *i << ": " << err << std::endl; + exit(1); + } + + // edit oldest_map value + den = new DencoderOSDSuperblock(); + den->generate(); + err = den->decode(encbl, 0); + den->editsb(oldest); + den->encode(encbl, features | CEPH_FEATURE_RESERVED); + + // output file + int fd = ::open(*i, O_WRONLY|O_CREAT|O_TRUNC, 0644); + if (fd < 0) { + cerr << "error opening " << *i << " for write: " << cpp_strerror(errno) << std::endl; + exit(1); + } + r = encbl.write_fd(fd); + if (r < 0) { + cerr << "error writing " << *i << ": " << cpp_strerror(errno) << std::endl; + exit(1); + } + ::close(fd); + + // dump json + JSONFormatter jf(true); + jf.open_object_section("object"); + den->dump(&jf); + jf.close_section(); + jf.flush(cout); + cout << std::endl; } else { cerr << "unknown option '" << *i << "'" << std::endl; usage(cerr); |
改动原因,查询线上环境OSD使用容量信息,发现osdmap占用了大量空间:
OLDEST MAP: 16986
NEWEST MAP: 235999
可以看到osd保存了235999-16986=219013左右的osdmap,占用了大量空间,200~300G可能
社区相关的tracker:
http://tracker.ceph.com/issues/13990
临时清理方案:
清理方案
1.ceph pg query $pgid确认osd上的最老的pg epoch版本
2.停止osd
3.find和读取superblock
find $OSDPATH/current/meta -name “osd\usuperblock*”
ceph-dencoder import $superblock type OSDSuperblock decode dump_json
确认oldestmap和newestmap
4.使用修改过的ceph-dencoder工具修改oldestmap
5.更新superblock,启动osd
6.观察一会儿无问题,清理老的osdmap
完整解决方案:合入社区修复补丁