mirror of
https://github.com/codership/wsrep-lib.git
synced 2025-08-02 05:46:35 +03:00
Fixes to streaming rollback processing
* Count separately fragments certified and fragments stored in streaming context. Storing the fragment may ultimately fail due to BF abort even if the fragment was succesfully certified. Therefore we need to have separate counter for certified fragments to determine if the transaction is streaming and seqnos of fragments which have been succesfully stored. * Provider release is called only after succesful fragment certification and fragment store. * Fixed handling of write sets with rollback flag set in apply_write_set()
This commit is contained in:
@ -120,13 +120,45 @@ static int apply_write_set(wsrep::server_state& server_state,
|
||||
const wsrep::const_buffer& data)
|
||||
{
|
||||
int ret(0);
|
||||
if (wsrep::starts_transaction(ws_meta.flags()) &&
|
||||
wsrep::commits_transaction(ws_meta.flags()) &&
|
||||
wsrep::rolls_back_transaction(ws_meta.flags()))
|
||||
// wsrep::log_info() << "apply_write_set: " << ws_meta;
|
||||
if (wsrep::rolls_back_transaction(ws_meta.flags()))
|
||||
{
|
||||
// Non streaming rollback (certification failed)
|
||||
ret = high_priority_service.log_dummy_write_set(
|
||||
ws_handle, ws_meta);
|
||||
if (wsrep::starts_transaction(ws_meta.flags()))
|
||||
{
|
||||
// No transaction existed before, log a dummy write set
|
||||
ret = high_priority_service.log_dummy_write_set(
|
||||
ws_handle, ws_meta);
|
||||
}
|
||||
else
|
||||
{
|
||||
wsrep::high_priority_service* sa(
|
||||
server_state.find_streaming_applier(
|
||||
ws_meta.server_id(), ws_meta.transaction_id()));
|
||||
if (sa == 0)
|
||||
{
|
||||
// It is possible that rapid group membership changes
|
||||
// may cause streaming transaction be rolled back before
|
||||
// commit fragment comes in. Although this is a valid
|
||||
// situation, log a warning if a sac cannot be found as
|
||||
// it may be an indication of a bug too.
|
||||
wsrep::log_warning()
|
||||
<< "Could not find applier context for "
|
||||
<< ws_meta.server_id()
|
||||
<< ": " << ws_meta.transaction_id();
|
||||
ret = high_priority_service.log_dummy_write_set(
|
||||
ws_handle, ws_meta);
|
||||
}
|
||||
else
|
||||
{
|
||||
// rollback_fragment() consumes sa
|
||||
ret = rollback_fragment(server_state,
|
||||
high_priority_service,
|
||||
sa,
|
||||
ws_handle,
|
||||
ws_meta,
|
||||
data);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (wsrep::starts_transaction(ws_meta.flags()) &&
|
||||
wsrep::commits_transaction(ws_meta.flags()))
|
||||
@ -225,36 +257,6 @@ static int apply_write_set(wsrep::server_state& server_state,
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (wsrep::rolls_back_transaction(ws_meta.flags()))
|
||||
{
|
||||
wsrep::high_priority_service* sa(
|
||||
server_state.find_streaming_applier(
|
||||
ws_meta.server_id(), ws_meta.transaction_id()));
|
||||
if (sa == 0)
|
||||
{
|
||||
// It is possible that rapid group membership changes
|
||||
// may cause streaming transaction be rolled back before
|
||||
// commit fragment comes in. Although this is a valid
|
||||
// situation, log a warning if a sac cannot be found as
|
||||
// it may be an indication of a bug too.
|
||||
wsrep::log_warning()
|
||||
<< "Could not find applier context for "
|
||||
<< ws_meta.server_id()
|
||||
<< ": " << ws_meta.transaction_id();
|
||||
ret = high_priority_service.log_dummy_write_set(
|
||||
ws_handle, ws_meta);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Rollback fragment consumes sa
|
||||
ret = rollback_fragment(server_state,
|
||||
high_priority_service,
|
||||
sa,
|
||||
ws_handle,
|
||||
ws_meta,
|
||||
data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0);
|
||||
|
Reference in New Issue
Block a user