1
0
mirror of https://github.com/codership/wsrep-lib.git synced 2025-07-03 16:22:35 +03:00

codership/wsrep-lib#106 Relaxed assumptions about threading model

Sanity checks to detect concurrency bugs were assuming a threading
model where each client state would always be processed within
single thread of execution. This however may be too strong assumption
if the application uses some kind of thread pooling.

This patch relaxes those assumptions by removing current_thread_id_
from client_state and relaxing assertions against owning_thread_id_.

This patch also adds a new method
wait_rollback_complete_and_acquire_ownership() into
client_state. This method is idempotent and can be used to gain
control to client_state before before_command() is called.
The method will wait until possible background rollback process is
over and marks the state to s_exec to protect the state against
new background rollbacks.

Other fixes/improvements:
- High priority globals state is restored after discarding streaming.
- Allowed server_state transition donor -> synced.
- Client state method store_globals() was renamed to acquire_ownership()
  to better describe the intent. Method store_globals() was left for
  backwards compatibility and marked deprecated.
This commit is contained in:
Teemu Ollakka
2019-07-10 16:13:56 +03:00
parent 0f676bd893
commit 0c54cbd3f8
5 changed files with 184 additions and 88 deletions

View File

@ -71,6 +71,7 @@ static inline int resolve_return_error(bool const vote,
static void
discard_streaming_applier(wsrep::server_state& server_state,
wsrep::high_priority_service& high_priority_service,
wsrep::high_priority_service* streaming_applier,
const wsrep::ws_meta& ws_meta)
{
@ -78,6 +79,7 @@ discard_streaming_applier(wsrep::server_state& server_state,
ws_meta.server_id(), ws_meta.transaction_id());
server_state.server_service().release_high_priority_service(
streaming_applier);
high_priority_service.store_globals();
}
static int apply_fragment(wsrep::server_state& server_state,
@ -135,7 +137,10 @@ static int apply_fragment(wsrep::server_state& server_state,
}
else
{
discard_streaming_applier(server_state, streaming_applier,ws_meta);
discard_streaming_applier(server_state,
high_priority_service,
streaming_applier,
ws_meta);
ret = resolve_return_error(err.size() > 0, ret, apply_err);
}
}
@ -188,7 +193,8 @@ static int commit_fragment(wsrep::server_state& server_state,
if (!ret)
{
discard_streaming_applier(server_state, streaming_applier, ws_meta);
discard_streaming_applier(server_state, high_priority_service,
streaming_applier, ws_meta);
}
return ret;
@ -227,7 +233,8 @@ static int rollback_fragment(wsrep::server_state& server_state,
if (!ret)
{
discard_streaming_applier(server_state, streaming_applier, ws_meta);
discard_streaming_applier(server_state, high_priority_service,
streaming_applier, ws_meta);
if (adopt_error == 0)
{
@ -1282,7 +1289,7 @@ void wsrep::server_state::state(
{ 1, 0, 0, 1, 1, 0, 0, 1, 1}, /* cted */
{ 1, 1, 0, 0, 0, 1, 0, 0, 1}, /* jer */
{ 1, 0, 0, 1, 0, 0, 1, 1, 1}, /* jed */
{ 1, 0, 0, 1, 0, 1, 0, 0, 1}, /* dor */
{ 1, 0, 0, 1, 0, 1, 0, 1, 1}, /* dor */
{ 1, 0, 0, 1, 0, 1, 1, 0, 1}, /* sed */
{ 1, 0, 0, 0, 0, 0, 0, 0, 0} /* ding */
};
@ -1438,6 +1445,7 @@ void wsrep::server_state::close_orphaned_sr_transactions(
streaming_appliers_.erase(i++);
server_service_.release_high_priority_service(streaming_applier);
high_priority_service.store_globals();
wsrep::ws_meta ws_meta(
wsrep::gtid(),
wsrep::stid(server_id, transaction_id, wsrep::client_id()),
@ -1478,6 +1486,7 @@ void wsrep::server_state::close_transactions_at_disconnect(
}
streaming_appliers_.erase(i++);
server_service_.release_high_priority_service(streaming_applier);
high_priority_service.store_globals();
}
streaming_appliers_recovered_ = false;
}