Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce a TablePinningPolicy to control how and when memory is pinned #459

Merged
merged 18 commits into from
Aug 2, 2023

Conversation

mrambacher
Copy link
Contributor

This PR adds a TablePinningPolicy to the BlockBasedTableOptions. This new class is Customizable and can be created from strings. The class has methods to limit the amount of pin data in the system.

The basic approach is that the unit probes (MayPin) if it believes data is available at the time. If so, the code does it normal checks and then attempts to pin the new data (PinData). Once the code is done with the data, UnPinData puts the memory back into the available pool

@Guyme Guyme linked an issue Apr 13, 2023 that may be closed by this pull request

options.ignore_unsupported_options = false;
const auto& id = GetParam();
EXPECT_OK(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why EXPECT_OK and not ASSERT_OK?

ASSERT_EQ(pinning_policy_->GetUsage(), 0);
}

static const std::vector<std::string>& GetPinningPolicies() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really minor, but unnamed namespaces should be the way to go instead of static functions.

struct ConfigOptions;
// Struct that contains information about the table being evaluated for pinning
struct TablePinningOptions {
TablePinningOptions() {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you choos the {} and not = default on purpose?

}
ASSERT_EQ(pinning_policy_->GetUsage(), used);
}
printf("MJR: Pinned=%d\n", (int)used);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is printing really necessary? I would avoid printing to the console during unit tests as it just bothers users running unit tests who just want to see the tests pass.
The unit test should use assertions to verify it is passing.

const auto& id = GetParam();
EXPECT_OK(
TablePinningPolicy::CreateFromString(options, id, &pinning_policy_));
printf("MJR: Loaded pinning policy (%s)\n", id.c_str());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the printing (which, btw, may be done using std::cout in unit tests). Please also see my comment below regarding the printf there.

plugin/speedb/pinning_policy/scoped_pinning_policy_test.cc Outdated Show resolved Hide resolved
@udi-speedb
Copy link
Contributor

@mrambacher - First batch of comments. Haven't finished the review.

@udi-speedb
Copy link
Contributor

@mrambacher - In case it wasn't clear. I am waiting for you to address the comments I have given before continuing my review.

@@ -34,13 +34,32 @@ static std::unordered_map<std::string, OptionTypeInfo>
OptionVerificationType::kNormal, OptionTypeFlags::kNone}},
};

ScopedPinningPolicy::ScopedPinningPolicy() {
static const uint8_t kNumTypes = 7;
static const int kNumLevels = 7;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that just for testing the concept?


std::atomic<size_t> usage_;
std::vector<std::atomic_size_t> usage_by_level_;
std::vector<std::atomic_size_t> usage_by_type_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not initialize the vectors to 0 here and avoid the necessity in the ctor?

}
for (uint8_t t = 0; t < kNumTypes; t++) {
usage_by_type_[t].store(0);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't you use std::fill?
But a better options IMO is to init all of the fields in the header as I suggest
And you could delegate to the non default ctor by calling here ScopedPinningPolicy(ScopedPinningOptions()) and avoid the code duplication in the ctor-s.

}
for (uint8_t t = 0; t < kNumTypes; t++) {
usage_by_type_[t].store(0);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see my comments above for the default ctor.

usage_by_type_[type] += size;
} else {
usage_by_level_[level] += size;
usage_by_type_[type] += size;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't you decrease the usage by level / type when pinned == false?

} else if (pinned) {
usage_by_type_[type] = size;
if (level >= kNumLevels) level = kNumLevels - 1;
if (type >= kNumTypes) type = kNumTypes - 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only for testing the concept or is that how it's going to be in production code?

@@ -49,78 +68,52 @@ std::string ScopedPinningPolicy::GetId() const {

bool ScopedPinningPolicy::MayPin(const TablePinningOptions& tpo, uint8_t type,
size_t size) const {
auto limit = GetUsage();
return CheckPin(tpo, type, size, limit);
return CheckPin(tpo, type, size, usage_);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is MayPin()? used for?
And, it should be clear to the users that they MayPin() may return true but actual pinning may still fail.

@udi-speedb udi-speedb self-requested a review May 31, 2023 01:37
@erez-speedb
Copy link

erez-speedb commented Jun 11, 2023

build db_bench failed
CC plugin/speedb/speedb_registry.o
CC plugin/speedb/memtable/hash_spd_rep.o
CC plugin/speedb/paired_filter/speedb_paired_bloom.o
CC plugin/speedb/paired_filter/speedb_paired_bloom_internal.o
CC plugin/speedb/pinning_policy/scoped_pinning_policy.o
CC utilities/transactions/lock/range/range_tree/lib/locktree/concurrent_tree.o
CC utilities/transactions/lock/range/range_tree/lib/locktree/keyrange.o
CC utilities/transactions/lock/range/range_tree/lib/locktree/lock_request.o
CC utilities/transactions/lock/range/range_tree/lib/locktree/locktree.o
CC utilities/transactions/lock/range/range_tree/lib/locktree/manager.o
CC utilities/transactions/lock/range/range_tree/lib/locktree/range_buffer.o
CC utilities/transactions/lock/range/range_tree/lib/locktree/treenode.o
CC utilities/transactions/lock/range/range_tree/lib/locktree/txnid_set.o
CC utilities/transactions/lock/range/range_tree/lib/locktree/wfg.o
plugin/speedb/pinning_policy/scoped_pinning_policy.cc: In member function ‘virtual bool rocksdb::ScopedPinningPolicy::CheckPin(const rocksdb::TablePinningOptions&, uint8_t, size_t, size_t) const’:
plugin/speedb/pinning_policy/scoped_pinning_policy.cc:56:48: error: comparison of unsigned expression >= 0 is always true [-Werror=type-limits]
56 | if (tpo.is_bottom && options_.bottom_percent >= 0) {
| ~~~~~~~~~~~~~~~~~~~~~~~~^~~~
plugin/speedb/pinning_policy/scoped_pinning_policy.cc:60:52: error: comparison of unsigned expression >= 0 is always true [-Werror=type-limits]
60 | } else if (tpo.level > 0 && options_.mid_percent >= 0) {
| ~~~~~~~~~~~~~~~~~~~~~^~~~
CC utilities/transactions/lock/range/range_tree/lib/standalone_port.o
CC utilities/transactions/lock/range/range_tree/lib/util/dbt.o
CC utilities/transactions/lock/range/range_tree/lib/util/memarena.o
CC utilities/transactions/lock/range/range_tree/range_tree_lock_manager.o
CC utilities/transactions/lock/range/range_tree/range_tree_lock_tracker.o
cc1plus: all warnings being treated as errors
make: *** [Makefile:2418: plugin/speedb/pinning_policy/scoped_pinning_policy.o] Error 1

comparison of unsigned expression >= 0 is always true [-Werror=type-limits]
@udi-speedb udi-speedb self-requested a review June 14, 2023 06:52
@Yuval-Ariel
Copy link
Contributor

blocked until #573 is fixed @maxb-io FYI

@Guyme Guyme requested review from erez-speedb and removed request for erez-speedb June 29, 2023 12:12
@Yuval-Ariel Yuval-Ariel self-requested a review July 3, 2023 12:56
@Yuval-Ariel
Copy link
Contributor

@mrambacher plz also add to the HISTORY.md file

@Yuval-Ariel
Copy link
Contributor

https://github.com/speedb-io/speedb/actions/runs/5444728254/jobs/9904106132#step:6:571

==15027==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x606000010398 at pc 0x7f21e95a2c2e bp 0x7f21dcdb9f20 sp 0x7f21dcdb9f10
WRITE of size 8 at 0x606000010398 thread T6
#0 0x7f21e95a2c2d in std::__atomic_base::operator+=(unsigned long) /usr/include/c++/7/bits/atomic_base.h:312
#1 0x7f21e95a2c2d in rocksdb::RecordingPinningPolicy::RecordPinned(int, unsigned char, unsigned long, bool) table/block_based/table_pinning_policy.cc:145
#2 0x7f21e95a2e92 in rocksdb::RecordingPinningPolicy::PinData(rocksdb::TablePinningOptions const&, unsigned char, unsigned long, std::unique_ptr<rocksdb::PinnedEntry, std::default_deleterocksdb::PinnedEntry >) table/block_based/table_pinning_policy.cc:126
#3 0x7f21e959030e in rocksdb::PartitionIndexReader::Create(rocksdb::BlockBasedTable const
, rocksdb::ReadOptions const&, rocksdb::TablePinningOptions const&, rocksdb::FilePrefetchBuffer*, bool, bool, bool, rocksdb::BlockCacheLookupContext*,

Not sure how it disappeared as part of the rebase...
Copy link
Contributor

@Yuval-Ariel Yuval-Ariel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove foo file.

@Yuval-Ariel
Copy link
Contributor

failed unit tests:
FAILED TESTS (1/11819):
752 ms: /__w/speedb/speedb/options_settable_test OptionsSettableTest.BlockBasedTableOptionsAllFieldsSettable

@Yuval-Ariel Yuval-Ariel merged commit 6e05428 into speedb-io:main Aug 2, 2023
1 check passed
udi-speedb pushed a commit that referenced this pull request Nov 22, 2023
udi-speedb pushed a commit that referenced this pull request Dec 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Clean data phase 1: Pinning metadata to the cache
4 participants