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

Support recovery of XA transactions

* Add method `restore_prepared_transaction` to `client_state` class
  which restores a transaction state from storage given its xid.
* Add method `commit_or_rollback_by_xid` to terminate prepared XA
  transactions by xid.
* Make sure that transactions in prepared state are not rolled back
  when their master fails/partitions away.
This commit is contained in:
Daniele Sciascia
2019-03-14 11:30:01 +01:00
parent 98af85498b
commit 052247144f
16 changed files with 210 additions and 31 deletions

View File

@ -73,6 +73,9 @@ namespace wsrep
*/
virtual void cleanup_transaction() = 0;
//
// XA
//
/**
* Return true if the current transactions is XA
*/
@ -83,6 +86,11 @@ namespace wsrep
*/
virtual bool is_xa_prepare() const = 0;
/**
* Return a string representing the xid of the transaction
*/
virtual std::string xid() const = 0;
//
// Streaming
//

View File

@ -305,6 +305,36 @@ namespace wsrep
return transaction_.assign_read_view(gtid);
}
/**
* Restores the client's transaction to prepared state
*
* The purpose of this method is to restore transaction state
* during recovery of a prepared XA transaction.
*/
int restore_prepared_transaction()
{
return transaction_.restore_to_prepared_state();
}
/**
* Terminate transaction with the given xid
*
* Sends a commit or rollback fragment to terminate the a
* transaction with the given xid. For the fragment to be
* sent, a streaming applier for the transaction must exist
* and the transaction must be in prepared state.
*
* @param xid the xid of the the transaction to terminate
* @param commit whether to send a commmit or rollback fragment
*
* @return Zero on success, non-zero on error. In case of error
* the client_state's current_error is set
*/
int commit_or_rollback_by_xid(const std::string& xid, bool commit)
{
return transaction_.commit_or_rollback_by_xid(xid, commit);
}
/**
* Append a key into transaction write set.
*

View File

@ -96,7 +96,8 @@ namespace wsrep
virtual int append_fragment_and_commit(
const wsrep::ws_handle& ws_handle,
const wsrep::ws_meta& ws_meta,
const wsrep::const_buffer& data) = 0;
const wsrep::const_buffer& data,
const std::string& xid) = 0;
/**
* Remove fragments belonging to streaming transaction.

View File

@ -130,7 +130,12 @@ namespace wsrep
, depends_on_(depends_on)
, flags_(flags)
{ }
ws_meta(const wsrep::stid& stid)
: gtid_()
, stid_(stid)
, depends_on_()
, flags_()
{ }
const wsrep::gtid& gtid() const { return gtid_; }
const wsrep::id& group_id() const
{

View File

@ -256,12 +256,20 @@ namespace wsrep
void stop_streaming_applier(
const wsrep::id&, const wsrep::transaction_id&);
/**
* Return reference to streaming applier.
* Find a streaming applier matching server and transaction ids
*/
wsrep::high_priority_service* find_streaming_applier(
const wsrep::id&,
const wsrep::transaction_id&) const;
/**
* Find a streaming applier matching xid
*/
wsrep::high_priority_service* find_streaming_applier(
const std::string& xid) const;
/**
* Load WSRep provider.
*

View File

@ -63,7 +63,8 @@ namespace wsrep
virtual int append_fragment(const wsrep::id& server_id,
wsrep::transaction_id client_id,
int flags,
const wsrep::const_buffer& data) = 0;
const wsrep::const_buffer& data,
const std::string& xid) = 0;
/**
* Update fragment meta data after certification process.

View File

@ -132,6 +132,15 @@ namespace wsrep
return client_service_.is_xa_prepare();
}
int restore_to_prepared_state();
int commit_or_rollback_by_xid(const std::string& xid, bool commit);
const std::string xid() const
{
return client_service_.xid();
}
bool pa_unsafe() const { return pa_unsafe_; }
void pa_unsafe(bool pa_unsafe) { pa_unsafe_ = pa_unsafe; }
@ -262,6 +271,7 @@ namespace wsrep
wsrep::streaming_context streaming_context_;
wsrep::sr_key_set sr_keys_;
wsrep::mutable_buffer apply_error_buf_;
bool is_recovered_xa_;
};
static inline const char* to_c_string(enum wsrep::transaction::state state)