diff --git a/dbsim/db_high_priority_service.hpp b/dbsim/db_high_priority_service.hpp index db9abce..84c55f6 100644 --- a/dbsim/db_high_priority_service.hpp +++ b/dbsim/db_high_priority_service.hpp @@ -37,9 +37,10 @@ namespace db void switch_execution_context(wsrep::high_priority_service&) override { } int log_dummy_write_set(const wsrep::ws_handle&, - const wsrep::ws_meta&) + const wsrep::ws_meta&) override { return 0; } - bool is_replaying() const; + bool is_replaying() const override; + void debug_crash(const char*) override { } private: high_priority_service(const high_priority_service&); high_priority_service& operator=(const high_priority_service&); diff --git a/include/wsrep/high_priority_service.hpp b/include/wsrep/high_priority_service.hpp index 24e7206..4c95029 100644 --- a/include/wsrep/high_priority_service.hpp +++ b/include/wsrep/high_priority_service.hpp @@ -169,6 +169,11 @@ namespace wsrep virtual bool is_replaying() const = 0; bool must_exit() const { return must_exit_; } + + /** + * Debug facility to crash the server at given point. + */ + virtual void debug_crash(const char* crash_point) = 0; protected: wsrep::server_state& server_state_; bool must_exit_; diff --git a/src/server_state.cpp b/src/server_state.cpp index 8dc430f..638effd 100644 --- a/src/server_state.cpp +++ b/src/server_state.cpp @@ -44,11 +44,14 @@ static int apply_fragment(wsrep::server_state& server_state, { wsrep::high_priority_switch sw(high_priority_service, streaming_applier); + ret = streaming_applier.apply_write_set(ws_meta, data); streaming_applier.after_apply(); } + high_priority_service.debug_crash("crash_apply_cb_before_append_frag"); ret = ret || high_priority_service.append_fragment_and_commit( ws_handle, ws_meta, data); + high_priority_service.debug_crash("crash_apply_cb_after_append_frag"); high_priority_service.after_apply(); return ret; } @@ -67,9 +70,17 @@ static int commit_fragment(wsrep::server_state& server_state, { wsrep::high_priority_switch sw( high_priority_service, *streaming_applier); - ret = streaming_applier->apply_write_set(ws_meta, data) || - streaming_applier->remove_fragments(ws_meta) || - streaming_applier->commit(ws_handle, ws_meta); + ret = streaming_applier->apply_write_set(ws_meta, data); + streaming_applier->debug_crash( + "crash_apply_cb_before_fragment_removal"); + ret = ret || streaming_applier->remove_fragments(ws_meta); + streaming_applier->debug_crash( + "crash_apply_cb_after_fragment_removal"); + streaming_applier->debug_crash( + "crash_commit_cb_before_last_fragment_commit"); + ret = ret || streaming_applier->commit(ws_handle, ws_meta); + streaming_applier->debug_crash( + "crash_commit_cb_last_fragment_commit_success"); streaming_applier->after_apply(); } if (ret == 0) diff --git a/test/mock_high_priority_service.hpp b/test/mock_high_priority_service.hpp index f4f91ec..19d090a 100644 --- a/test/mock_high_priority_service.hpp +++ b/test/mock_high_priority_service.hpp @@ -57,6 +57,8 @@ namespace wsrep const wsrep::ws_meta&) WSREP_OVERRIDE { return 0; } bool is_replaying() const WSREP_OVERRIDE { return replaying_; } + void debug_crash(const char*) WSREP_OVERRIDE { /* Not in unit tests*/} + wsrep::mock_client_state* client_state() { return client_state_;