point_lock_bench_tool.cc 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. // Copyright (c) Meta Platforms, Inc. and affiliates.
  2. //
  3. // This source code is licensed under both the GPLv2 (found in the
  4. // COPYING file in the root directory) and Apache 2.0 License
  5. // (found in the LICENSE.Apache file in the root directory).
  6. #ifdef GFLAGS
  7. #include <cstdio>
  8. #include <iostream>
  9. #include <memory>
  10. #include "port/stack_trace.h"
  11. #include "rocksdb/convenience.h"
  12. #include "rocksdb/env.h"
  13. #include "rocksdb/utilities/transaction_db.h"
  14. #include "util/gflags_compat.h"
  15. #include "utilities/transactions/lock/point/point_lock_manager.h"
  16. #include "utilities/transactions/lock/point/point_lock_validation_test_runner.h"
  17. #include "utilities/transactions/pessimistic_transaction_db.h"
  18. using GFLAGS_NAMESPACE::ParseCommandLineFlags;
  19. namespace ROCKSDB_NAMESPACE {
  20. DEFINE_string(db_dir, "/tmp/point_lock_manager_test",
  21. "DB path for running the benchmark");
  22. DEFINE_uint32(stripe_count, 16, "Number of stripes in point lock manager");
  23. DEFINE_bool(is_per_key_point_lock_manager, false,
  24. "Use PerKeyPointLockManager or PointLockManager");
  25. DEFINE_uint32(thread_count, 64,
  26. "Number of threads to acquire release locks concurrently");
  27. DEFINE_uint32(key_count, 16, "Number of keys to acquire release locks upon");
  28. DEFINE_uint32(max_num_keys_to_lock_per_txn, 8,
  29. "Max Number of keys to lock in a transaction");
  30. DEFINE_uint32(execution_time_sec, 10,
  31. "Number of seconds to execute the benchmark");
  32. DEFINE_uint32(lock_type, 2,
  33. "Lock type to test, 0: exclusive lock only; 1: shared lock only; "
  34. "2: both shared and exclusive locks");
  35. DEFINE_int64(lock_timeout_ms, 1000,
  36. "Lock acquisition request timeout in milliseconds.");
  37. DEFINE_int64(deadlock_timeout_us, 500,
  38. "DeadLock detection timeout in microseconds.");
  39. DEFINE_int64(lock_expiration_ms, 100,
  40. "Acquired Lock expiration time in milliseconds.");
  41. DEFINE_bool(allow_non_deadlock_error, true,
  42. "Allow returned error code other than deadlock, such as timeout.");
  43. DEFINE_uint32(
  44. max_sleep_after_lock_acquisition_ms, 5,
  45. "Max number of milliseconds to sleep after acquiring all the locks in the "
  46. "transaction. The actuall sleep time will be randomized from 0 to max. It "
  47. "is used to simulate some useful work performed.");
  48. DEFINE_bool(check_thread_stuck, false,
  49. "Check thread periodically to see whether they are stuck or not. "
  50. "This is useful for detecting stuck transaction quickly. But it "
  51. "could have false-positive when running with ASAN or running with "
  52. "high thread count on a small number of CPUs");
  53. namespace { // anonymous namespace
  54. class PointLockManagerBenchmark {
  55. public:
  56. PointLockManagerBenchmark() {
  57. env_ = Env::Default();
  58. env_->CreateDir(FLAGS_db_dir);
  59. Options opt;
  60. opt.create_if_missing = true;
  61. txndb_opt_.num_stripes = FLAGS_stripe_count;
  62. db_ = nullptr;
  63. auto s = TransactionDB::Open(opt, txndb_opt_, FLAGS_db_dir, &db_);
  64. ASSERT_OK(s);
  65. if (FLAGS_is_per_key_point_lock_manager) {
  66. locker_ = std::make_shared<PerKeyPointLockManager>(
  67. static_cast<PessimisticTransactionDB*>(db_), txndb_opt_);
  68. } else {
  69. locker_ = std::make_shared<PointLockManager>(
  70. static_cast<PessimisticTransactionDB*>(db_), txndb_opt_);
  71. }
  72. txn_opt_.deadlock_detect = true;
  73. txn_opt_.lock_timeout = FLAGS_lock_timeout_ms;
  74. txn_opt_.deadlock_timeout_us = FLAGS_deadlock_timeout_us;
  75. txn_opt_.expiration = FLAGS_lock_expiration_ms;
  76. }
  77. // Disable copy and assignment
  78. PointLockManagerBenchmark(const PointLockManagerBenchmark&) = delete;
  79. PointLockManagerBenchmark& operator=(const PointLockManagerBenchmark&) =
  80. delete;
  81. PointLockManagerBenchmark(PointLockManagerBenchmark&&) = delete;
  82. PointLockManagerBenchmark& operator=(PointLockManagerBenchmark&&) = delete;
  83. ~PointLockManagerBenchmark() {
  84. delete db_;
  85. auto s = DestroyDir(env_, FLAGS_db_dir);
  86. ASSERT_OK(s);
  87. }
  88. void run() {
  89. PointLockValidationTestRunner test_runner(
  90. env_, txndb_opt_, locker_, db_, txn_opt_, FLAGS_thread_count,
  91. FLAGS_key_count, FLAGS_max_num_keys_to_lock_per_txn,
  92. FLAGS_execution_time_sec, static_cast<LockTypeToTest>(FLAGS_lock_type),
  93. FLAGS_allow_non_deadlock_error,
  94. FLAGS_max_sleep_after_lock_acquisition_ms, FLAGS_check_thread_stuck);
  95. test_runner.run();
  96. }
  97. private:
  98. Env* env_;
  99. TransactionDBOptions txndb_opt_;
  100. std::shared_ptr<LockManager> locker_;
  101. TransactionDB* db_;
  102. TransactionOptions txn_opt_;
  103. };
  104. } // anonymous namespace
  105. int point_lock_bench_tool(int argc, char** argv) {
  106. ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();
  107. ParseCommandLineFlags(&argc, &argv, true);
  108. // Print test configuration
  109. std::vector<gflags::CommandLineFlagInfo> all_flags;
  110. gflags::GetAllFlags(&all_flags);
  111. for (const auto& flag : all_flags) {
  112. // only show the flags defined in this file
  113. if (flag.filename.find("point_lock_bench_tool.cc") != std::string::npos) {
  114. std::cout << "-" << flag.name << "=";
  115. if (flag.type == "bool") {
  116. std::cout << (gflags::GetCommandLineFlagInfoOrDie(flag.name.c_str())
  117. .current_value == "true"
  118. ? "true"
  119. : "false");
  120. } else {
  121. std::cout << gflags::GetCommandLineFlagInfoOrDie(flag.name.c_str())
  122. .current_value;
  123. }
  124. std::cout << " ";
  125. }
  126. }
  127. std::cout << std::endl;
  128. // Run the benchmark
  129. PointLockManagerBenchmark benchmark;
  130. benchmark.run();
  131. return 0;
  132. }
  133. } // namespace ROCKSDB_NAMESPACE
  134. #endif // GFLAGS