-
Notifications
You must be signed in to change notification settings - Fork 21
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
Add INDEX FLIP and CP abrupt #407
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,6 +39,31 @@ struct BtreeThreadVariables { | |
BtreeNodePtr force_split_node{nullptr}; | ||
}; | ||
|
||
struct BTREE_FLIPS { | ||
static constexpr uint32_t INDEX_PARENT_NON_ROOT = 1 << 0; | ||
static constexpr uint32_t INDEX_PARENT_ROOT = 1 << 1; | ||
static constexpr uint32_t INDEX_LEFT_SIBLING = 1 << 2; | ||
static constexpr uint32_t INDEX_RIGHT_SIBLING = 1 << 3; | ||
|
||
uint32_t flips; | ||
BTREE_FLIPS() : flips{0} {} | ||
std::string list() const { | ||
std::string str; | ||
if (flips & INDEX_PARENT_NON_ROOT) { str += "index_parent_non_root,"; } | ||
if (flips & INDEX_PARENT_ROOT) { str += "index_parent_root,"; } | ||
if (flips & INDEX_LEFT_SIBLING) { str += "index_left_sibling,"; } | ||
if (flips & INDEX_RIGHT_SIBLING) { str += "index_right_sibling,"; } | ||
return str; | ||
} | ||
void set_flip(uint32_t flip) { flips |= flip; } | ||
void set_flip(std::string flip) { | ||
if (flip == "index_parent_non_root") { set_flip(INDEX_PARENT_NON_ROOT); } | ||
if (flip == "index_parent_root") { set_flip(INDEX_PARENT_ROOT); } | ||
if (flip == "index_left_sibling") { set_flip(INDEX_LEFT_SIBLING); } | ||
if (flip == "index_right_sibling") { set_flip(INDEX_RIGHT_SIBLING); } | ||
} | ||
}; | ||
|
||
template < typename K, typename V > | ||
class Btree { | ||
private: | ||
|
@@ -52,7 +77,9 @@ class Btree { | |
#ifndef NDEBUG | ||
std::atomic< uint64_t > m_req_id{0}; | ||
#endif | ||
|
||
#ifdef _PRERELEASE | ||
BTREE_FLIPS m_flips; | ||
#endif | ||
// This workaround of BtreeThreadVariables is needed instead of directly declaring statics | ||
// to overcome the gcc bug, pointer here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66944 | ||
static BtreeThreadVariables* bt_thread_vars() { | ||
|
@@ -100,6 +127,16 @@ class Btree { | |
|
||
// static void set_io_flip(); | ||
// static void set_error_flip(); | ||
#ifdef _PRERELEASE | ||
void set_flip_point(std::string flip) { | ||
m_flips.set_flip(flip); | ||
} | ||
void set_flips(std::vector< std::string > flips) { | ||
for (const auto& flip : flips) { | ||
set_flip_point(flip); | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please avoid pass-by-value on containers, as it could be very expensive without any hint. |
||
#endif | ||
|
||
protected: | ||
/////////////////////////// Methods the underlying store is expected to handle /////////////////////////// | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ | |
#include <homestore/index_service.hpp> | ||
#include <homestore/checkpoint/cp_mgr.hpp> | ||
#include <homestore/index/wb_cache_base.hpp> | ||
#include <iomgr/iomgr_flip.hpp> | ||
|
||
SISL_LOGGING_DECL(wbcache) | ||
|
||
|
@@ -147,6 +148,11 @@ class IndexTable : public IndexTableBase, public Btree< K, V > { | |
for (const auto& right_child_node : new_nodes) { | ||
auto right_child = IndexBtreeNode::convert(right_child_node.get()); | ||
write_node_impl(right_child_node, context); | ||
#ifdef _PRERELEASE | ||
if (iomgr_flip::instance()->test_flip("index_right_sibling")) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would suggest a more contextful name for the flip, say |
||
index_service().wb_cache().add_to_crashing_buffers(right_child->m_idx_buf, "index_right_sibling"); | ||
} | ||
#endif | ||
wb_cache().prepend_to_chain(right_child->m_idx_buf, left_child_buf); | ||
} | ||
|
||
|
@@ -160,11 +166,28 @@ class IndexTable : public IndexTableBase, public Btree< K, V > { | |
} | ||
return str; | ||
}; | ||
|
||
#ifdef _PRERELEASE | ||
if (iomgr_flip::instance()->test_flip("index_left_sibling")) { | ||
index_service().wb_cache().add_to_crashing_buffers(left_child_idx_node->m_idx_buf, "index_left_sibling"); | ||
} | ||
#endif | ||
LOGTRACEMOD(wbcache, "{}", trace_index_bufs()); | ||
write_node_impl(left_child_node, context); | ||
write_node_impl(parent_node, context); | ||
|
||
#ifdef _PRERELEASE | ||
if (iomgr_flip::instance()->test_flip("index_parent_non_root")) { | ||
if(parent_node->node_id()!= this->root_node_id()){ | ||
index_service().wb_cache().add_to_crashing_buffers(parent_idx_node->m_idx_buf, "index_parent_non_root"); | ||
} | ||
} | ||
if (iomgr_flip::instance()->test_flip("index_parent_root")) { | ||
if(parent_node->node_id()== this->root_node_id()) { | ||
index_service().wb_cache().add_to_crashing_buffers(left_child_idx_node->m_idx_buf, "index_parent_root"); | ||
} | ||
} | ||
#endif | ||
|
||
return btree_status_t::success; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -74,6 +74,14 @@ class IndexWBCacheBase { | |
/// @param cur_buf | ||
/// @return | ||
virtual IndexBufferPtr copy_buffer(const IndexBufferPtr& cur_buf, const CPContext* context) const = 0; | ||
|
||
#ifdef _PRERELEASE | ||
/// @brief add the buffer to crashing buffers list. In transact_write_nodes(), it will be called. During flushing | ||
/// wbcache, it will be checked. If the buffer is in the list, cp_abrupt happens. | ||
/// @param first index buffer | ||
/// @param second the reason | ||
virtual void add_to_crashing_buffers(IndexBufferPtr, std::string reason) = 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment. |
||
#endif | ||
}; | ||
|
||
} // namespace homestore |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -151,7 +151,12 @@ void IndexWBCache::read_buf(bnodeid_t id, BtreeNodePtr& node, node_initializer_t | |
goto retry; | ||
} | ||
} | ||
|
||
#ifdef _PRERELEASE | ||
void IndexWBCache::add_to_crashing_buffers(IndexBufferPtr buf, std::string reason) { | ||
std::unique_lock lg(flip_mtx); | ||
this->crashing_buffers[buf].push_back(reason); | ||
} | ||
#endif | ||
std::pair< bool, bool > IndexWBCache::create_chain(IndexBufferPtr& second, IndexBufferPtr& third, CPContext* cp_ctx) { | ||
bool second_copied{false}, third_copied{false}; | ||
auto chain = second; | ||
|
@@ -241,6 +246,25 @@ folly::Future< bool > IndexWBCache::async_cp_flush(IndexCPContext* cp_ctx) { | |
void IndexWBCache::do_flush_one_buf(IndexCPContext* cp_ctx, IndexBufferPtr buf, bool part_of_batch) { | ||
LOGTRACEMOD(wbcache, "cp {} buf {}", cp_ctx->id(), buf->to_string()); | ||
buf->set_state(index_buf_state_t::FLUSHING); | ||
|
||
#ifdef _PRERELEASE | ||
|
||
if (cp_ctx->is_abrupt()) { | ||
LOGTRACEMOD(wbcache, "The cp {} is abrupt! for {}", cp_ctx->id(), BtreeNode::to_string_buf(buf->raw_buffer())); | ||
return; | ||
} | ||
if (auto it = crashing_buffers.find(buf);it != crashing_buffers.end()) { | ||
const auto& reasons = it->second; | ||
std::string formatted_reasons = fmt::format("[{}]", fmt::join(reasons, ", ")); | ||
LOGTRACEMOD(wbcache, "Buffer {} is in crashing_buffers with reason(s): {} - Buffer info: {}", | ||
buf->to_string(), formatted_reasons, BtreeNode::to_string_buf(buf->raw_buffer())); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't need another fmt::format over other format right? You could merge them. |
||
crashing_buffers.clear(); | ||
cp_ctx->abrupt(); | ||
return; | ||
} | ||
#endif | ||
LOGTRACEMOD(wbcache, "flushing cp {} buf {} info: {}", cp_ctx->id(), buf->to_string(), | ||
BtreeNode::to_string_buf(buf->raw_buffer())); | ||
m_vdev->async_write(r_cast< const char* >(buf->raw_buffer()), m_node_size, buf->m_blkid, part_of_batch) | ||
.thenValue([buf, cp_ctx](auto) { | ||
auto& pthis = s_cast< IndexWBCache& >(wb_cache()); // Avoiding more than 16 bytes capture | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why should btree maintain a separate vector of flips? Why can't the caller directly set the flip?