From 57c6a79136a390c74a800d03bc595f3363718c2f Mon Sep 17 00:00:00 2001 From: Igor Fedotov Date: Fri, 30 Aug 2019 18:04:21 +0300 Subject: [PATCH] test/store_test: test coverage for anti-spillover framework. Signed-off-by: Igor Fedotov --- src/os/bluestore/BlueFS.h | 3 + src/os/bluestore/BlueStore.h | 3 + src/test/objectstore/store_test.cc | 115 +++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+) diff --git a/src/os/bluestore/BlueFS.h b/src/os/bluestore/BlueFS.h index 9bca340fed6..3ae173f80ff 100644 --- a/src/os/bluestore/BlueFS.h +++ b/src/os/bluestore/BlueFS.h @@ -585,6 +585,9 @@ public: /// test purpose methods void debug_inject_duplicate_gift(unsigned bdev, uint64_t offset, uint64_t len); + const PerfCounters* get_perf_counters() const { + return logger; + } }; class OriginalVolumeSelector : public BlueFSVolumeSelector { diff --git a/src/os/bluestore/BlueStore.h b/src/os/bluestore/BlueStore.h index 6b97d454d73..5b308cc5507 100644 --- a/src/os/bluestore/BlueStore.h +++ b/src/os/bluestore/BlueStore.h @@ -2806,6 +2806,9 @@ public: const PerfCounters* get_perf_counters() const override { return logger; } + const PerfCounters* get_bluefs_perf_counters() const { + return bluefs->get_perf_counters(); + } int queue_transactions( CollectionHandle& ch, diff --git a/src/test/objectstore/store_test.cc b/src/test/objectstore/store_test.cc index 0835ffb2d3d..6a460a3ab10 100644 --- a/src/test/objectstore/store_test.cc +++ b/src/test/objectstore/store_test.cc @@ -28,9 +28,11 @@ #include "os/filestore/FileStore.h" #if defined(WITH_BLUESTORE) #include "os/bluestore/BlueStore.h" +#include "os/bluestore/BlueFS.h" #endif #include "include/Context.h" #include "common/ceph_argparse.h" +#include "common/admin_socket.h" #include "global/global_init.h" #include "common/ceph_mutex.h" #include "common/Cond.h" @@ -7988,6 +7990,119 @@ TEST_P(StoreTestSpecificAUSize, ReproNoBlobMultiTest) { } } +void doManySetAttr(ObjectStore* store, + std::function do_check_fn) +{ + MixedGenerator gen(447); + gen_type rng(time(NULL)); + coll_t cid(spg_t(pg_t(0, 447), shard_id_t::NO_SHARD)); + + SyntheticWorkloadState test_obj(store, &gen, &rng, cid, 40 * 1024, 4 * 1024, 0); + test_obj.init(); + for (int i = 0; i < 1500; ++i) { + if (!(i % 10)) cerr << "seeding object " << i << std::endl; + test_obj.touch(); + } + for (int i = 0; i < 10000; ++i) { + if (!(i % 100)) { + cerr << "Op " << i << std::endl; + test_obj.print_internal_state(); + } + boost::uniform_int<> true_false(0, 99); + test_obj.setattrs(); + } + test_obj.wait_for_done(); + + AdminSocket* admin_socket = g_ceph_context->get_admin_socket(); + ceph_assert(admin_socket); + + ceph::bufferlist in, out; + ostringstream err; + + bool b = admin_socket->execute_command( + { "{\"prefix\": \"bluestore bluefs stats\"}" }, + in, err, &out); + if (!b) { + cerr << "failure querying " << std::endl; + } + std::cout << std::string(out.c_str(), out.length()) << std::endl; + do_check_fn(store); + test_obj.shutdown(); +} + +TEST_P(StoreTestSpecificAUSize, SpilloverTest) { + if (string(GetParam()) != "bluestore") + return; + + SetVal(g_conf(), "bluestore_block_db_create", "true"); + SetVal(g_conf(), "bluestore_block_db_size", "3221225472"); + SetVal(g_conf(), "bluestore_volume_selection_policy", "rocksdb_original"); + + g_conf().apply_changes(nullptr); + + StartDeferred(65536); + doManySetAttr(store.get(), + [&](ObjectStore* _store) { + + BlueStore* bstore = dynamic_cast (_store); + ceph_assert(bstore); + const PerfCounters* logger = bstore->get_bluefs_perf_counters(); + //experimentally it was discovered that this case results in 400+MB spillover + //using lower 300MB threshold just to be safe enough + ASSERT_GE(logger->get(l_bluefs_slow_used_bytes), 300 * 1024 * 1024); + + } + ); +} + +TEST_P(StoreTestSpecificAUSize, SpilloverFixedTest) { + if (string(GetParam()) != "bluestore") + return; + + SetVal(g_conf(), "bluestore_block_db_create", "true"); + SetVal(g_conf(), "bluestore_block_db_size", "3221225472"); + SetVal(g_conf(), "bluestore_volume_selection_policy", "use_some_extra"); + SetVal(g_conf(), "bluestore_volume_selection_reserved", "1"); // just use non-zero to enable + + g_conf().apply_changes(nullptr); + + StartDeferred(65536); + doManySetAttr(store.get(), + [&](ObjectStore* _store) { + + BlueStore* bstore = dynamic_cast (_store); + ceph_assert(bstore); + const PerfCounters* logger = bstore->get_bluefs_perf_counters(); + ASSERT_EQ(0, logger->get(l_bluefs_slow_used_bytes)); + } + ); +} + +TEST_P(StoreTestSpecificAUSize, SpilloverFixed2Test) { + if (string(GetParam()) != "bluestore") + return; + + SetVal(g_conf(), "bluestore_block_db_create", "true"); + SetVal(g_conf(), "bluestore_block_db_size", "3221225472"); + SetVal(g_conf(), "bluestore_volume_selection_policy", "use_some_extra"); + //default 2.0 factor results in too high threshold, using less value + // that results in less but still present spillover. + SetVal(g_conf(), "bluestore_volume_selection_reserved_factor", "0.5"); + + g_conf().apply_changes(nullptr); + + StartDeferred(65536); + doManySetAttr(store.get(), + [&](ObjectStore* _store) { + + BlueStore* bstore = dynamic_cast (_store); + ceph_assert(bstore); + const PerfCounters* logger = bstore->get_bluefs_perf_counters(); + ASSERT_LE(logger->get(l_bluefs_slow_used_bytes), 300 * 1024 * 1024); // see SpilloverTest for 300MB choice rationale + } + ); +} + #endif // WITH_BLUESTORE int main(int argc, char **argv) { -- 2.39.5