[Commits] fb90597917a: When running with range locking, get deadlock info using RangeLockManager API
revision-id: fb90597917ae0587373596704d9a39ea4b9e6038 (fb-prod8-202009-54-gfb90597917a) parent(s): a7cea9a40a1e3a32a77cc9fd06e744eac94fe1e6 author: Sergei Petrunia committer: Sergei Petrunia timestamp: 2020-11-30 23:27:17 +0300 message: When running with range locking, get deadlock info using RangeLockManager API --- storage/rocksdb/ha_rocksdb.cc | 76 ++++++++++++++++++++++++++++++++++++------- storage/rocksdb/rdb_i_s.cc | 30 ++--------------- storage/rocksdb/rdb_utils.cc | 23 +++++++++++++ storage/rocksdb/rdb_utils.h | 3 ++ 4 files changed, 93 insertions(+), 39 deletions(-) diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index 18e4809aa8a..0f33dfe2a58 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -4907,8 +4907,9 @@ class Rdb_snapshot_status : public Rdb_tx_list_walker { "=========================================\n"; } + template<class PathStruct> static Rdb_deadlock_info::Rdb_dl_trx_info get_dl_txn_info( - const rocksdb::DeadlockInfo &txn, const GL_INDEX_ID &gl_index_id) { + const PathStruct &txn, const GL_INDEX_ID &gl_index_id) { Rdb_deadlock_info::Rdb_dl_trx_info txn_data; txn_data.trx_id = txn.m_txn_id; @@ -4933,23 +4934,48 @@ class Rdb_snapshot_status : public Rdb_tx_list_walker { ? cfh->GetName() : "NOT FOUND; CF_ID: " + std::to_string(txn.m_cf_id); - txn_data.waiting_key = - rdb_hexdump(txn.m_waiting_key.c_str(), txn.m_waiting_key.length()); + txn_data.waiting_key = format_wait_key(txn); txn_data.exclusive_lock = txn.m_exclusive; return txn_data; } + /* + Unify Range and Point-based locking: index_key is the index that the lock + is using. + */ + static const std::string& get_key_for_indexnr( + const rocksdb::DeadlockInfo& info) { + return info.m_waiting_key; + } + static const std::string& get_key_for_indexnr( + const rocksdb::RangeDeadlockInfo& info) { + // Range locks do not span indexes, so take the left bound + return info.m_start.slice; + } + + /* + Unify Range and Point-based locking: Print the locked key (or range) in hex + */ + static std::string format_wait_key(const rocksdb::DeadlockInfo& info) { + return rdb_hexdump(info.m_waiting_key.c_str(), info.m_waiting_key.length()); + } + + static std::string format_wait_key(const rocksdb::RangeDeadlockInfo& info) { + return rdb_hexdump_range(info.m_start, info.m_end); + } + + template<class PathStruct> static Rdb_deadlock_info get_dl_path_trx_info( - const rocksdb::DeadlockPath &path_entry) { + const PathStruct &path_entry) { Rdb_deadlock_info deadlock_info; for (auto it = path_entry.path.begin(); it != path_entry.path.end(); it++) { const auto &txn = *it; const GL_INDEX_ID gl_index_id = { txn.m_cf_id, rdb_netbuf_to_uint32(reinterpret_cast<const uchar *>( - txn.m_waiting_key.c_str()))}; + get_key_for_indexnr(txn).c_str()))}; deadlock_info.path.push_back(get_dl_txn_info(txn, gl_index_id)); } DBUG_ASSERT_IFF(path_entry.limit_exceeded, path_entry.path.empty()); @@ -4992,8 +5018,8 @@ class Rdb_snapshot_status : public Rdb_tx_list_walker { } } - void populate_deadlock_buffer() { - auto dlock_buffer = rdb->GetDeadlockInfoBuffer(); + template<class PathStruct> + void populate_deadlock_buffer_tmpl(PathStruct &dlock_buffer) { m_data += "----------LATEST DETECTED DEADLOCKS----------\n"; for (const auto &path_entry : dlock_buffer) { @@ -5033,12 +5059,32 @@ class Rdb_snapshot_status : public Rdb_tx_list_walker { } } + void populate_deadlock_buffer() { + if (range_lock_mgr) { + auto dlock_buffer = range_lock_mgr->GetRangeDeadlockInfoBuffer(); + populate_deadlock_buffer_tmpl(dlock_buffer); + } else { + auto dlock_buffer = rdb->GetDeadlockInfoBuffer(); + populate_deadlock_buffer_tmpl(dlock_buffer); + } + } + std::vector<Rdb_deadlock_info> get_deadlock_info() { std::vector<Rdb_deadlock_info> deadlock_info; - auto dlock_buffer = rdb->GetDeadlockInfoBuffer(); - for (const auto &path_entry : dlock_buffer) { - if (!path_entry.limit_exceeded) { - deadlock_info.push_back(get_dl_path_trx_info(path_entry)); + + if (range_lock_mgr) { + auto dlock_buffer = range_lock_mgr->GetRangeDeadlockInfoBuffer(); + for (const auto &path_entry : dlock_buffer) { + if (!path_entry.limit_exceeded) { + deadlock_info.push_back(get_dl_path_trx_info(path_entry)); + } + } + } else { + auto dlock_buffer = rdb->GetDeadlockInfoBuffer(); + for (const auto &path_entry : dlock_buffer) { + if (!path_entry.limit_exceeded) { + deadlock_info.push_back(get_dl_path_trx_info(path_entry)); + } } } return deadlock_info; @@ -15949,7 +15995,13 @@ void rocksdb_set_max_latest_deadlocks( const uint32_t new_val = *static_cast<const uint32_t *>(save); if (rocksdb_max_latest_deadlocks != new_val) { rocksdb_max_latest_deadlocks = new_val; - rdb->SetDeadlockInfoBufferSize(rocksdb_max_latest_deadlocks); + if (range_lock_mgr) { + auto n= rocksdb_max_latest_deadlocks; + range_lock_mgr->SetRangeDeadlockInfoBufferSize(n); + } + else + rdb->SetDeadlockInfoBufferSize(rocksdb_max_latest_deadlocks); + } RDB_MUTEX_UNLOCK_CHECK(rdb_sysvars_mutex); } diff --git a/storage/rocksdb/rdb_i_s.cc b/storage/rocksdb/rdb_i_s.cc index 765f432f0ce..9509cc90825 100644 --- a/storage/rocksdb/rdb_i_s.cc +++ b/storage/rocksdb/rdb_i_s.cc @@ -1751,6 +1751,7 @@ static ST_FIELD_INFO rdb_i_s_lock_info_fields_info[] = { ROCKSDB_FIELD_INFO("MODE", 32, MYSQL_TYPE_STRING, 0), ROCKSDB_FIELD_INFO_END}; + /* Fill the information_schema.rocksdb_locks virtual table */ static int rdb_i_s_lock_info_fill_table( my_core::THD *const thd, my_core::TABLE_LIST *const tables, @@ -1780,33 +1781,8 @@ static int rdb_i_s_lock_info_fill_table( const uint32_t cf_id = lock.first; const auto &range_lock_info = lock.second; - std::string key_hexstr; - // For keys: :0 keys should look like point keys - if (!range_lock_info.start.inf_suffix && - !range_lock_info.end.inf_suffix && - (range_lock_info.start.slice == - range_lock_info.end.slice)) { - // Ok the lock is held on a single-point range. - // Show it like a single-point key - key_hexstr = rdb_hexdump(range_lock_info.start.slice.c_str(), - range_lock_info.start.slice.length(), - FN_REFLEN); - } else { - key_hexstr = rdb_hexdump(range_lock_info.start.slice.c_str(), - range_lock_info.start.slice.length(), - FN_REFLEN); - if (range_lock_info.start.inf_suffix) - key_hexstr.append(":1"); - - key_hexstr.append("-"); - - std::string key2 = rdb_hexdump(range_lock_info.end.slice.c_str(), - range_lock_info.end.slice.length(), - FN_REFLEN); - if (range_lock_info.end.inf_suffix) - key2.append(":1"); - key_hexstr.append(key2); - } + std::string key_hexstr = rdb_hexdump_range(range_lock_info.start, + range_lock_info.end); for (const auto &id : range_lock_info.ids) { tables->table->field[RDB_LOCKS_FIELD::COLUMN_FAMILY_ID]->store(cf_id, diff --git a/storage/rocksdb/rdb_utils.cc b/storage/rocksdb/rdb_utils.cc index b14a3c94ea9..edd6597cd02 100644 --- a/storage/rocksdb/rdb_utils.cc +++ b/storage/rocksdb/rdb_utils.cc @@ -254,6 +254,29 @@ std::string rdb_hexdump(const char *data, const std::size_t data_len, return str; } +std::string rdb_hexdump_range(const rocksdb::EndpointWithString& start, + const rocksdb::EndpointWithString& end) { + std::string res; + // For keys: :0 keys should look like point keys + if (!start.inf_suffix && !end.inf_suffix && (start.slice == end.slice)) { + // This is a single-point range, show it like a key + res = rdb_hexdump(start.slice.c_str(), start.slice.length(), FN_REFLEN); + } else { + res = rdb_hexdump(start.slice.c_str(), start.slice.length(), FN_REFLEN); + if (start.inf_suffix) + res.append(":1"); + + res.append("-"); + + std::string key2 = rdb_hexdump(end.slice.c_str(), end.slice.length(), + FN_REFLEN); + if (end.inf_suffix) + key2.append(":1"); + res.append(key2); + } + return res; +} + /* Attempt to access the database subdirectory to see if it exists */ diff --git a/storage/rocksdb/rdb_utils.h b/storage/rocksdb/rdb_utils.h index ea313d401c1..910f5947281 100644 --- a/storage/rocksdb/rdb_utils.h +++ b/storage/rocksdb/rdb_utils.h @@ -29,6 +29,7 @@ /* RocksDB header files */ #include "rocksdb/slice.h" #include "rocksdb/status.h" +#include "rocksdb/utilities/transaction_db.h" /* MyRocks header files */ #include "./rdb_global.h" @@ -290,6 +291,8 @@ std::string rdb_hexdump(const char *data, const std::size_t data_len, const std::size_t maxsize = 0) MY_ATTRIBUTE((__nonnull__)); +std::string rdb_hexdump_range(const rocksdb::EndpointWithString& left, + const rocksdb::EndpointWithString& right); /* Helper function to see if a database exists */
participants (1)
-
psergey