Skip to content

Commit

Permalink
Add lock wait time as a perf context counter
Browse files Browse the repository at this point in the history
Summary:
Adds two new counters:

`key_lock_wait_count` counts how many times a lock was blocked by another transaction and had to wait, instead of being granted the lock immediately.
`key_lock_wait_time` counts the time spent acquiring locks.
Closes facebook#3107

Differential Revision: D6217332

Pulled By: lth

fbshipit-source-id: 55d4f46da5550c333e523263422fd61d6a46deb9
  • Loading branch information
lth authored and facebook-github-bot committed Nov 6, 2017
1 parent be410de commit e03377c
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 0 deletions.
5 changes: 5 additions & 0 deletions include/rocksdb/perf_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ struct PerfContext {
// total number of SST table bloom misses
uint64_t bloom_sst_miss_count;

// Time spent waiting on key locks in transaction lock manager.
uint64_t key_lock_wait_time;
// number of times acquiring a lock was blocked by another transaction.
uint64_t key_lock_wait_count;

// Total time spent in Env filesystem operations. These are only populated
// when TimedEnv is used.
uint64_t env_new_sequential_file_nanos;
Expand Down
4 changes: 4 additions & 0 deletions monitoring/perf_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ void PerfContext::Reset() {
bloom_memtable_miss_count = 0;
bloom_sst_hit_count = 0;
bloom_sst_miss_count = 0;
key_lock_wait_time = 0;
key_lock_wait_count = 0;

env_new_sequential_file_nanos = 0;
env_new_random_access_file_nanos = 0;
Expand Down Expand Up @@ -158,6 +160,8 @@ std::string PerfContext::ToString(bool exclude_zero_counters) const {
PERF_CONTEXT_OUTPUT(bloom_memtable_miss_count);
PERF_CONTEXT_OUTPUT(bloom_sst_hit_count);
PERF_CONTEXT_OUTPUT(bloom_sst_miss_count);
PERF_CONTEXT_OUTPUT(key_lock_wait_time);
PERF_CONTEXT_OUTPUT(key_lock_wait_count);
PERF_CONTEXT_OUTPUT(env_new_sequential_file_nanos);
PERF_CONTEXT_OUTPUT(env_new_random_access_file_nanos);
PERF_CONTEXT_OUTPUT(env_new_writable_file_nanos);
Expand Down
3 changes: 3 additions & 0 deletions utilities/transactions/transaction_lock_mgr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <string>
#include <vector>

#include "monitoring/perf_context_imp.h"
#include "rocksdb/slice.h"
#include "rocksdb/utilities/transaction_db_mutex.h"
#include "util/cast_util.h"
Expand Down Expand Up @@ -347,6 +348,8 @@ Status TransactionLockMgr::AcquireWithTimeout(
&expire_time_hint, &wait_ids);

if (!result.ok() && timeout != 0) {
PERF_TIMER_GUARD(key_lock_wait_time);
PERF_COUNTER_ADD(key_lock_wait_count, 1);
// If we weren't able to acquire the lock, we will keep retrying as long
// as the timeout allows.
bool timed_out = false;
Expand Down
6 changes: 6 additions & 0 deletions utilities/transactions/transaction_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "db/db_impl.h"
#include "rocksdb/db.h"
#include "rocksdb/options.h"
#include "rocksdb/perf_context.h"
#include "rocksdb/utilities/transaction.h"
#include "rocksdb/utilities/transaction_db.h"
#include "table/mock_table.h"
Expand Down Expand Up @@ -187,15 +188,18 @@ TEST_P(TransactionTest, WaitingTxn) {
ASSERT_EQ(cf_id, 0);
});

get_perf_context()->Reset();
// lock key in default cf
s = txn1->GetForUpdate(read_options, "foo", &value);
ASSERT_OK(s);
ASSERT_EQ(value, "bar");
ASSERT_EQ(get_perf_context()->key_lock_wait_count, 0);

// lock key in cfa
s = txn1->GetForUpdate(read_options, cfa, "foo", &value);
ASSERT_OK(s);
ASSERT_EQ(value, "bar");
ASSERT_EQ(get_perf_context()->key_lock_wait_count, 0);

auto lock_data = db->GetLockStatusData();
// Locked keys exist in both column family.
Expand Down Expand Up @@ -231,6 +235,8 @@ TEST_P(TransactionTest, WaitingTxn) {
s = txn2->GetForUpdate(read_options, "foo", &value);
ASSERT_TRUE(s.IsTimedOut());
ASSERT_EQ(s.ToString(), "Operation timed out: Timeout waiting to lock key");
ASSERT_EQ(get_perf_context()->key_lock_wait_count, 1);
ASSERT_GE(get_perf_context()->key_lock_wait_time, 0);

rocksdb::SyncPoint::GetInstance()->DisableProcessing();
rocksdb::SyncPoint::GetInstance()->ClearAllCallBacks();
Expand Down

0 comments on commit e03377c

Please sign in to comment.